Skip to content

Commit a918394

Browse files
committed
Refactor InternalMetadata, MigrationContext to belong to the pool
Extracted from: rails#50793 Similar to the recent refactoring of schema caches, rather than to directly hold a connection, they now hold a pool and checkout a connection when needed.
1 parent 85c58ff commit a918394

31 files changed

+376
-333
lines changed

activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,22 @@ def initialize(pool_config)
173173
@reaper.run
174174
end
175175

176+
def migration_context # :nodoc:
177+
MigrationContext.new(migrations_paths, schema_migration, internal_metadata)
178+
end
179+
180+
def migrations_paths # :nodoc:
181+
db_config.migrations_paths || Migrator.migrations_paths
182+
end
183+
184+
def schema_migration # :nodoc:
185+
SchemaMigration.new(self)
186+
end
187+
188+
def internal_metadata # :nodoc:
189+
InternalMetadata.new(self)
190+
end
191+
176192
# Retrieve the connection associated with the current thread, or call
177193
# #checkout to obtain one if necessary.
178194
#

activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ def truncate(table_name, name = nil)
214214
end
215215

216216
def truncate_tables(*table_names) # :nodoc:
217-
table_names -= [schema_migration.table_name, internal_metadata.table_name]
217+
table_names -= [pool.schema_migration.table_name, pool.internal_metadata.table_name]
218218

219219
return if table_names.empty?
220220

activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1317,7 +1317,7 @@ def check_constraint_exists?(table_name, **options)
13171317
end
13181318

13191319
def dump_schema_information # :nodoc:
1320-
versions = schema_migration.versions
1320+
versions = pool.schema_migration.versions
13211321
insert_versions_sql(versions) if versions.any?
13221322
end
13231323

@@ -1327,8 +1327,9 @@ def internal_string_options_for_primary_key # :nodoc:
13271327

13281328
def assume_migrated_upto_version(version)
13291329
version = version.to_i
1330-
sm_table = quote_table_name(schema_migration.table_name)
1330+
sm_table = quote_table_name(pool.schema_migration.table_name)
13311331

1332+
migration_context = pool.migration_context
13321333
migrated = migration_context.get_all_versions
13331334
versions = migration_context.migrations.map(&:version)
13341335

@@ -1838,7 +1839,7 @@ def remove_timestamps_for_alter(table_name, **options)
18381839
end
18391840

18401841
def insert_versions_sql(versions)
1841-
sm_table = quote_table_name(schema_migration.table_name)
1842+
sm_table = quote_table_name(pool.schema_migration.table_name)
18421843

18431844
if versions.is_a?(Array)
18441845
sql = +"INSERT INTO #{sm_table} (version) VALUES\n"

activerecord/lib/active_record/connection_adapters/abstract_adapter.rb

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -211,10 +211,6 @@ def replica?
211211
@config[:replica] || false
212212
end
213213

214-
def use_metadata_table?
215-
@config.fetch(:use_metadata_table, true)
216-
end
217-
218214
def connection_retries
219215
(@config[:connection_retries] || 1).to_i
220216
end
@@ -242,22 +238,6 @@ def preventing_writes?
242238
connection_class.current_preventing_writes
243239
end
244240

245-
def migrations_paths # :nodoc:
246-
@config[:migrations_paths] || Migrator.migrations_paths
247-
end
248-
249-
def migration_context # :nodoc:
250-
MigrationContext.new(migrations_paths, schema_migration, internal_metadata)
251-
end
252-
253-
def schema_migration # :nodoc:
254-
SchemaMigration.new(self)
255-
end
256-
257-
def internal_metadata # :nodoc:
258-
InternalMetadata.new(self)
259-
end
260-
261241
def prepared_statements?
262242
@prepared_statements && !prepared_statements_disabled_cache.include?(object_id)
263243
end
@@ -872,7 +852,7 @@ def check_version # :nodoc:
872852
# numbered migration that has been executed, or 0 if no schema
873853
# information is present / the database is empty.
874854
def schema_version
875-
migration_context.current_version
855+
pool.migration_context.current_version
876856
end
877857

878858
class << self

activerecord/lib/active_record/database_configurations/database_config.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@ def for_current_env?
9191
def schema_cache_path
9292
raise NotImplementedError
9393
end
94+
95+
def use_metadata_table?
96+
raise NotImplementedError
97+
end
9498
end
9599
end
96100
end

activerecord/lib/active_record/database_configurations/hash_config.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,10 @@ def database_tasks? # :nodoc:
154154
!replica? && !!configuration_hash.fetch(:database_tasks, true)
155155
end
156156

157+
def use_metadata_table? # :nodoc:
158+
configuration_hash.fetch(:use_metadata_table, true)
159+
end
160+
157161
private
158162
def schema_file_type(format)
159163
case format

activerecord/lib/active_record/internal_metadata.rb

Lines changed: 47 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,13 @@ class InternalMetadata # :nodoc:
1313
class NullInternalMetadata # :nodoc:
1414
end
1515

16-
attr_reader :connection, :arel_table
16+
attr_reader :arel_table
1717

18-
def initialize(connection)
19-
@connection = connection
18+
def initialize(pool)
19+
@pool = pool
2020
@arel_table = Arel::Table.new(table_name)
2121
end
2222

23-
def enabled?
24-
connection.use_metadata_table?
25-
end
26-
2723
def primary_key
2824
"key"
2925
end
@@ -36,108 +32,126 @@ def table_name
3632
"#{ActiveRecord::Base.table_name_prefix}#{ActiveRecord::Base.internal_metadata_table_name}#{ActiveRecord::Base.table_name_suffix}"
3733
end
3834

35+
def enabled?
36+
@pool.db_config.use_metadata_table?
37+
end
38+
3939
def []=(key, value)
4040
return unless enabled?
4141

42-
update_or_create_entry(key, value)
42+
@pool.with_connection do |connection|
43+
update_or_create_entry(connection, key, value)
44+
end
4345
end
4446

4547
def [](key)
4648
return unless enabled?
4749

48-
if entry = select_entry(key)
49-
entry[value_key]
50+
@pool.with_connection do |connection|
51+
if entry = select_entry(connection, key)
52+
entry[value_key]
53+
end
5054
end
5155
end
5256

5357
def delete_all_entries
5458
dm = Arel::DeleteManager.new(arel_table)
5559

56-
connection.delete(dm, "#{self.class} Destroy")
60+
@pool.with_connection do |connection|
61+
connection.delete(dm, "#{self.class} Destroy")
62+
end
5763
end
5864

5965
def count
6066
sm = Arel::SelectManager.new(arel_table)
6167
sm.project(*Arel::Nodes::Count.new([Arel.star]))
6268

63-
connection.select_values(sm, "#{self.class} Count").first
69+
@pool.with_connection do |connection|
70+
connection.select_values(sm, "#{self.class} Count").first
71+
end
6472
end
6573

6674
def create_table_and_set_flags(environment, schema_sha1 = nil)
6775
return unless enabled?
6876

69-
create_table
70-
update_or_create_entry(:environment, environment)
71-
update_or_create_entry(:schema_sha1, schema_sha1) if schema_sha1
77+
@pool.with_connection do |connection|
78+
create_table
79+
update_or_create_entry(connection, :environment, environment)
80+
update_or_create_entry(connection, :schema_sha1, schema_sha1) if schema_sha1
81+
end
7282
end
7383

7484
# Creates an internal metadata table with columns +key+ and +value+
7585
def create_table
7686
return unless enabled?
7787

78-
unless connection.table_exists?(table_name)
79-
connection.create_table(table_name, id: false) do |t|
80-
t.string :key, **connection.internal_string_options_for_primary_key
81-
t.string :value
82-
t.timestamps
88+
@pool.with_connection do |connection|
89+
unless connection.table_exists?(table_name)
90+
connection.create_table(table_name, id: false) do |t|
91+
t.string :key, **connection.internal_string_options_for_primary_key
92+
t.string :value
93+
t.timestamps
94+
end
8395
end
8496
end
8597
end
8698

8799
def drop_table
88100
return unless enabled?
89101

90-
connection.drop_table table_name, if_exists: true
102+
@pool.with_connection do |connection|
103+
connection.drop_table table_name, if_exists: true
104+
end
91105
end
92106

93107
def table_exists?
94-
@connection.schema_cache.data_source_exists?(table_name)
108+
@pool.schema_cache.data_source_exists?(table_name)
95109
end
96110

97111
private
98-
def update_or_create_entry(key, value)
99-
entry = select_entry(key)
112+
def update_or_create_entry(connection, key, value)
113+
entry = select_entry(connection, key)
100114

101115
if entry
102116
if entry[value_key] != value
103-
update_entry(key, value)
117+
update_entry(connection, key, value)
104118
else
105119
entry[value_key]
106120
end
107121
else
108-
create_entry(key, value)
122+
create_entry(connection, key, value)
109123
end
110124
end
111125

112-
def current_time
126+
def current_time(connection)
113127
connection.default_timezone == :utc ? Time.now.utc : Time.now
114128
end
115129

116-
def create_entry(key, value)
130+
def create_entry(connection, key, value)
117131
im = Arel::InsertManager.new(arel_table)
118132
im.insert [
119133
[arel_table[primary_key], key],
120134
[arel_table[value_key], value],
121-
[arel_table[:created_at], current_time],
122-
[arel_table[:updated_at], current_time]
135+
[arel_table[:created_at], current_time(connection)],
136+
[arel_table[:updated_at], current_time(connection)]
123137
]
124138

125139
connection.insert(im, "#{self.class} Create", primary_key, key)
126140
end
127141

128-
def update_entry(key, new_value)
142+
def update_entry(connection, key, new_value)
129143
um = Arel::UpdateManager.new(arel_table)
130144
um.set [
131145
[arel_table[value_key], new_value],
132-
[arel_table[:updated_at], current_time]
146+
[arel_table[:updated_at], current_time(connection)]
133147
]
134148

135149
um.where(arel_table[primary_key].eq(key))
136150

137151
connection.update(um, "#{self.class} Update")
138152
end
139153

140-
def select_entry(key)
154+
def select_entry(connection, key)
141155
sm = Arel::SelectManager.new(arel_table)
142156
sm.project(Arel::Nodes::SqlLiteral.new("*"))
143157
sm.where(arel_table[primary_key].eq(Arel::Nodes::BindParam.new(key)))

0 commit comments

Comments
 (0)