Skip to content

Commit f10a646

Browse files
authored
Merge pull request rails#30337 from kamipo/refactor_schema_dumper
Refactor `SchemaDumper` to make it possible to adapter specific customization
2 parents b0d5892 + 815dd11 commit f10a646

15 files changed

+54
-56
lines changed

activerecord/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
* Remove deprecated `#migration_keys`.
2+
3+
*Ryuta Kamizono*
4+
15
* Automatically guess the inverse associations for STI.
26

37
*Yuichiro Kaneko*

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

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,24 @@
44

55
module ActiveRecord
66
module ConnectionAdapters # :nodoc:
7-
# The goal of this module is to move Adapter specific column
8-
# definitions to the Adapter instead of having it in the schema
9-
# dumper itself. This code represents the normal case.
10-
# We can then redefine how certain data types may be handled in the schema dumper on the
11-
# Adapter level by over-writing this code inside the database specific adapters
12-
module ColumnDumper
13-
def column_spec(column)
14-
[schema_type_with_virtual(column), prepare_column_options(column)]
7+
class SchemaDumper < SchemaDumper # :nodoc:
8+
def self.create(connection, options)
9+
new(connection, options)
1510
end
1611

17-
def column_spec_for_primary_key(column)
18-
return {} if default_primary_key?(column)
19-
spec = { id: schema_type(column).inspect }
20-
spec.merge!(prepare_column_options(column).except!(:null))
21-
spec[:default] ||= "nil" if explicit_primary_key_default?(column)
22-
spec
23-
end
12+
private
13+
def column_spec(column)
14+
[schema_type_with_virtual(column), prepare_column_options(column)]
15+
end
2416

25-
# Lists the valid migration options
26-
def migration_keys # :nodoc:
27-
column_options_keys
28-
end
29-
deprecate :migration_keys
17+
def column_spec_for_primary_key(column)
18+
return {} if default_primary_key?(column)
19+
spec = { id: schema_type(column).inspect }
20+
spec.merge!(prepare_column_options(column).except!(:null))
21+
spec[:default] ||= "nil" if explicit_primary_key_default?(column)
22+
spec
23+
end
3024

31-
private
3225
def prepare_column_options(column)
3326
spec = {}
3427
spec[:limit] = schema_limit(column)
@@ -51,7 +44,7 @@ def explicit_primary_key_default?(column)
5144
end
5245

5346
def schema_type_with_virtual(column)
54-
if supports_virtual_columns? && column.virtual?
47+
if @connection.supports_virtual_columns? && column.virtual?
5548
:virtual
5649
else
5750
schema_type(column)
@@ -68,7 +61,7 @@ def schema_type(column)
6861

6962
def schema_limit(column)
7063
limit = column.limit unless column.bigint?
71-
limit.inspect if limit && limit != native_database_types[column.type][:limit]
64+
limit.inspect if limit && limit != @connection.native_database_types[column.type][:limit]
7265
end
7366

7467
def schema_precision(column)
@@ -81,7 +74,7 @@ def schema_scale(column)
8174

8275
def schema_default(column)
8376
return unless column.has_default?
84-
type = lookup_cast_type_from_column(column)
77+
type = @connection.lookup_cast_type_from_column(column)
8578
default = type.deserialize(column.default)
8679
if default.nil?
8780
schema_expression(column)

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1174,6 +1174,10 @@ def change_column_comment(table_name, column_name, comment) #:nodoc:
11741174
raise NotImplementedError, "#{self.class} does not support changing column comments"
11751175
end
11761176

1177+
def create_schema_dumper(options) # :nodoc:
1178+
SchemaDumper.create(self, options)
1179+
end
1180+
11771181
private
11781182
def column_options_keys
11791183
[:limit, :precision, :scale, :default, :null, :collation, :comment]

activerecord/lib/active_record/connection_adapters/abstract_adapter.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@ class AbstractAdapter
7272
include Quoting, DatabaseStatements, SchemaStatements
7373
include DatabaseLimits
7474
include QueryCache
75-
include ColumnDumper
7675
include Savepoints
7776

7877
SIMPLE_INT = /\A\d+\z/

activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ module ActiveRecord
1717
module ConnectionAdapters
1818
class AbstractMysqlAdapter < AbstractAdapter
1919
include MySQL::Quoting
20-
include MySQL::ColumnDumper
2120
include MySQL::SchemaStatements
2221

2322
##

activerecord/lib/active_record/connection_adapters/mysql/schema_dumper.rb

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,13 @@
33
module ActiveRecord
44
module ConnectionAdapters
55
module MySQL
6-
module ColumnDumper # :nodoc:
7-
def migration_keys
8-
super + [:unsigned]
9-
end
10-
6+
class SchemaDumper < ConnectionAdapters::SchemaDumper # :nodoc:
117
private
128
def prepare_column_options(column)
139
spec = super
1410
spec[:unsigned] = "true" if column.unsigned?
1511

16-
if supports_virtual_columns? && column.virtual?
12+
if @connection.supports_virtual_columns? && column.virtual?
1713
spec[:as] = extract_expression_for_virtual_column(column)
1814
spec[:stored] = "true" if /\b(?:STORED|PERSISTENT)\b/.match?(column.extra)
1915
spec = { type: schema_type(column).inspect }.merge!(spec)
@@ -48,24 +44,27 @@ def schema_precision(column)
4844
def schema_collation(column)
4945
if column.collation && table_name = column.table_name
5046
@table_collation_cache ||= {}
51-
@table_collation_cache[table_name] ||= exec_query("SHOW TABLE STATUS LIKE #{quote(table_name)}", "SCHEMA").first["Collation"]
47+
@table_collation_cache[table_name] ||=
48+
@connection.exec_query("SHOW TABLE STATUS LIKE #{@connection.quote(table_name)}", "SCHEMA").first["Collation"]
5249
column.collation.inspect if column.collation != @table_collation_cache[table_name]
5350
end
5451
end
5552

5653
def extract_expression_for_virtual_column(column)
57-
if mariadb? && version < "10.2.5"
58-
create_table_info = create_table_info(column.table_name)
59-
if %r/#{quote_column_name(column.name)} #{Regexp.quote(column.sql_type)}(?: COLLATE \w+)? AS \((?<expression>.+?)\) #{column.extra}/ =~ create_table_info
54+
if @connection.mariadb? && @connection.version < "10.2.5"
55+
create_table_info = @connection.send(:create_table_info, column.table_name)
56+
column_name = @connection.quote_column_name(column.name)
57+
if %r/#{column_name} #{Regexp.quote(column.sql_type)}(?: COLLATE \w+)? AS \((?<expression>.+?)\) #{column.extra}/ =~ create_table_info
6058
$~[:expression].inspect
6159
end
6260
else
63-
scope = quoted_scope(column.table_name)
61+
scope = @connection.send(:quoted_scope, column.table_name)
62+
column_name = @connection.quote(column.name)
6463
sql = "SELECT generation_expression FROM information_schema.columns" \
6564
" WHERE table_schema = #{scope[:schema]}" \
6665
" AND table_name = #{scope[:name]}" \
67-
" AND column_name = #{quote(column.name)}"
68-
query_value(sql, "SCHEMA").inspect
66+
" AND column_name = #{column_name}"
67+
@connection.query_value(sql, "SCHEMA").inspect
6968
end
7069
end
7170
end

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ def update_table_definition(table_name, base)
6666
MySQL::Table.new(table_name, base)
6767
end
6868

69+
def create_schema_dumper(options)
70+
MySQL::SchemaDumper.create(self, options)
71+
end
72+
6973
private
7074
CHARSETS_OF_4BYTES_MAXLEN = ["utf8mb4", "utf16", "utf16le", "utf32"]
7175

activerecord/lib/active_record/connection_adapters/postgresql/schema_dumper.rb

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,7 @@
33
module ActiveRecord
44
module ConnectionAdapters
55
module PostgreSQL
6-
module ColumnDumper # :nodoc:
7-
# Adds +:array+ as a valid migration key
8-
def migration_keys
9-
super + [:array]
10-
end
11-
6+
class SchemaDumper < ConnectionAdapters::SchemaDumper # :nodoc:
127
private
138
def prepare_column_options(column)
149
spec = super

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,10 @@ def update_table_definition(table_name, base) # :nodoc:
590590
PostgreSQL::Table.new(table_name, base)
591591
end
592592

593+
def create_schema_dumper(options) # :nodoc:
594+
PostgreSQL::SchemaDumper.create(self, options)
595+
end
596+
593597
private
594598
def schema_creation
595599
PostgreSQL::SchemaCreation.new(self)

activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,6 @@ class PostgreSQLAdapter < AbstractAdapter
121121
include PostgreSQL::ReferentialIntegrity
122122
include PostgreSQL::SchemaStatements
123123
include PostgreSQL::DatabaseStatements
124-
include PostgreSQL::ColumnDumper
125124

126125
def supports_index_sort_order?
127126
true

activerecord/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@
33
module ActiveRecord
44
module ConnectionAdapters
55
module SQLite3
6-
module ColumnDumper # :nodoc:
6+
class SchemaDumper < ConnectionAdapters::SchemaDumper # :nodoc:
77
private
8-
98
def default_primary_key?(column)
109
schema_type(column) == :integer
1110
end

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ def update_table_definition(table_name, base)
4343
SQLite3::Table.new(table_name, base)
4444
end
4545

46+
def create_schema_dumper(options)
47+
SQLite3::SchemaDumper.create(self, options)
48+
end
49+
4650
private
4751
def schema_creation
4852
SQLite3::SchemaCreation.new(self)

activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ class SQLite3Adapter < AbstractAdapter
5757
ADAPTER_NAME = "SQLite".freeze
5858

5959
include SQLite3::Quoting
60-
include SQLite3::ColumnDumper
6160
include SQLite3::SchemaStatements
6261

6362
NATIVE_DATABASE_TYPES = {

activerecord/lib/active_record/schema_dumper.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class SchemaDumper #:nodoc:
1919

2020
class << self
2121
def dump(connection = ActiveRecord::Base.connection, stream = STDOUT, config = ActiveRecord::Base)
22-
new(connection, generate_options(config)).dump(stream)
22+
connection.create_schema_dumper(generate_options(config)).dump(stream)
2323
stream
2424
end
2525

@@ -123,7 +123,7 @@ def table(table, stream)
123123
when String
124124
tbl.print ", primary_key: #{pk.inspect}" unless pk == "id"
125125
pkcol = columns.detect { |c| c.name == pk }
126-
pkcolspec = @connection.column_spec_for_primary_key(pkcol)
126+
pkcolspec = column_spec_for_primary_key(pkcol)
127127
if pkcolspec.present?
128128
tbl.print ", #{format_colspec(pkcolspec)}"
129129
end
@@ -145,7 +145,7 @@ def table(table, stream)
145145
columns.each do |column|
146146
raise StandardError, "Unknown type '#{column.sql_type}' for column '#{column.name}'" unless @connection.valid_type?(column.type)
147147
next if column.name == pk
148-
type, colspec = @connection.column_spec(column)
148+
type, colspec = column_spec(column)
149149
tbl.print " t.#{type} #{column.name.inspect}"
150150
tbl.print ", #{format_colspec(colspec)}" if colspec.present?
151151
tbl.puts

activerecord/test/cases/migration_test.rb

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,10 +1112,6 @@ def test_deprecate_initialize_internal_tables
11121112
assert_deprecated { ActiveRecord::Base.connection.initialize_internal_metadata_table }
11131113
end
11141114

1115-
def test_deprecate_migration_keys
1116-
assert_deprecated { ActiveRecord::Base.connection.migration_keys }
1117-
end
1118-
11191115
def test_deprecate_supports_migrations
11201116
assert_deprecated { ActiveRecord::Base.connection.supports_migrations? }
11211117
end

0 commit comments

Comments
 (0)