activerecord 6.0.0.beta2 → 6.0.2.rc1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +471 -9
- data/README.rdoc +3 -1
- data/lib/active_record.rb +0 -1
- data/lib/active_record/association_relation.rb +15 -6
- data/lib/active_record/associations.rb +4 -3
- data/lib/active_record/associations/association.rb +10 -2
- data/lib/active_record/associations/builder/association.rb +14 -18
- data/lib/active_record/associations/builder/belongs_to.rb +5 -2
- data/lib/active_record/associations/builder/collection_association.rb +5 -15
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +1 -1
- data/lib/active_record/associations/builder/has_many.rb +2 -0
- data/lib/active_record/associations/builder/has_one.rb +35 -1
- data/lib/active_record/associations/builder/singular_association.rb +2 -0
- data/lib/active_record/associations/collection_association.rb +6 -2
- data/lib/active_record/associations/collection_proxy.rb +2 -2
- data/lib/active_record/associations/has_many_through_association.rb +4 -11
- data/lib/active_record/associations/join_dependency.rb +14 -9
- data/lib/active_record/associations/join_dependency/join_association.rb +12 -3
- data/lib/active_record/associations/preloader.rb +13 -8
- data/lib/active_record/associations/preloader/association.rb +34 -30
- data/lib/active_record/associations/preloader/through_association.rb +48 -28
- data/lib/active_record/attribute_methods.rb +3 -53
- data/lib/active_record/attribute_methods/before_type_cast.rb +4 -1
- data/lib/active_record/attribute_methods/dirty.rb +47 -14
- data/lib/active_record/attribute_methods/primary_key.rb +7 -15
- data/lib/active_record/attribute_methods/query.rb +2 -3
- data/lib/active_record/attribute_methods/read.rb +3 -9
- data/lib/active_record/attribute_methods/write.rb +6 -12
- data/lib/active_record/attributes.rb +13 -0
- data/lib/active_record/autosave_association.rb +21 -7
- data/lib/active_record/base.rb +0 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +109 -11
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +8 -4
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +88 -61
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +6 -4
- data/lib/active_record/connection_adapters/abstract/quoting.rb +63 -6
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +4 -7
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +79 -22
- data/lib/active_record/connection_adapters/abstract/transaction.rb +12 -4
- data/lib/active_record/connection_adapters/abstract_adapter.rb +114 -34
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +78 -73
- data/lib/active_record/connection_adapters/column.rb +17 -13
- data/lib/active_record/connection_adapters/connection_specification.rb +2 -2
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +2 -2
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +48 -8
- data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -7
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +7 -5
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +10 -7
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +6 -10
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +18 -5
- data/lib/active_record/connection_adapters/postgresql/column.rb +17 -30
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +8 -2
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +39 -2
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +34 -38
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +23 -27
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +68 -27
- data/lib/active_record/connection_adapters/schema_cache.rb +32 -14
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +11 -8
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +120 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +38 -2
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +2 -2
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +66 -114
- data/lib/active_record/connection_handling.rb +31 -13
- data/lib/active_record/core.rb +23 -24
- data/lib/active_record/database_configurations.rb +73 -44
- data/lib/active_record/database_configurations/hash_config.rb +11 -11
- data/lib/active_record/database_configurations/url_config.rb +12 -12
- data/lib/active_record/dynamic_matchers.rb +1 -1
- data/lib/active_record/enum.rb +15 -0
- data/lib/active_record/errors.rb +1 -1
- data/lib/active_record/fixtures.rb +11 -6
- data/lib/active_record/gem_version.rb +2 -2
- data/lib/active_record/insert_all.rb +179 -0
- data/lib/active_record/integration.rb +13 -1
- data/lib/active_record/internal_metadata.rb +5 -1
- data/lib/active_record/locking/optimistic.rb +3 -4
- data/lib/active_record/log_subscriber.rb +1 -1
- data/lib/active_record/middleware/database_selector.rb +3 -3
- data/lib/active_record/middleware/database_selector/resolver.rb +4 -6
- data/lib/active_record/migration.rb +62 -44
- data/lib/active_record/migration/command_recorder.rb +28 -14
- data/lib/active_record/migration/compatibility.rb +10 -0
- data/lib/active_record/model_schema.rb +3 -0
- data/lib/active_record/persistence.rb +206 -13
- data/lib/active_record/querying.rb +17 -12
- data/lib/active_record/railtie.rb +0 -1
- data/lib/active_record/railties/databases.rake +127 -25
- data/lib/active_record/reflection.rb +3 -3
- data/lib/active_record/relation.rb +99 -20
- data/lib/active_record/relation/calculations.rb +38 -40
- data/lib/active_record/relation/delegation.rb +22 -30
- data/lib/active_record/relation/finder_methods.rb +17 -12
- data/lib/active_record/relation/merger.rb +11 -16
- data/lib/active_record/relation/query_methods.rb +228 -76
- data/lib/active_record/relation/where_clause.rb +9 -5
- data/lib/active_record/sanitization.rb +33 -4
- data/lib/active_record/schema.rb +1 -1
- data/lib/active_record/schema_dumper.rb +10 -1
- data/lib/active_record/schema_migration.rb +1 -1
- data/lib/active_record/scoping/default.rb +6 -7
- data/lib/active_record/scoping/named.rb +3 -2
- data/lib/active_record/statement_cache.rb +2 -2
- data/lib/active_record/store.rb +48 -0
- data/lib/active_record/table_metadata.rb +9 -13
- data/lib/active_record/tasks/database_tasks.rb +109 -6
- data/lib/active_record/tasks/mysql_database_tasks.rb +3 -1
- data/lib/active_record/test_databases.rb +1 -16
- data/lib/active_record/test_fixtures.rb +1 -0
- data/lib/active_record/timestamp.rb +26 -16
- data/lib/active_record/touch_later.rb +4 -2
- data/lib/active_record/transactions.rb +56 -46
- data/lib/active_record/type_caster/connection.rb +16 -10
- data/lib/active_record/validations.rb +1 -0
- data/lib/active_record/validations/uniqueness.rb +3 -5
- data/lib/arel.rb +12 -5
- data/lib/arel/insert_manager.rb +3 -3
- data/lib/arel/nodes.rb +2 -1
- data/lib/arel/nodes/comment.rb +29 -0
- data/lib/arel/nodes/select_core.rb +16 -12
- data/lib/arel/nodes/unary.rb +1 -0
- data/lib/arel/nodes/values_list.rb +2 -17
- data/lib/arel/select_manager.rb +10 -10
- data/lib/arel/visitors/depth_first.rb +7 -2
- data/lib/arel/visitors/dot.rb +7 -2
- data/lib/arel/visitors/ibm_db.rb +13 -0
- data/lib/arel/visitors/informix.rb +6 -0
- data/lib/arel/visitors/mssql.rb +15 -1
- data/lib/arel/visitors/oracle12.rb +4 -5
- data/lib/arel/visitors/postgresql.rb +4 -10
- data/lib/arel/visitors/to_sql.rb +107 -131
- data/lib/arel/visitors/visitor.rb +9 -5
- data/lib/rails/generators/active_record/migration/migration_generator.rb +1 -1
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +1 -1
- data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +4 -2
- data/lib/rails/generators/active_record/model/model_generator.rb +1 -1
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
- metadata +16 -12
- data/lib/active_record/collection_cache_key.rb +0 -53
- data/lib/arel/nodes/values.rb +0 -16
@@ -5,7 +5,7 @@ module ActiveRecord
|
|
5
5
|
module ConnectionAdapters
|
6
6
|
# An abstract definition of a column in a table.
|
7
7
|
class Column
|
8
|
-
attr_reader :name, :default, :sql_type_metadata, :null, :
|
8
|
+
attr_reader :name, :default, :sql_type_metadata, :null, :default_function, :collation, :comment
|
9
9
|
|
10
10
|
delegate :precision, :scale, :limit, :type, :sql_type, to: :sql_type_metadata, allow_nil: true
|
11
11
|
|
@@ -15,9 +15,8 @@ module ActiveRecord
|
|
15
15
|
# +default+ is the type-casted default value, such as +new+ in <tt>sales_stage varchar(20) default 'new'</tt>.
|
16
16
|
# +sql_type_metadata+ is various information about the type of the column
|
17
17
|
# +null+ determines if this column allows +NULL+ values.
|
18
|
-
def initialize(name, default, sql_type_metadata = nil, null = true,
|
18
|
+
def initialize(name, default, sql_type_metadata = nil, null = true, default_function = nil, collation: nil, comment: nil, **)
|
19
19
|
@name = name.freeze
|
20
|
-
@table_name = table_name
|
21
20
|
@sql_type_metadata = sql_type_metadata
|
22
21
|
@null = null
|
23
22
|
@default = default
|
@@ -44,7 +43,6 @@ module ActiveRecord
|
|
44
43
|
|
45
44
|
def init_with(coder)
|
46
45
|
@name = coder["name"]
|
47
|
-
@table_name = coder["table_name"]
|
48
46
|
@sql_type_metadata = coder["sql_type_metadata"]
|
49
47
|
@null = coder["null"]
|
50
48
|
@default = coder["default"]
|
@@ -55,7 +53,6 @@ module ActiveRecord
|
|
55
53
|
|
56
54
|
def encode_with(coder)
|
57
55
|
coder["name"] = @name
|
58
|
-
coder["table_name"] = @table_name
|
59
56
|
coder["sql_type_metadata"] = @sql_type_metadata
|
60
57
|
coder["null"] = @null
|
61
58
|
coder["default"] = @default
|
@@ -66,19 +63,26 @@ module ActiveRecord
|
|
66
63
|
|
67
64
|
def ==(other)
|
68
65
|
other.is_a?(Column) &&
|
69
|
-
|
66
|
+
name == other.name &&
|
67
|
+
default == other.default &&
|
68
|
+
sql_type_metadata == other.sql_type_metadata &&
|
69
|
+
null == other.null &&
|
70
|
+
default_function == other.default_function &&
|
71
|
+
collation == other.collation &&
|
72
|
+
comment == other.comment
|
70
73
|
end
|
71
74
|
alias :eql? :==
|
72
75
|
|
73
76
|
def hash
|
74
|
-
|
77
|
+
Column.hash ^
|
78
|
+
name.hash ^
|
79
|
+
default.hash ^
|
80
|
+
sql_type_metadata.hash ^
|
81
|
+
null.hash ^
|
82
|
+
default_function.hash ^
|
83
|
+
collation.hash ^
|
84
|
+
comment.hash
|
75
85
|
end
|
76
|
-
|
77
|
-
protected
|
78
|
-
|
79
|
-
def attributes_for_hash
|
80
|
-
[self.class, name, default, sql_type_metadata, null, table_name, default_function, collation]
|
81
|
-
end
|
82
86
|
end
|
83
87
|
|
84
88
|
class NullColumn < Column
|
@@ -186,7 +186,7 @@ module ActiveRecord
|
|
186
186
|
adapter_method = "#{spec[:adapter]}_connection"
|
187
187
|
|
188
188
|
unless ActiveRecord::Base.respond_to?(adapter_method)
|
189
|
-
raise AdapterNotFound, "database configuration specifies nonexistent #{spec
|
189
|
+
raise AdapterNotFound, "database configuration specifies nonexistent #{spec[:adapter]} adapter"
|
190
190
|
end
|
191
191
|
|
192
192
|
ConnectionSpecification.new(spec.delete(:name) || "primary", spec, adapter_method)
|
@@ -222,7 +222,7 @@ module ActiveRecord
|
|
222
222
|
when Hash
|
223
223
|
resolve_hash_connection config_or_env
|
224
224
|
else
|
225
|
-
|
225
|
+
raise TypeError, "Invalid type for configuration. Expected Symbol, String, or Hash. Got #{config_or_env.inspect}"
|
226
226
|
end
|
227
227
|
end
|
228
228
|
|
@@ -5,7 +5,7 @@ module ActiveRecord
|
|
5
5
|
module DetermineIfPreparableVisitor
|
6
6
|
attr_accessor :preparable
|
7
7
|
|
8
|
-
def accept(
|
8
|
+
def accept(object, collector)
|
9
9
|
@preparable = true
|
10
10
|
super
|
11
11
|
end
|
@@ -20,7 +20,7 @@ module ActiveRecord
|
|
20
20
|
super
|
21
21
|
end
|
22
22
|
|
23
|
-
def visit_Arel_Nodes_SqlLiteral(
|
23
|
+
def visit_Arel_Nodes_SqlLiteral(o, collector)
|
24
24
|
@preparable = false
|
25
25
|
super
|
26
26
|
end
|
@@ -11,7 +11,7 @@ module ActiveRecord
|
|
11
11
|
else
|
12
12
|
super
|
13
13
|
end
|
14
|
-
|
14
|
+
@connection.abandon_results!
|
15
15
|
result
|
16
16
|
end
|
17
17
|
|
@@ -19,7 +19,9 @@ module ActiveRecord
|
|
19
19
|
execute(sql, name).to_a
|
20
20
|
end
|
21
21
|
|
22
|
-
READ_QUERY = ActiveRecord::ConnectionAdapters::AbstractAdapter.build_read_query_regexp(
|
22
|
+
READ_QUERY = ActiveRecord::ConnectionAdapters::AbstractAdapter.build_read_query_regexp(
|
23
|
+
:begin, :commit, :explain, :select, :set, :show, :release, :savepoint, :rollback, :describe, :desc, :with
|
24
|
+
) # :nodoc:
|
23
25
|
private_constant :READ_QUERY
|
24
26
|
|
25
27
|
def write_query?(sql) # :nodoc:
|
@@ -61,7 +63,9 @@ module ActiveRecord
|
|
61
63
|
|
62
64
|
def exec_delete(sql, name = nil, binds = [])
|
63
65
|
if without_prepared_statement?(binds)
|
64
|
-
|
66
|
+
@lock.synchronize do
|
67
|
+
execute_and_free(sql, name) { @connection.affected_rows }
|
68
|
+
end
|
65
69
|
else
|
66
70
|
exec_stmt_and_free(sql, name, binds) { |stmt| stmt.affected_rows }
|
67
71
|
end
|
@@ -69,22 +73,31 @@ module ActiveRecord
|
|
69
73
|
alias :exec_update :exec_delete
|
70
74
|
|
71
75
|
private
|
76
|
+
def execute_batch(sql, name = nil)
|
77
|
+
super
|
78
|
+
@connection.abandon_results!
|
79
|
+
end
|
80
|
+
|
72
81
|
def default_insert_value(column)
|
73
|
-
|
82
|
+
super unless column.auto_increment?
|
74
83
|
end
|
75
84
|
|
76
85
|
def last_inserted_id(result)
|
77
86
|
@connection.last_id
|
78
87
|
end
|
79
88
|
|
80
|
-
def discard_remaining_results
|
81
|
-
@connection.abandon_results!
|
82
|
-
end
|
83
|
-
|
84
89
|
def supports_set_server_option?
|
85
90
|
@connection.respond_to?(:set_server_option)
|
86
91
|
end
|
87
92
|
|
93
|
+
def build_truncate_statements(*table_names)
|
94
|
+
if table_names.size == 1
|
95
|
+
super.first
|
96
|
+
else
|
97
|
+
super
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
88
101
|
def multi_statements_enabled?(flags)
|
89
102
|
if flags.is_a?(Array)
|
90
103
|
flags.include?("MULTI_STATEMENTS")
|
@@ -117,6 +130,33 @@ module ActiveRecord
|
|
117
130
|
end
|
118
131
|
end
|
119
132
|
|
133
|
+
def combine_multi_statements(total_sql)
|
134
|
+
total_sql.each_with_object([]) do |sql, total_sql_chunks|
|
135
|
+
previous_packet = total_sql_chunks.last
|
136
|
+
if max_allowed_packet_reached?(sql, previous_packet)
|
137
|
+
total_sql_chunks << +sql
|
138
|
+
else
|
139
|
+
previous_packet << ";\n"
|
140
|
+
previous_packet << sql
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def max_allowed_packet_reached?(current_packet, previous_packet)
|
146
|
+
if current_packet.bytesize > max_allowed_packet
|
147
|
+
raise ActiveRecordError,
|
148
|
+
"Fixtures set is too large #{current_packet.bytesize}. Consider increasing the max_allowed_packet variable."
|
149
|
+
elsif previous_packet.nil?
|
150
|
+
true
|
151
|
+
else
|
152
|
+
(current_packet.bytesize + previous_packet.bytesize + 2) > max_allowed_packet
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def max_allowed_packet
|
157
|
+
@max_allowed_packet ||= show_variable("max_allowed_packet")
|
158
|
+
end
|
159
|
+
|
120
160
|
def exec_stmt_and_free(sql, name, binds, cache_stmt: false)
|
121
161
|
if preventing_writes? && write_query?(sql)
|
122
162
|
raise ActiveRecord::ReadOnlyError, "Write query attempted while in readonly mode: #{sql}"
|
@@ -5,11 +5,11 @@ module ActiveRecord
|
|
5
5
|
module MySQL
|
6
6
|
module Quoting # :nodoc:
|
7
7
|
def quote_column_name(name)
|
8
|
-
|
8
|
+
self.class.quoted_column_names[name] ||= "`#{super.gsub('`', '``')}`"
|
9
9
|
end
|
10
10
|
|
11
11
|
def quote_table_name(name)
|
12
|
-
|
12
|
+
self.class.quoted_table_names[name] ||= super.gsub(".", "`.`").freeze
|
13
13
|
end
|
14
14
|
|
15
15
|
def unquoted_true
|
@@ -32,12 +32,49 @@ module ActiveRecord
|
|
32
32
|
"x'#{value.hex}'"
|
33
33
|
end
|
34
34
|
|
35
|
-
def
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
35
|
+
def column_name_matcher
|
36
|
+
COLUMN_NAME
|
37
|
+
end
|
38
|
+
|
39
|
+
def column_name_with_order_matcher
|
40
|
+
COLUMN_NAME_WITH_ORDER
|
40
41
|
end
|
42
|
+
|
43
|
+
COLUMN_NAME = /
|
44
|
+
\A
|
45
|
+
(
|
46
|
+
(?:
|
47
|
+
# `table_name`.`column_name` | function(one or no argument)
|
48
|
+
((?:\w+\.|`\w+`\.)?(?:\w+|`\w+`)) | \w+\((?:|\g<2>)\)
|
49
|
+
)
|
50
|
+
(?:\s+AS\s+(?:\w+|`\w+`))?
|
51
|
+
)
|
52
|
+
(?:\s*,\s*\g<1>)*
|
53
|
+
\z
|
54
|
+
/ix
|
55
|
+
|
56
|
+
COLUMN_NAME_WITH_ORDER = /
|
57
|
+
\A
|
58
|
+
(
|
59
|
+
(?:
|
60
|
+
# `table_name`.`column_name` | function(one or no argument)
|
61
|
+
((?:\w+\.|`\w+`\.)?(?:\w+|`\w+`)) | \w+\((?:|\g<2>)\)
|
62
|
+
)
|
63
|
+
(?:\s+ASC|\s+DESC)?
|
64
|
+
)
|
65
|
+
(?:\s*,\s*\g<1>)*
|
66
|
+
\z
|
67
|
+
/ix
|
68
|
+
|
69
|
+
private_constant :COLUMN_NAME, :COLUMN_NAME_WITH_ORDER
|
70
|
+
|
71
|
+
private
|
72
|
+
def _type_cast(value)
|
73
|
+
case value
|
74
|
+
when Date, Time then value
|
75
|
+
else super
|
76
|
+
end
|
77
|
+
end
|
41
78
|
end
|
42
79
|
end
|
43
80
|
end
|
@@ -41,13 +41,15 @@ module ActiveRecord
|
|
41
41
|
case column.sql_type
|
42
42
|
when /\Atimestamp\b/
|
43
43
|
:timestamp
|
44
|
+
when /\A(?:enum|set)\b/
|
45
|
+
column.sql_type
|
44
46
|
else
|
45
47
|
super
|
46
48
|
end
|
47
49
|
end
|
48
50
|
|
49
51
|
def schema_limit(column)
|
50
|
-
super unless /\A(?:tiny|medium|long)?(?:text|blob)/.match?(column.sql_type)
|
52
|
+
super unless /\A(?:enum|set|(?:tiny|medium|long)?(?:text|blob))\b/.match?(column.sql_type)
|
51
53
|
end
|
52
54
|
|
53
55
|
def schema_precision(column)
|
@@ -55,7 +57,7 @@ module ActiveRecord
|
|
55
57
|
end
|
56
58
|
|
57
59
|
def schema_collation(column)
|
58
|
-
if column.collation
|
60
|
+
if column.collation
|
59
61
|
@table_collation_cache ||= {}
|
60
62
|
@table_collation_cache[table_name] ||=
|
61
63
|
@connection.exec_query("SHOW TABLE STATUS LIKE #{@connection.quote(table_name)}", "SCHEMA").first["Collation"]
|
@@ -64,14 +66,14 @@ module ActiveRecord
|
|
64
66
|
end
|
65
67
|
|
66
68
|
def extract_expression_for_virtual_column(column)
|
67
|
-
if @connection.mariadb? && @connection.
|
68
|
-
create_table_info = @connection.send(:create_table_info,
|
69
|
+
if @connection.mariadb? && @connection.database_version < "10.2.5"
|
70
|
+
create_table_info = @connection.send(:create_table_info, table_name)
|
69
71
|
column_name = @connection.quote_column_name(column.name)
|
70
72
|
if %r/#{column_name} #{Regexp.quote(column.sql_type)}(?: COLLATE \w+)? AS \((?<expression>.+?)\) #{column.extra}/ =~ create_table_info
|
71
73
|
$~[:expression].inspect
|
72
74
|
end
|
73
75
|
else
|
74
|
-
scope = @connection.send(:quoted_scope,
|
76
|
+
scope = @connection.send(:quoted_scope, table_name)
|
75
77
|
column_name = @connection.quote(column.name)
|
76
78
|
sql = "SELECT generation_expression FROM information_schema.columns" \
|
77
79
|
" WHERE table_schema = #{scope[:schema]}" \
|
@@ -121,14 +121,18 @@ module ActiveRecord
|
|
121
121
|
sql
|
122
122
|
end
|
123
123
|
|
124
|
+
def table_alias_length
|
125
|
+
256 # https://dev.mysql.com/doc/refman/8.0/en/identifiers.html
|
126
|
+
end
|
127
|
+
|
124
128
|
private
|
125
129
|
CHARSETS_OF_4BYTES_MAXLEN = ["utf8mb4", "utf16", "utf16le", "utf32"]
|
126
130
|
|
127
131
|
def row_format_dynamic_by_default?
|
128
132
|
if mariadb?
|
129
|
-
|
133
|
+
database_version >= "10.2.2"
|
130
134
|
else
|
131
|
-
|
135
|
+
database_version >= "5.7.9"
|
132
136
|
end
|
133
137
|
end
|
134
138
|
|
@@ -158,7 +162,7 @@ module ActiveRecord
|
|
158
162
|
type_metadata = fetch_type_metadata(field[:Type], field[:Extra])
|
159
163
|
default, default_function = field[:Default], nil
|
160
164
|
|
161
|
-
if type_metadata.type == :datetime && /\ACURRENT_TIMESTAMP(?:\([0-6]?\))?\z/i.match?(default)
|
165
|
+
if type_metadata.type == :datetime && default && /\ACURRENT_TIMESTAMP(?:\([0-6]?\))?\z/i.match?(default)
|
162
166
|
default, default_function = nil, default
|
163
167
|
elsif type_metadata.extra == "DEFAULT_GENERATED"
|
164
168
|
default = +"(#{default})" unless default.start_with?("(")
|
@@ -170,9 +174,8 @@ module ActiveRecord
|
|
170
174
|
default,
|
171
175
|
type_metadata,
|
172
176
|
field[:Null] == "YES",
|
173
|
-
table_name,
|
174
177
|
default_function,
|
175
|
-
field[:Collation],
|
178
|
+
collation: field[:Collation],
|
176
179
|
comment: field[:Comment].presence
|
177
180
|
)
|
178
181
|
end
|
@@ -240,7 +243,7 @@ module ActiveRecord
|
|
240
243
|
when nil, 0x100..0xffff; nil
|
241
244
|
when 0x10000..0xffffff; "medium"
|
242
245
|
when 0x1000000..0xffffffff; "long"
|
243
|
-
else raise
|
246
|
+
else raise ArgumentError, "No #{type} type has byte size #{limit}"
|
244
247
|
end
|
245
248
|
end
|
246
249
|
end
|
@@ -252,7 +255,7 @@ module ActiveRecord
|
|
252
255
|
when 3; "mediumint"
|
253
256
|
when nil, 4; "int"
|
254
257
|
when 5..8; "bigint"
|
255
|
-
else raise
|
258
|
+
else raise ArgumentError, "No integer type has byte size #{limit}. Use a decimal with scale 0 instead."
|
256
259
|
end
|
257
260
|
end
|
258
261
|
end
|
@@ -10,25 +10,21 @@ module ActiveRecord
|
|
10
10
|
|
11
11
|
def initialize(type_metadata, extra: "")
|
12
12
|
super(type_metadata)
|
13
|
-
@type_metadata = type_metadata
|
14
13
|
@extra = extra
|
15
14
|
end
|
16
15
|
|
17
16
|
def ==(other)
|
18
|
-
other.is_a?(
|
19
|
-
|
17
|
+
other.is_a?(TypeMetadata) &&
|
18
|
+
__getobj__ == other.__getobj__ &&
|
19
|
+
extra == other.extra
|
20
20
|
end
|
21
21
|
alias eql? ==
|
22
22
|
|
23
23
|
def hash
|
24
|
-
|
24
|
+
TypeMetadata.hash ^
|
25
|
+
__getobj__.hash ^
|
26
|
+
extra.hash
|
25
27
|
end
|
26
|
-
|
27
|
-
protected
|
28
|
-
|
29
|
-
def attributes_for_hash
|
30
|
-
[self.class, @type_metadata, extra]
|
31
|
-
end
|
32
28
|
end
|
33
29
|
end
|
34
30
|
end
|
@@ -8,6 +8,8 @@ require "mysql2"
|
|
8
8
|
|
9
9
|
module ActiveRecord
|
10
10
|
module ConnectionHandling # :nodoc:
|
11
|
+
ER_BAD_DB_ERROR = 1049
|
12
|
+
|
11
13
|
# Establishes a connection to the database that's used by all Active Record objects.
|
12
14
|
def mysql2_connection(config)
|
13
15
|
config = config.symbolize_keys
|
@@ -22,7 +24,7 @@ module ActiveRecord
|
|
22
24
|
client = Mysql2::Client.new(config)
|
23
25
|
ConnectionAdapters::Mysql2Adapter.new(client, logger, nil, config)
|
24
26
|
rescue Mysql2::Error => error
|
25
|
-
if error.
|
27
|
+
if error.error_number == ER_BAD_DB_ERROR
|
26
28
|
raise ActiveRecord::NoDatabaseError
|
27
29
|
else
|
28
30
|
raise
|
@@ -37,13 +39,19 @@ module ActiveRecord
|
|
37
39
|
include MySQL::DatabaseStatements
|
38
40
|
|
39
41
|
def initialize(connection, logger, connection_options, config)
|
40
|
-
|
41
|
-
|
42
|
+
superclass_config = config.reverse_merge(prepared_statements: false)
|
43
|
+
super(connection, logger, connection_options, superclass_config)
|
42
44
|
configure_connection
|
43
45
|
end
|
44
46
|
|
47
|
+
def self.database_exists?(config)
|
48
|
+
!!ActiveRecord::Base.mysql2_connection(config)
|
49
|
+
rescue ActiveRecord::NoDatabaseError
|
50
|
+
false
|
51
|
+
end
|
52
|
+
|
45
53
|
def supports_json?
|
46
|
-
!mariadb? &&
|
54
|
+
!mariadb? && database_version >= "5.7.8"
|
47
55
|
end
|
48
56
|
|
49
57
|
def supports_comments?
|
@@ -109,6 +117,7 @@ module ActiveRecord
|
|
109
117
|
end
|
110
118
|
|
111
119
|
def discard! # :nodoc:
|
120
|
+
super
|
112
121
|
@connection.automatic_close = false
|
113
122
|
@connection = nil
|
114
123
|
end
|
@@ -126,7 +135,11 @@ module ActiveRecord
|
|
126
135
|
end
|
127
136
|
|
128
137
|
def full_version
|
129
|
-
|
138
|
+
schema_cache.database_version.full_version_string
|
139
|
+
end
|
140
|
+
|
141
|
+
def get_full_version
|
142
|
+
@connection.server_info[:version]
|
130
143
|
end
|
131
144
|
end
|
132
145
|
end
|