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 118 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 217 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 139 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 223 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 146 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 231 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 195 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 155 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
# File lib/apartment/adapters/postgresql_adapter.rb, line 172 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 131 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 205 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 178 def with_pg_env(&block) pghost, pgport, pguser, pgpassword = ENV['PGHOST'], ENV['PGPORT'], ENV['PGUSER'], 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] block.call ensure ENV['PGHOST'], ENV['PGPORT'], ENV['PGUSER'], ENV['PGPASSWORD'] = pghost, pgport, pguser, pgpassword end