activerecord 5.1.7 → 5.2.0.beta1

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 (259) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +221 -900
  3. data/README.rdoc +3 -3
  4. data/examples/performance.rb +2 -0
  5. data/examples/simple.rb +2 -0
  6. data/lib/active_record.rb +10 -3
  7. data/lib/active_record/aggregations.rb +2 -0
  8. data/lib/active_record/association_relation.rb +2 -0
  9. data/lib/active_record/associations.rb +13 -42
  10. data/lib/active_record/associations/alias_tracker.rb +17 -17
  11. data/lib/active_record/associations/association.rb +11 -22
  12. data/lib/active_record/associations/association_scope.rb +32 -44
  13. data/lib/active_record/associations/belongs_to_association.rb +6 -4
  14. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +3 -1
  15. data/lib/active_record/associations/builder/association.rb +2 -5
  16. data/lib/active_record/associations/builder/belongs_to.rb +7 -12
  17. data/lib/active_record/associations/builder/collection_association.rb +1 -1
  18. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -1
  19. data/lib/active_record/associations/builder/has_many.rb +2 -0
  20. data/lib/active_record/associations/builder/has_one.rb +2 -0
  21. data/lib/active_record/associations/builder/singular_association.rb +2 -0
  22. data/lib/active_record/associations/collection_association.rb +41 -33
  23. data/lib/active_record/associations/collection_proxy.rb +11 -14
  24. data/lib/active_record/associations/foreign_association.rb +2 -0
  25. data/lib/active_record/associations/has_many_association.rb +4 -2
  26. data/lib/active_record/associations/has_many_through_association.rb +4 -2
  27. data/lib/active_record/associations/has_one_association.rb +3 -1
  28. data/lib/active_record/associations/has_one_through_association.rb +3 -1
  29. data/lib/active_record/associations/join_dependency.rb +22 -40
  30. data/lib/active_record/associations/join_dependency/join_association.rb +17 -56
  31. data/lib/active_record/associations/join_dependency/join_base.rb +9 -8
  32. data/lib/active_record/associations/join_dependency/join_part.rb +2 -9
  33. data/lib/active_record/associations/preloader.rb +17 -37
  34. data/lib/active_record/associations/preloader/association.rb +42 -58
  35. data/lib/active_record/associations/preloader/through_association.rb +71 -79
  36. data/lib/active_record/associations/singular_association.rb +14 -10
  37. data/lib/active_record/associations/through_association.rb +3 -1
  38. data/lib/active_record/attribute_assignment.rb +2 -0
  39. data/lib/active_record/attribute_decorators.rb +3 -2
  40. data/lib/active_record/attribute_methods.rb +47 -7
  41. data/lib/active_record/attribute_methods/before_type_cast.rb +2 -0
  42. data/lib/active_record/attribute_methods/dirty.rb +25 -214
  43. data/lib/active_record/attribute_methods/primary_key.rb +7 -6
  44. data/lib/active_record/attribute_methods/query.rb +2 -0
  45. data/lib/active_record/attribute_methods/read.rb +8 -2
  46. data/lib/active_record/attribute_methods/serialization.rb +23 -0
  47. data/lib/active_record/attribute_methods/time_zone_conversion.rb +6 -8
  48. data/lib/active_record/attribute_methods/write.rb +21 -9
  49. data/lib/active_record/attributes.rb +7 -6
  50. data/lib/active_record/autosave_association.rb +5 -11
  51. data/lib/active_record/base.rb +2 -0
  52. data/lib/active_record/callbacks.rb +6 -8
  53. data/lib/active_record/coders/json.rb +2 -0
  54. data/lib/active_record/coders/yaml_column.rb +2 -0
  55. data/lib/active_record/collection_cache_key.rb +10 -5
  56. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +110 -35
  57. data/lib/active_record/connection_adapters/abstract/database_limits.rb +2 -0
  58. data/lib/active_record/connection_adapters/abstract/database_statements.rb +120 -28
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +7 -2
  60. data/lib/active_record/connection_adapters/abstract/quoting.rb +14 -33
  61. data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
  62. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +13 -5
  63. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +40 -2
  64. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +31 -53
  65. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +103 -63
  66. data/lib/active_record/connection_adapters/abstract/transaction.rb +45 -9
  67. data/lib/active_record/connection_adapters/abstract_adapter.rb +62 -90
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +75 -138
  69. data/lib/active_record/connection_adapters/column.rb +3 -1
  70. data/lib/active_record/connection_adapters/connection_specification.rb +17 -3
  71. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +2 -0
  72. data/lib/active_record/connection_adapters/mysql/column.rb +2 -0
  73. data/lib/active_record/connection_adapters/mysql/database_statements.rb +3 -1
  74. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +2 -0
  75. data/lib/active_record/connection_adapters/mysql/quoting.rb +9 -10
  76. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +5 -3
  77. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +7 -6
  78. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +30 -30
  79. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +91 -1
  80. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +2 -0
  81. data/lib/active_record/connection_adapters/mysql2_adapter.rb +8 -2
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +2 -0
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +6 -0
  84. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +2 -0
  85. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -1
  86. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +3 -11
  87. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +2 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
  90. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +2 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -0
  92. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  93. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +2 -0
  94. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +2 -0
  95. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -1
  97. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -1
  99. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +2 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -0
  101. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +3 -5
  102. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +2 -0
  103. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +4 -2
  104. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +3 -1
  105. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
  106. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
  107. data/lib/active_record/connection_adapters/postgresql/quoting.rb +10 -0
  108. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
  109. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +2 -0
  110. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +11 -7
  111. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +20 -13
  112. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +79 -65
  113. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +2 -0
  114. data/lib/active_record/connection_adapters/postgresql/utils.rb +2 -0
  115. data/lib/active_record/connection_adapters/postgresql_adapter.rb +47 -82
  116. data/lib/active_record/connection_adapters/schema_cache.rb +2 -0
  117. data/lib/active_record/connection_adapters/sql_type_metadata.rb +2 -0
  118. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +2 -0
  119. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +19 -2
  120. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +2 -0
  121. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +6 -15
  122. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +3 -2
  123. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +71 -1
  124. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +34 -89
  125. data/lib/active_record/connection_adapters/statement_pool.rb +2 -0
  126. data/lib/active_record/connection_handling.rb +4 -2
  127. data/lib/active_record/core.rb +27 -57
  128. data/lib/active_record/counter_cache.rb +15 -12
  129. data/lib/active_record/define_callbacks.rb +5 -3
  130. data/lib/active_record/dynamic_matchers.rb +9 -9
  131. data/lib/active_record/enum.rb +15 -13
  132. data/lib/active_record/errors.rb +54 -21
  133. data/lib/active_record/explain.rb +3 -1
  134. data/lib/active_record/explain_registry.rb +2 -0
  135. data/lib/active_record/explain_subscriber.rb +2 -0
  136. data/lib/active_record/fixture_set/file.rb +2 -0
  137. data/lib/active_record/fixtures.rb +40 -24
  138. data/lib/active_record/gem_version.rb +5 -3
  139. data/lib/active_record/inheritance.rb +6 -5
  140. data/lib/active_record/integration.rb +58 -19
  141. data/lib/active_record/internal_metadata.rb +2 -0
  142. data/lib/active_record/legacy_yaml_adapter.rb +3 -1
  143. data/lib/active_record/locking/optimistic.rb +31 -20
  144. data/lib/active_record/locking/pessimistic.rb +10 -7
  145. data/lib/active_record/log_subscriber.rb +2 -0
  146. data/lib/active_record/migration.rb +47 -21
  147. data/lib/active_record/migration/command_recorder.rb +11 -9
  148. data/lib/active_record/migration/compatibility.rb +20 -2
  149. data/lib/active_record/migration/join_table.rb +2 -0
  150. data/lib/active_record/model_schema.rb +29 -38
  151. data/lib/active_record/nested_attributes.rb +18 -6
  152. data/lib/active_record/no_touching.rb +3 -1
  153. data/lib/active_record/null_relation.rb +2 -0
  154. data/lib/active_record/persistence.rb +184 -40
  155. data/lib/active_record/query_cache.rb +17 -12
  156. data/lib/active_record/querying.rb +3 -1
  157. data/lib/active_record/railtie.rb +54 -1
  158. data/lib/active_record/railties/console_sandbox.rb +2 -0
  159. data/lib/active_record/railties/controller_runtime.rb +2 -0
  160. data/lib/active_record/railties/databases.rake +41 -28
  161. data/lib/active_record/readonly_attributes.rb +3 -2
  162. data/lib/active_record/reflection.rb +100 -182
  163. data/lib/active_record/relation.rb +61 -193
  164. data/lib/active_record/relation/batches.rb +20 -5
  165. data/lib/active_record/relation/batches/batch_enumerator.rb +2 -0
  166. data/lib/active_record/relation/calculations.rb +40 -23
  167. data/lib/active_record/relation/delegation.rb +10 -27
  168. data/lib/active_record/relation/finder_methods.rb +53 -49
  169. data/lib/active_record/relation/from_clause.rb +2 -8
  170. data/lib/active_record/relation/merger.rb +22 -19
  171. data/lib/active_record/relation/predicate_builder.rb +42 -79
  172. data/lib/active_record/relation/predicate_builder/array_handler.rb +10 -7
  173. data/lib/active_record/relation/predicate_builder/association_query_value.rb +46 -0
  174. data/lib/active_record/relation/predicate_builder/base_handler.rb +2 -2
  175. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +12 -1
  176. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +54 -0
  177. data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -6
  178. data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
  179. data/lib/active_record/relation/query_attribute.rb +9 -2
  180. data/lib/active_record/relation/query_methods.rb +80 -69
  181. data/lib/active_record/relation/record_fetch_warning.rb +2 -0
  182. data/lib/active_record/relation/spawn_methods.rb +2 -0
  183. data/lib/active_record/relation/where_clause.rb +50 -67
  184. data/lib/active_record/relation/where_clause_factory.rb +4 -46
  185. data/lib/active_record/result.rb +2 -0
  186. data/lib/active_record/runtime_registry.rb +2 -0
  187. data/lib/active_record/sanitization.rb +15 -9
  188. data/lib/active_record/schema.rb +3 -1
  189. data/lib/active_record/schema_dumper.rb +24 -23
  190. data/lib/active_record/schema_migration.rb +2 -0
  191. data/lib/active_record/scoping.rb +9 -8
  192. data/lib/active_record/scoping/default.rb +6 -7
  193. data/lib/active_record/scoping/named.rb +15 -7
  194. data/lib/active_record/secure_token.rb +2 -0
  195. data/lib/active_record/serialization.rb +2 -0
  196. data/lib/active_record/statement_cache.rb +22 -12
  197. data/lib/active_record/store.rb +2 -0
  198. data/lib/active_record/suppressor.rb +2 -0
  199. data/lib/active_record/table_metadata.rb +3 -1
  200. data/lib/active_record/tasks/database_tasks.rb +23 -12
  201. data/lib/active_record/tasks/mysql_database_tasks.rb +9 -48
  202. data/lib/active_record/tasks/postgresql_database_tasks.rb +10 -2
  203. data/lib/active_record/tasks/sqlite_database_tasks.rb +25 -3
  204. data/lib/active_record/timestamp.rb +5 -12
  205. data/lib/active_record/touch_later.rb +2 -0
  206. data/lib/active_record/transactions.rb +9 -7
  207. data/lib/active_record/translation.rb +2 -0
  208. data/lib/active_record/type.rb +4 -1
  209. data/lib/active_record/type/adapter_specific_registry.rb +2 -0
  210. data/lib/active_record/type/date.rb +2 -0
  211. data/lib/active_record/type/date_time.rb +2 -0
  212. data/lib/active_record/type/decimal_without_scale.rb +2 -0
  213. data/lib/active_record/type/hash_lookup_type_map.rb +2 -0
  214. data/lib/active_record/type/internal/timezone.rb +2 -0
  215. data/lib/active_record/type/json.rb +30 -0
  216. data/lib/active_record/type/serialized.rb +2 -4
  217. data/lib/active_record/type/text.rb +2 -0
  218. data/lib/active_record/type/time.rb +2 -0
  219. data/lib/active_record/type/type_map.rb +2 -0
  220. data/lib/active_record/type/unsigned_integer.rb +2 -0
  221. data/lib/active_record/type_caster.rb +2 -0
  222. data/lib/active_record/type_caster/connection.rb +2 -0
  223. data/lib/active_record/type_caster/map.rb +2 -0
  224. data/lib/active_record/validations.rb +2 -0
  225. data/lib/active_record/validations/absence.rb +2 -0
  226. data/lib/active_record/validations/associated.rb +2 -0
  227. data/lib/active_record/validations/length.rb +2 -0
  228. data/lib/active_record/validations/presence.rb +2 -0
  229. data/lib/active_record/validations/uniqueness.rb +36 -6
  230. data/lib/active_record/version.rb +2 -0
  231. data/lib/rails/generators/active_record.rb +3 -1
  232. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
  233. data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
  234. data/lib/rails/generators/active_record/migration.rb +2 -0
  235. data/lib/rails/generators/active_record/migration/migration_generator.rb +3 -1
  236. data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +0 -0
  237. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +0 -0
  238. data/lib/rails/generators/active_record/model/model_generator.rb +2 -23
  239. data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +0 -0
  240. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  241. metadata +25 -38
  242. data/lib/active_record/associations/preloader/belongs_to.rb +0 -15
  243. data/lib/active_record/associations/preloader/collection_association.rb +0 -17
  244. data/lib/active_record/associations/preloader/has_many.rb +0 -15
  245. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  246. data/lib/active_record/associations/preloader/has_one.rb +0 -15
  247. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  248. data/lib/active_record/associations/preloader/singular_association.rb +0 -18
  249. data/lib/active_record/attribute.rb +0 -240
  250. data/lib/active_record/attribute/user_provided_default.rb +0 -30
  251. data/lib/active_record/attribute_mutation_tracker.rb +0 -122
  252. data/lib/active_record/attribute_set.rb +0 -113
  253. data/lib/active_record/attribute_set/builder.rb +0 -126
  254. data/lib/active_record/attribute_set/yaml_encoder.rb +0 -41
  255. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -10
  256. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  257. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
  258. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -59
  259. data/lib/active_record/type/internal/abstract_json.rb +0 -37
@@ -1,10 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  class TransactionState
4
- VALID_STATES = Set.new([:committed, :rolledback, nil])
5
-
6
6
  def initialize(state = nil)
7
7
  @state = state
8
+ @children = []
9
+ end
10
+
11
+ def add_child(state)
12
+ @children << state
8
13
  end
9
14
 
10
15
  def finalized?
@@ -19,15 +24,43 @@ module ActiveRecord
19
24
  @state == :rolledback
20
25
  end
21
26
 
27
+ def fully_completed?
28
+ completed?
29
+ end
30
+
22
31
  def completed?
23
32
  committed? || rolledback?
24
33
  end
25
34
 
26
35
  def set_state(state)
27
- unless VALID_STATES.include?(state)
36
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
37
+ The set_state method is deprecated and will be removed in
38
+ Rails 6.0. Please use rollback! or commit! to set transaction
39
+ state directly.
40
+ MSG
41
+ case state
42
+ when :rolledback
43
+ rollback!
44
+ when :committed
45
+ commit!
46
+ when nil
47
+ nullify!
48
+ else
28
49
  raise ArgumentError, "Invalid transaction state: #{state}"
29
50
  end
30
- @state = state
51
+ end
52
+
53
+ def rollback!
54
+ @children.each { |c| c.rollback! }
55
+ @state = :rolledback
56
+ end
57
+
58
+ def commit!
59
+ @state = :committed
60
+ end
61
+
62
+ def nullify!
63
+ @state = nil
31
64
  end
32
65
  end
33
66
 
@@ -57,7 +90,7 @@ module ActiveRecord
57
90
  end
58
91
 
59
92
  def rollback
60
- @state.set_state(:rolledback)
93
+ @state.rollback!
61
94
  end
62
95
 
63
96
  def rollback_records
@@ -72,7 +105,7 @@ module ActiveRecord
72
105
  end
73
106
 
74
107
  def commit
75
- @state.set_state(:committed)
108
+ @state.commit!
76
109
  end
77
110
 
78
111
  def before_commit_records
@@ -100,8 +133,11 @@ module ActiveRecord
100
133
  end
101
134
 
102
135
  class SavepointTransaction < Transaction
103
- def initialize(connection, savepoint_name, options, *args)
136
+ def initialize(connection, savepoint_name, parent_transaction, options, *args)
104
137
  super(connection, options, *args)
138
+
139
+ parent_transaction.state.add_child(@state)
140
+
105
141
  if options[:isolation]
106
142
  raise ActiveRecord::TransactionIsolationError, "cannot set transaction isolation in a nested transaction"
107
143
  end
@@ -155,7 +191,7 @@ module ActiveRecord
155
191
  if @stack.empty?
156
192
  RealTransaction.new(@connection, options, run_commit_callbacks: run_commit_callbacks)
157
193
  else
158
- SavepointTransaction.new(@connection, "active_record_#{@stack.size}", options,
194
+ SavepointTransaction.new(@connection, "active_record_#{@stack.size}", @stack.last, options,
159
195
  run_commit_callbacks: run_commit_callbacks)
160
196
  end
161
197
 
@@ -204,7 +240,7 @@ module ActiveRecord
204
240
  rollback_transaction if transaction
205
241
  else
206
242
  begin
207
- commit_transaction
243
+ commit_transaction if transaction
208
244
  rescue Exception
209
245
  rollback_transaction(transaction) unless transaction.state.completed?
210
246
  raise
@@ -1,4 +1,5 @@
1
- require "active_record/type"
1
+ # frozen_string_literal: true
2
+
2
3
  require "active_record/connection_adapters/determine_if_preparable_visitor"
3
4
  require "active_record/connection_adapters/schema_cache"
4
5
  require "active_record/connection_adapters/sql_type_metadata"
@@ -6,7 +7,9 @@ require "active_record/connection_adapters/abstract/schema_dumper"
6
7
  require "active_record/connection_adapters/abstract/schema_creation"
7
8
  require "active_support/concurrency/load_interlock_aware_monitor"
8
9
  require "arel/collectors/bind"
10
+ require "arel/collectors/composite"
9
11
  require "arel/collectors/sql_string"
12
+ require "arel/collectors/substitute_binds"
10
13
 
11
14
  module ActiveRecord
12
15
  module ConnectionAdapters # :nodoc:
@@ -69,7 +72,6 @@ module ActiveRecord
69
72
  include Quoting, DatabaseStatements, SchemaStatements
70
73
  include DatabaseLimits
71
74
  include QueryCache
72
- include ColumnDumper
73
75
  include Savepoints
74
76
 
75
77
  SIMPLE_INT = /\A\d+\z/
@@ -103,6 +105,7 @@ module ActiveRecord
103
105
  @logger = logger
104
106
  @config = config
105
107
  @pool = nil
108
+ @idle_since = Concurrent.monotonic_time
106
109
  @schema_cache = SchemaCache.new self
107
110
  @quoted_column_names, @quoted_table_names = {}, {}
108
111
  @visitor = arel_visitor
@@ -128,51 +131,14 @@ module ActiveRecord
128
131
  end
129
132
  end
130
133
 
131
- class BindCollector < Arel::Collectors::Bind
132
- def compile(bvs, conn)
133
- casted_binds = bvs.map(&:value_for_database)
134
- super(casted_binds.map { |value| conn.quote(value) })
135
- end
136
- end
137
-
138
- class SQLString < Arel::Collectors::SQLString
139
- def compile(bvs, conn)
140
- super(bvs)
141
- end
142
- end
143
-
144
- def collector
145
- if prepared_statements
146
- SQLString.new
147
- else
148
- BindCollector.new
149
- end
150
- end
151
-
152
- def arel_visitor # :nodoc:
153
- Arel::Visitors::ToSql.new(self)
154
- end
155
-
156
134
  def valid_type?(type) # :nodoc:
157
135
  !native_database_types[type].nil?
158
136
  end
159
137
 
160
- def schema_creation
161
- SchemaCreation.new self
162
- end
163
-
164
- # Returns an array of +Column+ objects for the table specified by +table_name+.
165
- def columns(table_name) # :nodoc:
166
- table_name = table_name.to_s
167
- column_definitions(table_name).map do |field|
168
- new_column_from_field(table_name, field)
169
- end
170
- end
171
-
172
138
  # this method must only be called while holding connection pool's mutex
173
139
  def lease
174
140
  if in_use?
175
- msg = "Cannot lease connection, "
141
+ msg = "Cannot lease connection, ".dup
176
142
  if @owner == Thread.current
177
143
  msg << "it is already leased by the current thread."
178
144
  else
@@ -199,6 +165,7 @@ module ActiveRecord
199
165
  "Current thread: #{Thread.current}."
200
166
  end
201
167
 
168
+ @idle_since = Concurrent.monotonic_time
202
169
  @owner = nil
203
170
  else
204
171
  raise ActiveRecordError, "Cannot expire connection, it is not currently leased."
@@ -218,6 +185,12 @@ module ActiveRecord
218
185
  end
219
186
  end
220
187
 
188
+ # Seconds since this connection was returned to the pool
189
+ def seconds_idle # :nodoc:
190
+ return 0 if in_use?
191
+ Concurrent.monotonic_time - @idle_since
192
+ end
193
+
221
194
  def unprepared_statement
222
195
  old_prepared_statements, @prepared_statements = @prepared_statements, false
223
196
  yield
@@ -231,16 +204,6 @@ module ActiveRecord
231
204
  self.class::ADAPTER_NAME
232
205
  end
233
206
 
234
- def supports_migrations? # :nodoc:
235
- true
236
- end
237
- deprecate :supports_migrations?
238
-
239
- def supports_primary_key? # :nodoc:
240
- true
241
- end
242
- deprecate :supports_primary_key?
243
-
244
207
  # Does this adapter support DDL rollbacks in transactions? That is, would
245
208
  # CREATE TABLE or ALTER TABLE get rolled back by a transaction?
246
209
  def supports_ddl_transactions?
@@ -412,6 +375,19 @@ module ActiveRecord
412
375
  reset_transaction
413
376
  end
414
377
 
378
+ # Immediately forget this connection ever existed. Unlike disconnect!,
379
+ # this will not communicate with the server.
380
+ #
381
+ # After calling this method, the behavior of all other methods becomes
382
+ # undefined. This is called internally just before a forked process gets
383
+ # rid of a connection that belonged to its parent.
384
+ def discard!
385
+ # This should be overridden by concrete adapters.
386
+ #
387
+ # Prevent @connection's finalizer from touching the socket, or
388
+ # otherwise communicating with its server, when it is collected.
389
+ end
390
+
415
391
  # Reset the state of this connection, directing the DBMS to clear
416
392
  # transactions and other connection-related server-side state. Usually a
417
393
  # database-dependent operation.
@@ -437,10 +413,7 @@ module ActiveRecord
437
413
  # Checks whether the connection to the database is still active (i.e. not stale).
438
414
  # This is done under the hood by calling #active?. If the connection
439
415
  # is no longer active, then this method will reconnect to the database.
440
- def verify!(*ignored)
441
- if ignored.size > 0
442
- ActiveSupport::Deprecation.warn("Passing arguments to #verify method of the connection has no effect and has been deprecated. Please remove all arguments from the #verify method call.")
443
- end
416
+ def verify!
444
417
  reconnect! unless active?
445
418
  end
446
419
 
@@ -476,40 +449,12 @@ module ActiveRecord
476
449
  pool.checkin self
477
450
  end
478
451
 
479
- def type_map # :nodoc:
480
- @type_map ||= Type::TypeMap.new.tap do |mapping|
481
- initialize_type_map(mapping)
482
- end
483
- end
484
-
485
- def new_column(name, default, sql_type_metadata, null, table_name, default_function = nil, collation = nil) # :nodoc:
486
- Column.new(name, default, sql_type_metadata, null, table_name, default_function, collation)
487
- end
488
-
489
- def lookup_cast_type(sql_type) # :nodoc:
490
- type_map.lookup(sql_type)
452
+ def column_name_for_operation(operation, node) # :nodoc:
453
+ column_name_from_arel_node(node)
491
454
  end
492
455
 
493
- def column_name_for_operation(operation, node) # :nodoc:
494
- visitor.accept(node, collector).value
495
- end
496
-
497
- def combine_bind_parameters(
498
- from_clause: [],
499
- join_clause: [],
500
- where_clause: [],
501
- having_clause: [],
502
- limit: nil,
503
- offset: nil
504
- ) # :nodoc:
505
- result = from_clause + join_clause + where_clause + having_clause
506
- if limit
507
- result << limit
508
- end
509
- if offset
510
- result << offset
511
- end
512
- result
456
+ def column_name_from_arel_node(node) # :nodoc:
457
+ visitor.accept(node, Arel::Collectors::SQLString.new).value
513
458
  end
514
459
 
515
460
  def default_index_type?(index) # :nodoc:
@@ -517,8 +462,13 @@ module ActiveRecord
517
462
  end
518
463
 
519
464
  private
465
+ def type_map
466
+ @type_map ||= Type::TypeMap.new.tap do |mapping|
467
+ initialize_type_map(mapping)
468
+ end
469
+ end
520
470
 
521
- def initialize_type_map(m)
471
+ def initialize_type_map(m = type_map)
522
472
  register_class_with_limit m, %r(boolean)i, Type::Boolean
523
473
  register_class_with_limit m, %r(char)i, Type::String
524
474
  register_class_with_limit m, %r(binary)i, Type::Binary
@@ -536,6 +486,8 @@ module ActiveRecord
536
486
  m.alias_type %r(number)i, "decimal"
537
487
  m.alias_type %r(double)i, "float"
538
488
 
489
+ m.register_type %r(^json)i, Type::Json.new
490
+
539
491
  m.register_type(%r(decimal)i) do |sql_type|
540
492
  scale = extract_scale(sql_type)
541
493
  precision = extract_precision(sql_type)
@@ -551,7 +503,7 @@ module ActiveRecord
551
503
 
552
504
  def reload_type_map
553
505
  type_map.clear
554
- initialize_type_map(type_map)
506
+ initialize_type_map
555
507
  end
556
508
 
557
509
  def register_class_with_limit(mapping, key, klass)
@@ -609,12 +561,14 @@ module ActiveRecord
609
561
  type_casted_binds: type_casted_binds,
610
562
  statement_name: statement_name,
611
563
  connection_id: object_id) do
564
+ begin
612
565
  @lock.synchronize do
613
566
  yield
614
567
  end
568
+ rescue => e
569
+ raise translate_exception_class(e, sql)
615
570
  end
616
- rescue => e
617
- raise translate_exception_class(e, sql)
571
+ end
618
572
  end
619
573
 
620
574
  def translate_exception(exception, message)
@@ -636,6 +590,24 @@ module ActiveRecord
636
590
  columns(table_name).detect { |c| c.name == column_name } ||
637
591
  raise(ActiveRecordError, "No such column: #{table_name}.#{column_name}")
638
592
  end
593
+
594
+ def collector
595
+ if prepared_statements
596
+ Arel::Collectors::Composite.new(
597
+ Arel::Collectors::SQLString.new,
598
+ Arel::Collectors::Bind.new,
599
+ )
600
+ else
601
+ Arel::Collectors::SubstituteBinds.new(
602
+ self,
603
+ Arel::Collectors::SQLString.new,
604
+ )
605
+ end
606
+ end
607
+
608
+ def arel_visitor
609
+ Arel::Visitors::ToSql.new(self)
610
+ end
639
611
  end
640
612
  end
641
613
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_record/connection_adapters/abstract_adapter"
2
4
  require "active_record/connection_adapters/statement_pool"
3
5
  require "active_record/connection_adapters/mysql/column"
@@ -15,21 +17,8 @@ module ActiveRecord
15
17
  module ConnectionAdapters
16
18
  class AbstractMysqlAdapter < AbstractAdapter
17
19
  include MySQL::Quoting
18
- include MySQL::ColumnDumper
19
20
  include MySQL::SchemaStatements
20
21
 
21
- def update_table_definition(table_name, base) # :nodoc:
22
- MySQL::Table.new(table_name, base)
23
- end
24
-
25
- def schema_creation # :nodoc:
26
- MySQL::SchemaCreation.new(self)
27
- end
28
-
29
- def arel_visitor # :nodoc:
30
- Arel::Visitors::MySQL.new(self)
31
- end
32
-
33
22
  ##
34
23
  # :singleton-method:
35
24
  # By default, the Mysql2Adapter will consider all columns of type <tt>tinyint(1)</tt>
@@ -37,15 +26,14 @@ module ActiveRecord
37
26
  # to your application.rb file:
38
27
  #
39
28
  # ActiveRecord::ConnectionAdapters::Mysql2Adapter.emulate_booleans = false
40
- class_attribute :emulate_booleans
41
- self.emulate_booleans = true
29
+ class_attribute :emulate_booleans, default: true
42
30
 
43
31
  NATIVE_DATABASE_TYPES = {
44
32
  primary_key: "bigint auto_increment PRIMARY KEY",
45
33
  string: { name: "varchar", limit: 255 },
46
34
  text: { name: "text", limit: 65535 },
47
35
  integer: { name: "int", limit: 4 },
48
- float: { name: "float" },
36
+ float: { name: "float", limit: 24 },
49
37
  decimal: { name: "decimal" },
50
38
  datetime: { name: "datetime" },
51
39
  timestamp: { name: "timestamp" },
@@ -56,10 +44,7 @@ module ActiveRecord
56
44
  json: { name: "json" },
57
45
  }
58
46
 
59
- INDEX_TYPES = [:fulltext, :spatial]
60
- INDEX_USINGS = [:btree, :hash]
61
-
62
- class StatementPool < ConnectionAdapters::StatementPool
47
+ class StatementPool < ConnectionAdapters::StatementPool # :nodoc:
63
48
  private def dealloc(stmt)
64
49
  stmt[:stmt].close
65
50
  end
@@ -87,16 +72,8 @@ module ActiveRecord
87
72
  true
88
73
  end
89
74
 
90
- # Returns true, since this connection adapter supports prepared statement
91
- # caching.
92
- def supports_statement_cache?
93
- true
94
- end
95
-
96
- # Technically MySQL allows to create indexes with the sort order syntax
97
- # but at the moment (5.5) it doesn't yet implement them
98
75
  def supports_index_sort_order?
99
- true
76
+ !mariadb? && version >= "8.0.1"
100
77
  end
101
78
 
102
79
  def supports_transaction_isolation?
@@ -140,11 +117,11 @@ module ActiveRecord
140
117
  end
141
118
 
142
119
  def get_advisory_lock(lock_name, timeout = 0) # :nodoc:
143
- query_value("SELECT GET_LOCK(#{quote(lock_name.to_s)}, #{timeout})") == 1
120
+ query_value("SELECT GET_LOCK(#{quote(lock_name)}, #{timeout})") == 1
144
121
  end
145
122
 
146
123
  def release_advisory_lock(lock_name) # :nodoc:
147
- query_value("SELECT RELEASE_LOCK(#{quote(lock_name.to_s)})") == 1
124
+ query_value("SELECT RELEASE_LOCK(#{quote(lock_name)})") == 1
148
125
  end
149
126
 
150
127
  def native_database_types
@@ -152,7 +129,7 @@ module ActiveRecord
152
129
  end
153
130
 
154
131
  def index_algorithms
155
- { default: "ALGORITHM = DEFAULT", copy: "ALGORITHM = COPY", inplace: "ALGORITHM = INPLACE" }
132
+ { default: "ALGORITHM = DEFAULT".dup, copy: "ALGORITHM = COPY".dup, inplace: "ALGORITHM = INPLACE".dup }
156
133
  end
157
134
 
158
135
  # HELPER METHODS ===========================================
@@ -163,10 +140,6 @@ module ActiveRecord
163
140
  raise NotImplementedError
164
141
  end
165
142
 
166
- def new_column(*args) #:nodoc:
167
- MySQL::Column.new(*args)
168
- end
169
-
170
143
  # Must return the MySQL error number from the exception, if the exception has an
171
144
  # error number.
172
145
  def error_number(exception) # :nodoc:
@@ -308,50 +281,10 @@ module ActiveRecord
308
281
  execute "TRUNCATE TABLE #{quote_table_name(table_name)}", name
309
282
  end
310
283
 
311
- # Returns an array of indexes for the given table.
312
- def indexes(table_name, name = nil) #:nodoc:
313
- if name
314
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
315
- Passing name to #indexes is deprecated without replacement.
316
- MSG
317
- end
318
-
319
- indexes = []
320
- current_index = nil
321
- execute_and_free("SHOW KEYS FROM #{quote_table_name(table_name)}", "SCHEMA") do |result|
322
- each_hash(result) do |row|
323
- if current_index != row[:Key_name]
324
- next if row[:Key_name] == "PRIMARY" # skip the primary key
325
- current_index = row[:Key_name]
326
-
327
- mysql_index_type = row[:Index_type].downcase.to_sym
328
- index_type = INDEX_TYPES.include?(mysql_index_type) ? mysql_index_type : nil
329
- index_using = INDEX_USINGS.include?(mysql_index_type) ? mysql_index_type : nil
330
- indexes << IndexDefinition.new(row[:Table], row[:Key_name], row[:Non_unique].to_i == 0, [], {}, nil, nil, index_type, index_using, row[:Index_comment].presence)
331
- end
332
-
333
- indexes.last.columns << row[:Column_name]
334
- indexes.last.lengths.merge!(row[:Column_name] => row[:Sub_part].to_i) if row[:Sub_part]
335
- end
336
- end
337
-
338
- indexes
339
- end
340
-
341
- def new_column_from_field(table_name, field) # :nodoc:
342
- type_metadata = fetch_type_metadata(field[:Type], field[:Extra])
343
- if type_metadata.type == :datetime && /\ACURRENT_TIMESTAMP(?:\(\))?\z/i.match?(field[:Default])
344
- default, default_function = nil, "CURRENT_TIMESTAMP"
345
- else
346
- default, default_function = field[:Default], nil
347
- end
348
- new_column(field[:Field], default, type_metadata, field[:Null] == "YES", table_name, default_function, field[:Collation], comment: field[:Comment].presence)
349
- end
350
-
351
284
  def table_comment(table_name) # :nodoc:
352
285
  scope = quoted_scope(table_name)
353
286
 
354
- query_value(<<-SQL.strip_heredoc, "SCHEMA")
287
+ query_value(<<-SQL.strip_heredoc, "SCHEMA").presence
355
288
  SELECT table_comment
356
289
  FROM information_schema.tables
357
290
  WHERE table_schema = #{scope[:schema]}
@@ -378,6 +311,11 @@ module ActiveRecord
378
311
  execute("ALTER TABLE #{quote_table_name(table_name)} #{sqls}")
379
312
  end
380
313
 
314
+ def change_table_comment(table_name, comment) #:nodoc:
315
+ comment = "" if comment.nil?
316
+ execute("ALTER TABLE #{quote_table_name(table_name)} COMMENT #{quote(comment)}")
317
+ end
318
+
381
319
  # Renames a table.
382
320
  #
383
321
  # Example:
@@ -418,18 +356,19 @@ module ActiveRecord
418
356
 
419
357
  def change_column_default(table_name, column_name, default_or_changes) #:nodoc:
420
358
  default = extract_new_default_value(default_or_changes)
421
- column = column_for(table_name, column_name)
422
- change_column table_name, column_name, column.sql_type, default: default
359
+ change_column table_name, column_name, nil, default: default
423
360
  end
424
361
 
425
362
  def change_column_null(table_name, column_name, null, default = nil) #:nodoc:
426
- column = column_for(table_name, column_name)
427
-
428
363
  unless null || default.nil?
429
364
  execute("UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote(default)} WHERE #{quote_column_name(column_name)} IS NULL")
430
365
  end
431
366
 
432
- change_column table_name, column_name, column.sql_type, null: null
367
+ change_column table_name, column_name, nil, null: null
368
+ end
369
+
370
+ def change_column_comment(table_name, column_name, comment) #:nodoc:
371
+ change_column table_name, column_name, nil, comment: comment
433
372
  end
434
373
 
435
374
  def change_column(table_name, column_name, type, options = {}) #:nodoc:
@@ -443,7 +382,7 @@ module ActiveRecord
443
382
 
444
383
  def add_index(table_name, column_name, options = {}) #:nodoc:
445
384
  index_name, index_type, index_columns, _, index_algorithm, index_using, comment = add_index_options(table_name, column_name, options)
446
- sql = "CREATE #{index_type} INDEX #{quote_column_name(index_name)} #{index_using} ON #{quote_table_name(table_name)} (#{index_columns}) #{index_algorithm}"
385
+ sql = "CREATE #{index_type} INDEX #{quote_column_name(index_name)} #{index_using} ON #{quote_table_name(table_name)} (#{index_columns}) #{index_algorithm}".dup
447
386
  execute add_sql_comment!(sql, comment)
448
387
  end
449
388
 
@@ -464,13 +403,12 @@ module ActiveRecord
464
403
  fk.constraint_name AS 'name',
465
404
  rc.update_rule AS 'on_update',
466
405
  rc.delete_rule AS 'on_delete'
467
- FROM information_schema.referential_constraints rc
468
- JOIN information_schema.key_column_usage fk
406
+ FROM information_schema.key_column_usage fk
407
+ JOIN information_schema.referential_constraints rc
469
408
  USING (constraint_schema, constraint_name)
470
409
  WHERE fk.referenced_column_name IS NOT NULL
471
410
  AND fk.table_schema = #{scope[:schema]}
472
411
  AND fk.table_name = #{scope[:name]}
473
- AND rc.constraint_schema = #{scope[:schema]}
474
412
  AND rc.table_name = #{scope[:name]}
475
413
  SQL
476
414
 
@@ -529,7 +467,7 @@ module ActiveRecord
529
467
  super
530
468
  end
531
469
 
532
- sql << " unsigned" if unsigned && type != :primary_key
470
+ sql = "#{sql} unsigned" if unsigned && type != :primary_key
533
471
  sql
534
472
  end
535
473
 
@@ -591,9 +529,26 @@ module ActiveRecord
591
529
  index.using == :btree || super
592
530
  end
593
531
 
532
+ def insert_fixtures(*)
533
+ without_sql_mode("NO_AUTO_VALUE_ON_ZERO") { super }
534
+ end
535
+
594
536
  private
595
537
 
596
- def initialize_type_map(m)
538
+ def without_sql_mode(mode)
539
+ result = execute("SELECT @@SESSION.sql_mode")
540
+ current_mode = result.first[0]
541
+ return yield unless current_mode.include?(mode)
542
+
543
+ sql_mode = "REPLACE(@@sql_mode, '#{mode}', '')"
544
+ execute("SET @@SESSION.sql_mode = #{sql_mode}")
545
+ yield
546
+ ensure
547
+ sql_mode = "CONCAT(@@sql_mode, ',#{mode}')"
548
+ execute("SET @@SESSION.sql_mode = #{sql_mode}")
549
+ end
550
+
551
+ def initialize_type_map(m = type_map)
597
552
  super
598
553
 
599
554
  register_class_with_limit m, %r(char)i, MysqlString
@@ -608,7 +563,6 @@ module ActiveRecord
608
563
  m.register_type %r(longblob)i, Type::Binary.new(limit: 2**32 - 1)
609
564
  m.register_type %r(^float)i, Type::Float.new(limit: 24)
610
565
  m.register_type %r(^double)i, Type::Float.new(limit: 53)
611
- m.register_type %r(^json)i, MysqlJson.new
612
566
 
613
567
  register_integer_type m, %r(^bigint)i, limit: 8
614
568
  register_integer_type m, %r(^int)i, limit: 4
@@ -651,10 +605,6 @@ module ActiveRecord
651
605
  end
652
606
  end
653
607
 
654
- def fetch_type_metadata(sql_type, extra = "")
655
- MySQL::TypeMetadata.new(super(sql_type), extra: extra)
656
- end
657
-
658
608
  def add_index_length(quoted_columns, **options)
659
609
  if length = options[:length]
660
610
  case length
@@ -684,6 +634,9 @@ module ActiveRecord
684
634
  ER_LOCK_DEADLOCK = 1213
685
635
  ER_CANNOT_ADD_FOREIGN = 1215
686
636
  ER_CANNOT_CREATE_TABLE = 1005
637
+ ER_LOCK_WAIT_TIMEOUT = 1205
638
+ ER_QUERY_INTERRUPTED = 1317
639
+ ER_QUERY_TIMEOUT = 3024
687
640
 
688
641
  def translate_exception(exception, message)
689
642
  case error_number(exception)
@@ -707,6 +660,12 @@ module ActiveRecord
707
660
  NotNullViolation.new(message)
708
661
  when ER_LOCK_DEADLOCK
709
662
  Deadlocked.new(message)
663
+ when ER_LOCK_WAIT_TIMEOUT
664
+ LockWaitTimeout.new(message)
665
+ when ER_QUERY_TIMEOUT
666
+ StatementTimeout.new(message)
667
+ when ER_QUERY_INTERRUPTED
668
+ QueryCanceled.new(message)
710
669
  else
711
670
  super
712
671
  end
@@ -720,6 +679,7 @@ module ActiveRecord
720
679
 
721
680
  def change_column_sql(table_name, column_name, type, options = {})
722
681
  column = column_for(table_name, column_name)
682
+ type ||= column.sql_type
723
683
 
724
684
  unless options.key?(:default)
725
685
  options[:default] = column.default
@@ -768,7 +728,7 @@ module ActiveRecord
768
728
 
769
729
  def remove_index_sql(table_name, options = {})
770
730
  index_name = index_name_for_remove(table_name, options)
771
- "DROP INDEX #{index_name}"
731
+ "DROP INDEX #{quote_column_name(index_name)}"
772
732
  end
773
733
 
774
734
  def add_timestamps_sql(table_name, options = {})
@@ -782,16 +742,14 @@ module ActiveRecord
782
742
  # MySQL is too stupid to create a temporary table for use subquery, so we have
783
743
  # to give it some prompting in the form of a subsubquery. Ugh!
784
744
  def subquery_for(key, select)
785
- subsubselect = select.clone
786
- subsubselect.projections = [key]
745
+ subselect = select.clone
746
+ subselect.projections = [key]
787
747
 
788
748
  # Materialize subquery by adding distinct
789
749
  # to work with MySQL 5.7.6 which sets optimizer_switch='derived_merge=on'
790
- subsubselect.distinct unless select.limit || select.offset || select.orders.any?
750
+ subselect.distinct unless select.limit || select.offset || select.orders.any?
791
751
 
792
- subselect = Arel::SelectManager.new(select.engine)
793
- subselect.project Arel.sql(key.name)
794
- subselect.from subsubselect.as("__active_record_temp")
752
+ Arel::SelectManager.new(subselect.as("__active_record_temp")).project(Arel.sql(key.name))
795
753
  end
796
754
 
797
755
  def supports_rename_index?
@@ -812,7 +770,7 @@ module ActiveRecord
812
770
  defaults = [":default", :default].to_set
813
771
 
814
772
  # Make MySQL reject illegal values rather than truncating or blanking them, see
815
- # http://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sqlmode_strict_all_tables
773
+ # https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sqlmode_strict_all_tables
816
774
  # If the user has provided another value for sql_mode, don't replace it.
817
775
  if sql_mode = variables.delete("sql_mode")
818
776
  sql_mode = quote(sql_mode)
@@ -829,10 +787,10 @@ module ActiveRecord
829
787
  sql_mode_assignment = "@@SESSION.sql_mode = #{sql_mode}, " if sql_mode
830
788
 
831
789
  # NAMES does not have an equals sign, see
832
- # http://dev.mysql.com/doc/refman/5.7/en/set-statement.html#id944430
790
+ # https://dev.mysql.com/doc/refman/5.7/en/set-names.html
833
791
  # (trailing comma because variable_assignments will always have content)
834
792
  if @config[:encoding]
835
- encoding = "NAMES #{@config[:encoding]}"
793
+ encoding = "NAMES #{@config[:encoding]}".dup
836
794
  encoding << " COLLATE #{@config[:collation]}" if @config[:collation]
837
795
  encoding << ", "
838
796
  end
@@ -857,41 +815,24 @@ module ActiveRecord
857
815
  end
858
816
  end
859
817
 
860
- def extract_foreign_key_action(specifier) # :nodoc:
861
- case specifier
862
- when "CASCADE"; :cascade
863
- when "SET NULL"; :nullify
864
- end
865
- end
866
-
867
818
  def create_table_info(table_name) # :nodoc:
868
819
  exec_query("SHOW CREATE TABLE #{quote_table_name(table_name)}", "SCHEMA").first["Create Table"]
869
820
  end
870
821
 
871
- def create_table_definition(*args) # :nodoc:
872
- MySQL::TableDefinition.new(*args)
822
+ def arel_visitor
823
+ Arel::Visitors::MySQL.new(self)
873
824
  end
874
825
 
875
826
  def mismatched_foreign_key(message)
876
- match = %r/
877
- (?:CREATE|ALTER)\s+TABLE\s*(?:`?\w+`?\.)?`?(?<table>\w+)`?.+?
878
- FOREIGN\s+KEY\s*\(`?(?<foreign_key>\w+)`?\)\s*
879
- REFERENCES\s*(`?(?<target_table>\w+)`?)\s*\(`?(?<primary_key>\w+)`?\)
880
- /xmi.match(message)
881
-
882
- options = {
827
+ parts = message.scan(/`(\w+)`[ $)]/).flatten
828
+ MismatchedForeignKey.new(
829
+ self,
883
830
  message: message,
884
- }
885
-
886
- if match
887
- options[:table] = match[:table]
888
- options[:foreign_key] = match[:foreign_key]
889
- options[:target_table] = match[:target_table]
890
- options[:primary_key] = match[:primary_key]
891
- options[:primary_key_column] = column_for(match[:target_table], match[:primary_key])
892
- end
893
-
894
- MismatchedForeignKey.new(options)
831
+ table: parts[0],
832
+ foreign_key: parts[1],
833
+ target_table: parts[2],
834
+ primary_key: parts[3],
835
+ )
895
836
  end
896
837
 
897
838
  def integer_to_sql(limit) # :nodoc:
@@ -929,14 +870,11 @@ module ActiveRecord
929
870
  full_version.match(/^(?:5\.5\.5-)?(\d+\.\d+\.\d+)/)[1]
930
871
  end
931
872
 
932
- class MysqlJson < Type::Internal::AbstractJson # :nodoc:
933
- end
934
-
935
873
  class MysqlString < Type::String # :nodoc:
936
874
  def serialize(value)
937
875
  case value
938
- when true then MySQL::Quoting::QUOTED_TRUE
939
- when false then MySQL::Quoting::QUOTED_FALSE
876
+ when true then "1"
877
+ when false then "0"
940
878
  else super
941
879
  end
942
880
  end
@@ -945,14 +883,13 @@ module ActiveRecord
945
883
 
946
884
  def cast_value(value)
947
885
  case value
948
- when true then MySQL::Quoting::QUOTED_TRUE
949
- when false then MySQL::Quoting::QUOTED_FALSE
886
+ when true then "1"
887
+ when false then "0"
950
888
  else super
951
889
  end
952
890
  end
953
891
  end
954
892
 
955
- ActiveRecord::Type.register(:json, MysqlJson, adapter: :mysql2)
956
893
  ActiveRecord::Type.register(:string, MysqlString, adapter: :mysql2)
957
894
  ActiveRecord::Type.register(:unsigned_integer, Type::UnsignedInteger, adapter: :mysql2)
958
895
  end