Skip to content

Commit

Permalink
DRY up some duplication in DB helpers
Browse files Browse the repository at this point in the history
  • Loading branch information
aramprice authored and selzoc committed Aug 29, 2024
1 parent 4fbb0be commit 2cd3e29
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 58 deletions.
45 changes: 33 additions & 12 deletions src/bosh-dev/lib/bosh/dev/sandbox/mysql.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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|
Expand All @@ -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
90 changes: 44 additions & 46 deletions src/bosh-dev/lib/bosh/dev/sandbox/postgresql.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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)
Expand All @@ -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|
Expand All @@ -97,32 +89,52 @@ 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
INNER JOIN pg_class ON conrelid=pg_class.oid
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
Expand All @@ -133,35 +145,21 @@ 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
INNER JOIN pg_class ON conrelid=pg_class.oid
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

0 comments on commit 2cd3e29

Please sign in to comment.