class Apartment::Adapters::PostgresqlSchemaFromSqlAdapter
Another Adapter for Postgresql when using schemas and SQL
def check_input_against_regexps(input, regexps)
Checks if any of regexps matches against input
def check_input_against_regexps(input, regexps) regexps.select { |c| input.match c } end
def clone_pg_schema
Clone default schema into new schema named after current tenant
def clone_pg_schema pg_schema_sql = patch_search_path(pg_dump_schema) Apartment.connection.execute(pg_schema_sql) end
def collect_table_names(models)
Collect table names from AR Models
def collect_table_names(models) models.map do |m| m.constantize.table_name end end
def copy_schema_migrations
Copy data from schema_migrations into new schema
def copy_schema_migrations pg_migrations_data = patch_search_path(pg_dump_schema_migrations_data) Apartment.connection.execute(pg_migrations_data) end
def dbname
Convenience method for current database name
def dbname Apartment.connection_config[:database] end
def import_database_schema
def import_database_schema preserving_search_path do clone_pg_schema copy_schema_migrations end end
def patch_search_path(sql)
-
(String)
- patched raw SQL dump
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
def pg_dump_schema
-
(String)
- raw SQL contaning only postgres schema dump
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
def pg_dump_schema_migrations_data
-
(String)
- raw SQL contaning inserts with data from schema_migrations
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
def preserving_search_path
and it mut be reset
Postgres now sets search path to empty before dumping the schema
Re-set search path after the schema is imported.
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
def swap_schema_qualifier(sql)
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
def with_pg_env
Temporary set Postgresql related environment variables if there are in @config
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