activerecord 6.0.0.beta3 → 6.0.2.rc2

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.

Files changed (142) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +466 -9
  3. data/README.rdoc +3 -1
  4. data/lib/active_record.rb +0 -1
  5. data/lib/active_record/association_relation.rb +15 -6
  6. data/lib/active_record/associations.rb +4 -3
  7. data/lib/active_record/associations/association.rb +10 -2
  8. data/lib/active_record/associations/builder/association.rb +14 -18
  9. data/lib/active_record/associations/builder/belongs_to.rb +5 -2
  10. data/lib/active_record/associations/builder/collection_association.rb +5 -15
  11. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +1 -1
  12. data/lib/active_record/associations/builder/has_many.rb +2 -0
  13. data/lib/active_record/associations/builder/has_one.rb +35 -1
  14. data/lib/active_record/associations/builder/singular_association.rb +2 -0
  15. data/lib/active_record/associations/collection_association.rb +6 -2
  16. data/lib/active_record/associations/collection_proxy.rb +2 -2
  17. data/lib/active_record/associations/has_many_through_association.rb +4 -11
  18. data/lib/active_record/associations/join_dependency.rb +14 -9
  19. data/lib/active_record/associations/join_dependency/join_association.rb +12 -3
  20. data/lib/active_record/associations/preloader.rb +13 -8
  21. data/lib/active_record/associations/preloader/association.rb +34 -30
  22. data/lib/active_record/associations/preloader/through_association.rb +48 -28
  23. data/lib/active_record/attribute_methods.rb +3 -53
  24. data/lib/active_record/attribute_methods/before_type_cast.rb +4 -1
  25. data/lib/active_record/attribute_methods/dirty.rb +47 -14
  26. data/lib/active_record/attribute_methods/primary_key.rb +7 -15
  27. data/lib/active_record/attribute_methods/query.rb +2 -3
  28. data/lib/active_record/attribute_methods/read.rb +3 -9
  29. data/lib/active_record/attribute_methods/write.rb +6 -12
  30. data/lib/active_record/attributes.rb +13 -0
  31. data/lib/active_record/autosave_association.rb +21 -7
  32. data/lib/active_record/base.rb +0 -1
  33. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +109 -11
  34. data/lib/active_record/connection_adapters/abstract/database_limits.rb +8 -4
  35. data/lib/active_record/connection_adapters/abstract/database_statements.rb +88 -61
  36. data/lib/active_record/connection_adapters/abstract/query_cache.rb +6 -4
  37. data/lib/active_record/connection_adapters/abstract/quoting.rb +63 -6
  38. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +4 -7
  39. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +1 -1
  40. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +79 -22
  41. data/lib/active_record/connection_adapters/abstract/transaction.rb +12 -4
  42. data/lib/active_record/connection_adapters/abstract_adapter.rb +111 -33
  43. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +78 -73
  44. data/lib/active_record/connection_adapters/column.rb +17 -13
  45. data/lib/active_record/connection_adapters/connection_specification.rb +2 -2
  46. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +2 -2
  47. data/lib/active_record/connection_adapters/mysql/database_statements.rb +48 -8
  48. data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -7
  49. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +7 -5
  50. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +9 -6
  51. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +6 -10
  52. data/lib/active_record/connection_adapters/mysql2_adapter.rb +18 -5
  53. data/lib/active_record/connection_adapters/postgresql/column.rb +17 -30
  54. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +8 -2
  55. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
  56. data/lib/active_record/connection_adapters/postgresql/quoting.rb +39 -2
  57. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +34 -38
  58. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +23 -27
  59. data/lib/active_record/connection_adapters/postgresql_adapter.rb +67 -26
  60. data/lib/active_record/connection_adapters/schema_cache.rb +32 -14
  61. data/lib/active_record/connection_adapters/sql_type_metadata.rb +11 -8
  62. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +120 -0
  63. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +38 -2
  64. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +2 -2
  65. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +66 -114
  66. data/lib/active_record/connection_handling.rb +31 -13
  67. data/lib/active_record/core.rb +23 -24
  68. data/lib/active_record/database_configurations.rb +73 -44
  69. data/lib/active_record/database_configurations/hash_config.rb +11 -11
  70. data/lib/active_record/database_configurations/url_config.rb +12 -12
  71. data/lib/active_record/dynamic_matchers.rb +1 -1
  72. data/lib/active_record/enum.rb +15 -0
  73. data/lib/active_record/errors.rb +1 -1
  74. data/lib/active_record/fixtures.rb +11 -6
  75. data/lib/active_record/gem_version.rb +2 -2
  76. data/lib/active_record/insert_all.rb +179 -0
  77. data/lib/active_record/integration.rb +13 -1
  78. data/lib/active_record/internal_metadata.rb +5 -1
  79. data/lib/active_record/locking/optimistic.rb +3 -4
  80. data/lib/active_record/log_subscriber.rb +1 -1
  81. data/lib/active_record/middleware/database_selector.rb +3 -3
  82. data/lib/active_record/middleware/database_selector/resolver.rb +4 -6
  83. data/lib/active_record/migration.rb +62 -44
  84. data/lib/active_record/migration/command_recorder.rb +28 -14
  85. data/lib/active_record/migration/compatibility.rb +10 -0
  86. data/lib/active_record/model_schema.rb +3 -0
  87. data/lib/active_record/persistence.rb +206 -13
  88. data/lib/active_record/querying.rb +17 -12
  89. data/lib/active_record/railtie.rb +0 -1
  90. data/lib/active_record/railties/databases.rake +127 -25
  91. data/lib/active_record/reflection.rb +3 -3
  92. data/lib/active_record/relation.rb +99 -20
  93. data/lib/active_record/relation/calculations.rb +38 -40
  94. data/lib/active_record/relation/delegation.rb +22 -30
  95. data/lib/active_record/relation/finder_methods.rb +17 -12
  96. data/lib/active_record/relation/merger.rb +11 -16
  97. data/lib/active_record/relation/query_methods.rb +228 -76
  98. data/lib/active_record/relation/where_clause.rb +9 -5
  99. data/lib/active_record/sanitization.rb +33 -4
  100. data/lib/active_record/schema.rb +1 -1
  101. data/lib/active_record/schema_dumper.rb +10 -1
  102. data/lib/active_record/schema_migration.rb +1 -1
  103. data/lib/active_record/scoping/default.rb +6 -7
  104. data/lib/active_record/scoping/named.rb +3 -2
  105. data/lib/active_record/statement_cache.rb +2 -2
  106. data/lib/active_record/store.rb +48 -0
  107. data/lib/active_record/table_metadata.rb +9 -13
  108. data/lib/active_record/tasks/database_tasks.rb +109 -6
  109. data/lib/active_record/tasks/mysql_database_tasks.rb +3 -1
  110. data/lib/active_record/test_databases.rb +1 -16
  111. data/lib/active_record/test_fixtures.rb +1 -0
  112. data/lib/active_record/timestamp.rb +26 -16
  113. data/lib/active_record/touch_later.rb +4 -2
  114. data/lib/active_record/transactions.rb +56 -46
  115. data/lib/active_record/type_caster/connection.rb +16 -10
  116. data/lib/active_record/validations.rb +1 -0
  117. data/lib/active_record/validations/uniqueness.rb +3 -5
  118. data/lib/arel.rb +12 -5
  119. data/lib/arel/insert_manager.rb +3 -3
  120. data/lib/arel/nodes.rb +2 -1
  121. data/lib/arel/nodes/comment.rb +29 -0
  122. data/lib/arel/nodes/select_core.rb +16 -12
  123. data/lib/arel/nodes/unary.rb +1 -0
  124. data/lib/arel/nodes/values_list.rb +2 -17
  125. data/lib/arel/select_manager.rb +10 -10
  126. data/lib/arel/visitors/depth_first.rb +7 -2
  127. data/lib/arel/visitors/dot.rb +7 -2
  128. data/lib/arel/visitors/ibm_db.rb +13 -0
  129. data/lib/arel/visitors/informix.rb +6 -0
  130. data/lib/arel/visitors/mssql.rb +15 -1
  131. data/lib/arel/visitors/oracle12.rb +4 -5
  132. data/lib/arel/visitors/postgresql.rb +4 -10
  133. data/lib/arel/visitors/to_sql.rb +107 -131
  134. data/lib/arel/visitors/visitor.rb +9 -5
  135. data/lib/rails/generators/active_record/migration/migration_generator.rb +1 -1
  136. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +1 -1
  137. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +4 -2
  138. data/lib/rails/generators/active_record/model/model_generator.rb +1 -1
  139. data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
  140. metadata +16 -12
  141. data/lib/active_record/collection_cache_key.rb +0 -53
  142. 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, :table_name, :default_function, :collation, :comment
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, table_name = nil, default_function = nil, collation = nil, comment: nil, **)
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
- attributes_for_hash == other.attributes_for_hash
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
- attributes_for_hash.hash
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.config[:adapter]} adapter"
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
- resolve_connection config_or_env
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
- discard_remaining_results
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(:begin, :commit, :explain, :select, :set, :show, :release, :savepoint, :rollback) # :nodoc:
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
- execute_and_free(sql, name) { @connection.affected_rows }
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
- Arel.sql("DEFAULT") unless column.auto_increment?
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
- @quoted_column_names[name] ||= "`#{super.gsub('`', '``')}`"
8
+ self.class.quoted_column_names[name] ||= "`#{super.gsub('`', '``')}`"
9
9
  end
10
10
 
11
11
  def quote_table_name(name)
12
- @quoted_table_names[name] ||= super.gsub(".", "`.`").freeze
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 _type_cast(value)
36
- case value
37
- when Date, Time then value
38
- else super
39
- end
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 && table_name = column.table_name
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.version < "10.2.5"
68
- create_table_info = @connection.send(:create_table_info, column.table_name)
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, column.table_name)
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
- version >= "10.2.2"
133
+ database_version >= "10.2.2"
130
134
  else
131
- version >= "5.7.9"
135
+ database_version >= "5.7.9"
132
136
  end
133
137
  end
134
138
 
@@ -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 ActiveRecordError, "No #{type} type has byte size #{limit}"
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 ActiveRecordError, "No integer type has byte size #{limit}. Use a decimal with scale 0 instead."
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?(MySQL::TypeMetadata) &&
19
- attributes_for_hash == other.attributes_for_hash
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
- attributes_for_hash.hash
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.message.include?("Unknown database")
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
- super
41
- @prepared_statements = false unless config.key?(:prepared_statements)
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? && version >= "5.7.8"
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
- @full_version ||= @connection.server_info[:version]
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