Class: ActiveRecord::ConnectionAdapters::PostgreSQL::Branched::Adapter

Inherits:
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
  • Object
show all
Defined in:
lib/active_record/connection_adapters/postgresql/branched/adapter.rb

Constant Summary collapse

ADAPTER_NAME =
"PostgreSQL Branched"
SHADOW_SKIP =

Methods where the first argument is not the table to shadow, or where shadowing would be wasteful (join table methods pass table_1, not the derived join table name).

%i[create_join_table drop_join_table].freeze
SHADOW_HANDLED =

Methods with custom shadow handling outside the generic loop.

%i[rename_table drop_table create_table].freeze
SHADOW_BEFORE =

Everything else with a table param gets the generic wrapper. Shadow#call is idempotent — if the table doesn’t exist in public or is already shadowed, it’s a no-op.

(Branched.table_methods - SHADOW_SKIP - SHADOW_HANDLED).freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeAdapter

Returns a new instance of Adapter.



36
37
38
39
40
# File 'lib/active_record/connection_adapters/postgresql/branched/adapter.rb', line 36

def initialize(...)
  super
  @branch_manager = BranchManager.new(self, @config)
  @shadow = Shadow.new(self, @branch_manager.branch_schema) unless @branch_manager.primary_branch?
end

Instance Attribute Details

#branch_managerObject (readonly)

Returns the value of attribute branch_manager.



95
96
97
# File 'lib/active_record/connection_adapters/postgresql/branched/adapter.rb', line 95

def branch_manager
  @branch_manager
end

Instance Method Details

#configure_connectionObject



42
43
44
45
# File 'lib/active_record/connection_adapters/postgresql/branched/adapter.rb', line 42

def configure_connection
  super
  @branch_manager.activate(@shadow)
end

#create_table(*args, **kwargs, &block) ⇒ Object

create_table after drop_table should work — remove the tombstone so the new table takes precedence.



68
69
70
71
# File 'lib/active_record/connection_adapters/postgresql/branched/adapter.rb', line 68

def create_table(*args, **kwargs, &block)
  @shadow&.undrop_table(args.first)
  super
end

#drop_table(*table_names, **options) ⇒ Object

Shadow each table so DROP resolves to the branch copy, then create a tombstone in the dropped schema to block fallthrough.



56
57
58
59
60
61
62
63
64
# File 'lib/active_record/connection_adapters/postgresql/branched/adapter.rb', line 56

def drop_table(*table_names, **options)
  if @branch_manager.primary_branch?
    super
  else
    table_names.each { |t| @shadow&.call(t) }
    super
    table_names.each { |t| @shadow&.drop_table(t) }
  end
end

#rename_table(table_name, new_name, **options) ⇒ Object

rename_table needs special handling: the shadow table’s sequences live in public, but Rails’ rename_table tries to rename them using the branch schema. The table and index renames succeed before the sequence rename fails, so we rescue the sequence error.



87
88
89
90
91
92
93
# File 'lib/active_record/connection_adapters/postgresql/branched/adapter.rb', line 87

def rename_table(table_name, new_name, **options)
  @shadow&.call(table_name)
  super
rescue ActiveRecord::StatementInvalid => e
  raise if @branch_manager.primary_branch?
  raise unless e.cause.is_a?(PG::UndefinedTable)
end

#table_dropped_on_branch?(table_name) ⇒ Boolean

Returns:

  • (Boolean)


97
98
99
# File 'lib/active_record/connection_adapters/postgresql/branched/adapter.rb', line 97

def table_dropped_on_branch?(table_name)
  @shadow&.dropped?(table_name) || false
end