class Apartment::Adapters::PostgresqlSchemaAdapter

Separate Adapter for Postgresql when using schemas

def connect_to_new(tenant = nil)


Set schema search path to new schema
def connect_to_new(tenant = nil)
  return reset if tenant.nil?
  raise ActiveRecord::StatementInvalid, "Could not find schema #{tenant}" unless schema_exists?(tenant)
  @current = tenant.is_a?(Array) ? tenant.map(&:to_s) : tenant.to_s
  Apartment.connection.schema_search_path = full_search_path
  # When the PostgreSQL version is < 9.3,
  # there is a issue for prepared statement with changing search_path.
  # https://www.postgresql.org/docs/9.3/static/sql-prepare.html
  Apartment.connection.clear_cache! if postgresql_version < 90_300
rescue *rescuable_exceptions => e
  raise_schema_connect_to_new(tenant, e)
end

def create_tenant_command(conn, tenant)

def create_tenant_command(conn, tenant)
  # NOTE: This was causing some tests to fail because of the database strategy for rspec
  if ActiveRecord::Base.connection.open_transactions.positive?
    conn.execute(%(CREATE SCHEMA "#{tenant}"))
  else
    schema = %(BEGIN;
    CREATE SCHEMA "#{tenant}";
    COMMIT;)
    conn.execute(schema)
  end
rescue *rescuable_exceptions => e
  rollback_transaction(conn)
  raise e
end

def current

def current
  @current || default_tenant
end

def default_tenant

def default_tenant
  @default_tenant = Apartment.default_tenant || 'public'
end

def drop_command(conn, tenant)

def drop_command(conn, tenant)
  conn.execute(%(DROP SCHEMA "#{tenant}" CASCADE))
end

def full_search_path


Generate the final search path to set including persistent_schemas
def full_search_path
  persistent_schemas.map(&:inspect).join(', ')
end

def init

def init
  super
  Apartment.connection.schema_search_path = full_search_path
end

def initialize(config)

def initialize(config)
  super
  reset
end

def persistent_schemas

def persistent_schemas
  [@current, Apartment.persistent_schemas].flatten
end

def postgresql_version

def postgresql_version
  # ActiveRecord::ConnectionAdapters::PostgreSQLAdapter#postgresql_version is
  # public from Rails 5.0.
  Apartment.connection.send(:postgresql_version)
end

def process_excluded_model(excluded_model)

def process_excluded_model(excluded_model)
  excluded_model.constantize.tap do |klass|
    # Ensure that if a schema *was* set, we override
    table_name = klass.table_name.split('.', 2).last
    klass.table_name = "#{default_tenant}.#{table_name}"
  end
end

def raise_schema_connect_to_new(tenant, exception)

def raise_schema_connect_to_new(tenant, exception)
  raise TenantNotFound, <<~EXCEPTION_MESSAGE
    Could not set search path to schemas, they may be invalid: "#{tenant}" #{full_search_path}.
    Original error: #{exception.class}: #{exception}
  EXCEPTION_MESSAGE
end

def reset

Returns:
  • (String) - default schema search path
def reset
  @current = default_tenant
  Apartment.connection.schema_search_path = full_search_path
end

def rollback_transaction(conn)

def rollback_transaction(conn)
  conn.execute('ROLLBACK;')
end

def schema_exists?(schemas)

def schema_exists?(schemas)
  return true unless Apartment.tenant_presence_check
  Array(schemas).all? { |schema| Apartment.connection.schema_exists?(schema.to_s) }
end

def tenant_exists?(tenant)

def tenant_exists?(tenant)
  return true unless Apartment.tenant_presence_check
  Apartment.connection.schema_exists?(tenant)
end