diff --git a/src/bosh-dev/lib/bosh/dev/sandbox/mysql.rb b/src/bosh-dev/lib/bosh/dev/sandbox/mysql.rb index 1f9f2466bef..cfef5026a10 100644 --- a/src/bosh-dev/lib/bosh/dev/sandbox/mysql.rb +++ b/src/bosh-dev/lib/bosh/dev/sandbox/mysql.rb @@ -24,12 +24,12 @@ def connection_string def create_db @logger.info("Creating mysql database #{db_name}") - @runner.run(%Q{mysql -h #{@host} -P #{@port} --user=#{@username} --password=#{@password} -e 'create database `#{db_name}`;' > /dev/null 2>&1}, redact: [@password]) + execute_sql(%{CREATE DATABASE `#{db_name}`;}, nil) end def drop_db @logger.info("Dropping mysql database #{db_name}") - @runner.run(%Q{mysql -h #{@host} -P #{@port} --user=#{@username} --password=#{@password} -e 'drop database `#{db_name}`;' > /dev/null 2>&1}, redact: [@password]) + execute_sql(%{DROP DATABASE `#{db_name}`;}, nil) end def load_db_initial_state(initial_state_assets_dir) @@ -39,12 +39,11 @@ def load_db_initial_state(initial_state_assets_dir) def load_db(dump_file_path) @logger.info("Loading dump '#{dump_file_path}' into mysql database #{db_name}") - @runner.run(%Q{mysql -h #{@host} -P #{@port} --user=#{@username} --password=#{@password} #{db_name} < #{dump_file_path} > /dev/null 2>&1}, redact: [@password]) + run_quietly_redacted(%Q{#{mysql_cmd} #{db_name} < #{dump_file_path} > /dev/null 2>&1}) end def current_tasks - tasks_list_cmd = %Q{mysql -h #{@host} -P #{@port} --user=#{@username} --password=#{@password} -e "select description, output from tasks where state='processing';" #{db_name} 2> /dev/null} - task_lines = `#{tasks_list_cmd}`.lines.to_a[1..-1] || [] + task_lines = sql_results_for(%{SELECT description, output FROM TASKS WHERE state='processing';}) result = [] task_lines.each do |task_line| @@ -56,17 +55,39 @@ def current_tasks end def current_locked_jobs - jobs_cmd = %Q{mysql -h #{@host} -P #{@port} --user=#{@username} --password=#{@password} -e "select * from delayed_jobs where locked_by is not null;" #{db_name} 2> /dev/null} - `#{jobs_cmd}`.lines.to_a[1..-1] || [] + sql_results_for(%{SELECT * FROM delayed_jobs WHERE locked_by IS NOT NULL;}) end def truncate_db @logger.info("Truncating mysql database #{db_name}") - table_name_cmd = %Q{mysql -h #{@host} -P #{@port} --user=#{@username} --password=#{@password} -e "show tables;" #{db_name} 2>/dev/null} - table_names = `#{table_name_cmd}`.lines.to_a[1..-1].map(&:strip) - table_names.reject!{|name| name == "schema_migrations" } - truncates = table_names.map{|name| 'truncate table `' + name + '`' }.join(';') - @runner.run(%Q{mysql -h #{@host} -P #{@port} --user=#{@username} --password=#{@password} -e 'SET FOREIGN_KEY_CHECKS=0; #{truncates}; SET FOREIGN_KEY_CHECKS=1;' #{db_name} > /dev/null 2>&1}, redact: [@password]) + table_names = sql_results_for(%{SHOW TABLES}) + table_names.reject! { |name| name == 'schema_migrations' } + truncate_cmds = table_names.map { |name| %{TRUNCATE TABLE '#{name.strip}'} } + + execute_sql(%{SET FOREIGN_KEY_CHECKS=0; #{truncate_cmds.join(';')}; SET FOREIGN_KEY_CHECKS=1;}) + end + + private + + def run_quietly_redacted(cmd) + redacted = [@password] unless @password.blank? + @runner.run(%{#{cmd} > /dev/null 2>&1}, redact: redacted) + end + + def execute_sql(sql, this_db_name = db_name) + run_quietly_redacted(%{#{sql_cmd(sql, this_db_name)} > /dev/null 2>&1}) + end + + def sql_results_for(sql, this_db_name = db_name) + %x{#{sql_cmd(sql, this_db_name)} 2> /dev/null}.lines.to_a[1..-1] || [] + end + + def sql_cmd(sql, this_db_name) + %{#{mysql_cmd} -e '#{sql.strip}' #{this_db_name}} + end + + def mysql_cmd + %{mysql -h #{@host} -P #{@port} --user=#{@username} --password=#{@password}} end end end diff --git a/src/bosh-dev/lib/bosh/dev/sandbox/postgresql.rb b/src/bosh-dev/lib/bosh/dev/sandbox/postgresql.rb index dad10ae57da..973443fd4da 100644 --- a/src/bosh-dev/lib/bosh/dev/sandbox/postgresql.rb +++ b/src/bosh-dev/lib/bosh/dev/sandbox/postgresql.rb @@ -19,18 +19,15 @@ def initialize(db_name, runner, logger, options = {}) @ca_path = options.fetch(:ca_path, nil) end - def connection_string - "postgres://#{@username}:#{@password}@#{@host}:#{@port}/#{@db_name}" + def connection_string(this_db_name = @db_name) + "postgres://#{@username}:#{@password}@#{@host}:#{@port}/#{this_db_name}" end # Assumption is that user running tests can # login via psql without entering password. def create_db @logger.info("Creating postgres database #{db_name}") - @runner.run( - "echo #{Shellwords.escape(%(CREATE DATABASE "#{db_name}";))} | " \ - "psql #{connection_string.gsub(/#{@db_name}$/, 'postgres')} > /dev/null", - ) + execute_sql(%(CREATE DATABASE "#{db_name}";), connection_string('postgres')) end def kill_connections @@ -51,10 +48,7 @@ def drop_db REVOKE CONNECT ON DATABASE "#{db_name}" FROM public; DROP DATABASE "#{db_name}"; ) - @runner.run( - "echo #{Shellwords.escape(sql)} | " \ - "psql #{connection_string.gsub(@db_name, 'postgres')} > /dev/null", - ) + execute_sql(sql, connection_string('postgres')) end def dump_db @@ -64,7 +58,7 @@ def dump_db def describe_db @logger.info("Describing postgres database tables for #{db_name}") - @runner.run(%(psql #{connection_string} -c '\\d+ public.*')) + execute_sql("\\d+ public.*") end def load_db_initial_state(initial_state_assets_dir) @@ -78,14 +72,12 @@ def load_db(dump_file_path) end def current_tasks - tasks_list_cmd = %( - psql #{connection_string} -c " + tasks_list_cmd = %{ SELECT description, output FROM tasks WHERE state='processing'; - " - ) - task_lines = `#{tasks_list_cmd}`.lines.to_a[2...-2] || [] + } + task_lines = sql_results_for(tasks_list_cmd) result = [] task_lines.each do |task_line| @@ -97,20 +89,37 @@ def current_tasks end def current_locked_jobs - jobs_cmd = %( - psql #{connection_string} -c " + jobs_cmd = %{ SELECT * FROM delayed_jobs WHERE locked_by IS NOT NULL; - " - ) - `#{jobs_cmd}`.lines.to_a[2...-2] || [] + } + sql_results_for(jobs_cmd) end def truncate_db @logger.info("Truncating postgres database #{db_name}") - drop_constraints_cmds_cmd = %{psql #{connection_string} -c " + cmds = drop_constraints_cmds + clear_table_cmds + add_constraints_cmds + execute_sql(cmds.join(';')) + end + + private + + def execute_sql(sql, this_connection_string = connection_string) + @runner.run(%{#{sql_cmd(sql, this_connection_string)} > /dev/null}) + end + + def sql_results_for(sql, this_connection_string = connection_string) + %x{#{sql_cmd(sql, this_connection_string)}}.lines.to_a[2...-2] || [] + end + + def sql_cmd(sql, this_connection_string = connection_string) + %{echo #{Shellwords.escape(sql)} | psql #{this_connection_string}} + end + + def drop_constraints_cmds + drop_constraints_cmds_cmd = %{ SELECT CONCAT('ALTER TABLE ',nspname,'.',relname,' DROP CONSTRAINT ',conname,';') FROM pg_constraint @@ -118,11 +127,14 @@ def truncate_db INNER JOIN pg_namespace ON pg_namespace.oid=pg_class.relnamespace WHERE nspname != 'pg_catalog' ORDER BY CASE WHEN contype='f' THEN 0 ELSE 1 END,contype,nspname,relname,conname - "} + } + sql_results_for(drop_constraints_cmds_cmd) + end - clear_table_cmds_cmd = %{psql #{connection_string} -c " + def clear_table_cmds + clear_table_cmds_cmd = %{ SELECT - CONCAT('DELETE FROM \\"', tablename, '\\"') + CONCAT('DELETE FROM \"', tablename, '\"') FROM pg_tables WHERE schemaname = 'public' AND @@ -133,9 +145,12 @@ def truncate_db FROM pg_class WHERE relkind = 'S' - "} + } + sql_results_for(clear_table_cmds_cmd) + end - add_constraints_cmds_cmd = %{psql #{connection_string} -c " + def add_constraints_cmds + add_constraints_cmds_cmd = %{ SELECT 'ALTER TABLE '||nspname||'.'||relname||' ADD CONSTRAINT '||conname||' '|| pg_get_constraintdef(pg_constraint.oid)||';' FROM pg_constraint @@ -143,25 +158,8 @@ def truncate_db INNER JOIN pg_namespace ON pg_namespace.oid=pg_class.relnamespace WHERE nspname != 'pg_catalog' ORDER BY CASE WHEN contype='f' THEN 0 ELSE 1 END DESC,contype DESC,nspname DESC,relname DESC,conname DESC; - "} - - drop_constraints_cmds = `#{drop_constraints_cmds_cmd}`.lines.to_a[2...-2] || [] - clear_table_cmds = `#{clear_table_cmds_cmd}`.lines.to_a[2...-2] || [] - add_constraints_cmds = `#{add_constraints_cmds_cmd}`.lines.to_a[2...-2] || [] - - cmds = drop_constraints_cmds + clear_table_cmds + add_constraints_cmds - @runner.run( - "psql #{connection_string} -c '#{cmds.join(';')}' > /dev/null 2>&1", - ) - end - - private - - def execute_sql(statements) - @runner.run( - "echo #{Shellwords.escape(statements)} | " \ - "psql #{connection_string} > /dev/null", - ) + } + sql_results_for(add_constraints_cmds_cmd) end end end