Class: Apartment::Adapters::PostgresqlSchemaAdapter
- Inherits:
-
AbstractAdapter
- Object
- AbstractAdapter
- Apartment::Adapters::PostgresqlSchemaAdapter
- Includes:
- PostgresqlTransactionState
- Defined in:
- lib/apartment/adapters/postgresql_schema_adapter.rb
Overview
v4 PostgreSQL adapter using schema-based tenant isolation.
Resolves tenant-specific connection configs by setting schema_search_path
to the raw tenant name (not environmentified — schemas are named directly,
unlike database-per-tenant adapters) plus any persistent schemas from
Apartment.config.postgres_config. Lifecycle operations (create/drop)
execute DDL against the default connection.
Instance Attribute Summary
Attributes inherited from AbstractAdapter
Instance Method Summary collapse
-
#failsafe_error_classes ⇒ Object
The schema-strategy missing-tenant error: a dropped schema is not caught at switch time (search_path accepts a non-existent schema silently) — it surfaces on the first query as ActiveRecord::StatementInvalid (PG::UndefinedTable, 42P01).
-
#physical_tenant_name(tenant) ⇒ Object
Schemas are named directly (never environmentified), so the physical identifier validated at pool-resolution time is the raw tenant name.
-
#pinned_table_qualifier ⇒ Object
Pinned tables live in the default tenant's schema; every tenant connection can reach them by schema-qualifying the name.
- #resolve_connection_config(tenant, base_config: nil) ⇒ Object
- #shared_pinned_connection? ⇒ Boolean
Methods included from PostgresqlTransactionState
Methods inherited from AbstractAdapter
#aborted_transaction?, #apply_pinned_qualification, #check_pinned_subclass, #create, #default_tenant, #drop, #environmentify, #inherits_pinned_table?, #initialize, #migrate, #nearest_pinned_ancestor, #process_excluded_models, #process_pinned_model, #process_pinned_models, #qualify_pinned_table_name, #qualify_pinned_table_name_prefix, #seed, #tenant_container_gone?, #unregistered_pinned_subclass?, #validated_connection_config, #warn_unqualified_subclass, #warn_unregistered_pinned_subclasses
Constructor Details
This class inherits a constructor from Apartment::Adapters::AbstractAdapter
Instance Method Details
#failsafe_error_classes ⇒ Object
The schema-strategy missing-tenant error: a dropped schema is not caught at switch time (search_path accepts a non-existent schema silently) — it surfaces on the first query as ActiveRecord::StatementInvalid (PG::UndefinedTable, 42P01). That is the same shape as a missing table in a live schema, so #tenant_container_exists? does the disambiguating to_regnamespace check.
ApartmentError is included because ConnectionHandling wraps errors raised during pool resolution (e.g. the dev-mode pending-migration check, which queries schema_migrations in the gone schema) as ApartmentError with the StatementInvalid as #cause; #container_error? then unwraps and classifies it the same as the query-time case, and re-raises any other ApartmentError.
53 54 55 |
# File 'lib/apartment/adapters/postgresql_schema_adapter.rb', line 53 def failsafe_error_classes [ActiveRecord::StatementInvalid, Apartment::ApartmentError] end |
#physical_tenant_name(tenant) ⇒ Object
Schemas are named directly (never environmentified), so the physical identifier validated at pool-resolution time is the raw tenant name.
37 38 39 |
# File 'lib/apartment/adapters/postgresql_schema_adapter.rb', line 37 def physical_tenant_name(tenant) tenant.to_s end |
#pinned_table_qualifier ⇒ Object
Pinned tables live in the default tenant's schema; every tenant connection can reach them by schema-qualifying the name.
23 24 25 |
# File 'lib/apartment/adapters/postgresql_schema_adapter.rb', line 23 def pinned_table_qualifier default_tenant end |
#resolve_connection_config(tenant, base_config: nil) ⇒ Object
27 28 29 30 31 32 33 |
# File 'lib/apartment/adapters/postgresql_schema_adapter.rb', line 27 def resolve_connection_config(tenant, base_config: nil) config = base_config || send(:base_config) persistent = Apartment.config.postgres_config&.persistent_schemas || [] search_path = [tenant, *persistent].map { |s| %("#{s}") }.join(',') config.merge('schema_search_path' => search_path) end |