class Apartment::Adapters::PostgresqlSchemaFromSqlAdapter
Another Adapter for Postgresql when using schemas and SQL
Constants
- PSQL_DUMP_BLACKLISTED_STATEMENTS
Public Instance Methods
# File lib/apartment/adapters/postgresql_adapter.rb, line 171 def import_database_schema preserving_search_path do clone_pg_schema copy_schema_migrations end end
Private Instance Methods
Checks if any of regexps matches against input
# File lib/apartment/adapters/postgresql_adapter.rb, line 277 def check_input_against_regexps(input, regexps) regexps.select { |c| input.match c } end
Clone default schema into new schema named after current tenant
# File lib/apartment/adapters/postgresql_adapter.rb, line 192 def clone_pg_schema pg_schema_sql = patch_search_path(pg_dump_schema) Apartment.connection.execute(pg_schema_sql) end
Collect table names from AR Models
# File lib/apartment/adapters/postgresql_adapter.rb, line 283 def collect_table_names(models) models.map do |m| m.constantize.table_name end end
Copy data from schema_migrations into new schema
# File lib/apartment/adapters/postgresql_adapter.rb, line 199 def copy_schema_migrations pg_migrations_data = patch_search_path(pg_dump_schema_migrations_data) Apartment.connection.execute(pg_migrations_data) end
Convenience method for current database name
# File lib/apartment/adapters/postgresql_adapter.rb, line 291 def dbname Apartment.connection_config[:database] end
Remove “SET search_path …” line from SQL dump and prepend search_path set to current tenant
@return {String} patched raw SQL dump
# File lib/apartment/adapters/postgresql_adapter.rb, line 255 def patch_search_path(sql) search_path = "SET search_path = \"#{current}\", #{default_tenant};" swap_schema_qualifier(sql) .split("\n") .select { |line| check_input_against_regexps(line, PSQL_DUMP_BLACKLISTED_STATEMENTS).empty? } .prepend(search_path) .join("\n") end
Dump postgres default schema
@return {String} raw SQL contaning only postgres schema dump
# File lib/apartment/adapters/postgresql_adapter.rb, line 208 def pg_dump_schema # Skip excluded tables? :/ # excluded_tables = # collect_table_names(Apartment.excluded_models) # .map! {|t| "-T #{t}"} # .join(' ') # `pg_dump -s -x -O -n #{default_tenant} #{excluded_tables} #{dbname}` with_pg_env { `pg_dump -s -x -O -n #{default_tenant} #{dbname}` } end
Dump data from schema_migrations table @return {String} raw SQL contaning inserts with data from schema_migrations
rubocop:disable Layout/LineLength
# File lib/apartment/adapters/postgresql_adapter.rb, line 225 def pg_dump_schema_migrations_data with_pg_env { `pg_dump -a --inserts -t #{default_tenant}.schema_migrations -t #{default_tenant}.ar_internal_metadata #{dbname}` } end
Re-set search path after the schema is imported. Postgres now sets search path to empty before dumping the schema and it mut be reset
# File lib/apartment/adapters/postgresql_adapter.rb, line 184 def preserving_search_path search_path = Apartment.connection.execute('show search_path').first['search_path'] yield Apartment.connection.execute("set search_path = #{search_path}") end
# File lib/apartment/adapters/postgresql_adapter.rb, line 265 def swap_schema_qualifier(sql) sql.gsub(/#{default_tenant}\.\w*/) do |match| if Apartment.pg_excluded_names.any? { |name| match.include? name } match else match.gsub("#{default_tenant}.", %("#{current}".)) end end end
Temporary set Postgresql related environment variables if there are in @config
# File lib/apartment/adapters/postgresql_adapter.rb, line 232 def with_pg_env pghost = ENV['PGHOST'] pgport = ENV['PGPORT'] pguser = ENV['PGUSER'] pgpassword = ENV['PGPASSWORD'] ENV['PGHOST'] = @config[:host] if @config[:host] ENV['PGPORT'] = @config[:port].to_s if @config[:port] ENV['PGUSER'] = @config[:username].to_s if @config[:username] ENV['PGPASSWORD'] = @config[:password].to_s if @config[:password] yield ensure ENV['PGHOST'] = pghost ENV['PGPORT'] = pgport ENV['PGUSER'] = pguser ENV['PGPASSWORD'] = pgpassword end