lib/active_record/tasks/chronomodel_database_tasks.rb
# frozen_string_literal: true
module ActiveRecord
module Tasks
class ChronomodelDatabaseTasks < PostgreSQLDatabaseTasks
CHRONOMODEL_SCHEMAS = [
ChronoModel::Adapter::TEMPORAL_SCHEMA,
ChronoModel::Adapter::HISTORY_SCHEMA
].freeze
def structure_dump(*arguments)
if schema_search_path.present?
with_chronomodel_schema_search_path { super }
else
super
end
# The structure.sql includes CREATE SCHEMA statements, but as these are executed
# when the connection to the database is established, a db:structure:load fails.
#
# This code adds the IF NOT EXISTS clause to CREATE SCHEMA statements as long as
# it is not already present.
#
filename = arguments.first
sql = File.read(filename).gsub(/CREATE SCHEMA (?!IF NOT EXISTS)/, '\&IF NOT EXISTS ')
File.open(filename, 'w') { |file| file << sql }
end
def data_dump(target)
psql_env
args = ['-c', '-f', target.to_s]
args << chronomodel_configuration[:database]
run_cmd 'pg_dump', args, 'dumping data'
end
def data_load(source)
psql_env
args = ['-f', source]
args << chronomodel_configuration[:database]
run_cmd 'psql', args, 'loading data'
end
private
def chronomodel_configuration
@chronomodel_configuration ||= @configuration_hash
end
# If a schema search path is defined in the configuration file, it will
# be used by the database tasks class to dump only the specified search
# path. Here we add also ChronoModel's temporal and history schemas to
# the search path and yield.
#
def with_chronomodel_schema_search_path
patch_configuration!
yield
ensure
reset_configuration!
end
def patch_configuration!
@original_schema_search_path = schema_search_path
chronomodel_schema_search_path = "#{schema_search_path},#{CHRONOMODEL_SCHEMAS.join(',')}"
@configuration_hash = @configuration_hash.dup
@configuration_hash[:schema_search_path] = chronomodel_schema_search_path
@configuration_hash.freeze
end
def reset_configuration!
@configuration_hash = @configuration_hash.dup
@configuration_hash[:schema_search_path] = @original_schema_search_path
@configuration_hash.freeze
end
def schema_search_path
@schema_search_path ||= chronomodel_configuration[:schema_search_path]
end
end
end
end