activerecord 5.1.0 → 5.2.3

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 (261) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +596 -450
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +5 -5
  5. data/examples/performance.rb +2 -0
  6. data/examples/simple.rb +2 -0
  7. data/lib/active_record.rb +11 -4
  8. data/lib/active_record/aggregations.rb +6 -5
  9. data/lib/active_record/association_relation.rb +7 -5
  10. data/lib/active_record/associations.rb +77 -85
  11. data/lib/active_record/associations/alias_tracker.rb +23 -32
  12. data/lib/active_record/associations/association.rb +49 -35
  13. data/lib/active_record/associations/association_scope.rb +55 -55
  14. data/lib/active_record/associations/belongs_to_association.rb +30 -11
  15. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -8
  16. data/lib/active_record/associations/builder/association.rb +4 -7
  17. data/lib/active_record/associations/builder/belongs_to.rb +21 -8
  18. data/lib/active_record/associations/builder/collection_association.rb +1 -1
  19. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -1
  20. data/lib/active_record/associations/builder/has_many.rb +2 -0
  21. data/lib/active_record/associations/builder/has_one.rb +2 -0
  22. data/lib/active_record/associations/builder/singular_association.rb +2 -0
  23. data/lib/active_record/associations/collection_association.rb +66 -53
  24. data/lib/active_record/associations/collection_proxy.rb +30 -73
  25. data/lib/active_record/associations/foreign_association.rb +2 -0
  26. data/lib/active_record/associations/has_many_association.rb +13 -2
  27. data/lib/active_record/associations/has_many_through_association.rb +37 -19
  28. data/lib/active_record/associations/has_one_association.rb +14 -1
  29. data/lib/active_record/associations/has_one_through_association.rb +13 -8
  30. data/lib/active_record/associations/join_dependency.rb +52 -96
  31. data/lib/active_record/associations/join_dependency/join_association.rb +22 -75
  32. data/lib/active_record/associations/join_dependency/join_base.rb +9 -8
  33. data/lib/active_record/associations/join_dependency/join_part.rb +9 -9
  34. data/lib/active_record/associations/preloader.rb +17 -37
  35. data/lib/active_record/associations/preloader/association.rb +53 -92
  36. data/lib/active_record/associations/preloader/through_association.rb +72 -73
  37. data/lib/active_record/associations/singular_association.rb +14 -16
  38. data/lib/active_record/associations/through_association.rb +27 -12
  39. data/lib/active_record/attribute_assignment.rb +2 -5
  40. data/lib/active_record/attribute_decorators.rb +3 -2
  41. data/lib/active_record/attribute_methods.rb +65 -24
  42. data/lib/active_record/attribute_methods/before_type_cast.rb +2 -0
  43. data/lib/active_record/attribute_methods/dirty.rb +33 -216
  44. data/lib/active_record/attribute_methods/primary_key.rb +10 -13
  45. data/lib/active_record/attribute_methods/query.rb +2 -0
  46. data/lib/active_record/attribute_methods/read.rb +9 -3
  47. data/lib/active_record/attribute_methods/serialization.rb +23 -0
  48. data/lib/active_record/attribute_methods/time_zone_conversion.rb +6 -8
  49. data/lib/active_record/attribute_methods/write.rb +22 -19
  50. data/lib/active_record/attributes.rb +7 -6
  51. data/lib/active_record/autosave_association.rb +15 -13
  52. data/lib/active_record/base.rb +2 -0
  53. data/lib/active_record/callbacks.rb +12 -6
  54. data/lib/active_record/coders/json.rb +2 -0
  55. data/lib/active_record/coders/yaml_column.rb +2 -0
  56. data/lib/active_record/collection_cache_key.rb +15 -11
  57. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +120 -39
  58. data/lib/active_record/connection_adapters/abstract/database_limits.rb +7 -0
  59. data/lib/active_record/connection_adapters/abstract/database_statements.rb +192 -37
  60. data/lib/active_record/connection_adapters/abstract/query_cache.rb +13 -2
  61. data/lib/active_record/connection_adapters/abstract/quoting.rb +15 -25
  62. data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
  63. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +15 -6
  64. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +65 -7
  65. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +31 -53
  66. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +158 -87
  67. data/lib/active_record/connection_adapters/abstract/transaction.rb +66 -21
  68. data/lib/active_record/connection_adapters/abstract_adapter.rb +86 -98
  69. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +126 -189
  70. data/lib/active_record/connection_adapters/column.rb +4 -2
  71. data/lib/active_record/connection_adapters/connection_specification.rb +17 -3
  72. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +13 -2
  73. data/lib/active_record/connection_adapters/mysql/column.rb +2 -0
  74. data/lib/active_record/connection_adapters/mysql/database_statements.rb +45 -15
  75. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +2 -0
  76. data/lib/active_record/connection_adapters/mysql/quoting.rb +9 -10
  77. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +5 -3
  78. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +7 -10
  79. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +30 -23
  80. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +106 -1
  81. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +2 -0
  82. data/lib/active_record/connection_adapters/mysql2_adapter.rb +8 -2
  83. data/lib/active_record/connection_adapters/postgresql/column.rb +30 -1
  84. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +6 -32
  85. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +2 -0
  86. data/lib/active_record/connection_adapters/postgresql/oid.rb +3 -1
  87. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +13 -1
  88. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +2 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  90. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +2 -0
  92. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
  93. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -0
  94. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  95. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +2 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +2 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  99. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -1
  101. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +2 -0
  102. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -0
  103. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +8 -2
  104. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +2 -0
  105. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +4 -2
  106. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +3 -1
  107. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
  108. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
  109. data/lib/active_record/connection_adapters/postgresql/quoting.rb +22 -1
  110. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
  111. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +50 -0
  112. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +24 -11
  113. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +20 -13
  114. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +258 -129
  115. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +2 -0
  116. data/lib/active_record/connection_adapters/postgresql/utils.rb +3 -1
  117. data/lib/active_record/connection_adapters/postgresql_adapter.rb +75 -87
  118. data/lib/active_record/connection_adapters/schema_cache.rb +4 -2
  119. data/lib/active_record/connection_adapters/sql_type_metadata.rb +2 -0
  120. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +2 -0
  121. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +24 -1
  122. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +2 -0
  123. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +6 -15
  124. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +3 -2
  125. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +75 -1
  126. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +90 -96
  127. data/lib/active_record/connection_adapters/statement_pool.rb +2 -0
  128. data/lib/active_record/connection_handling.rb +4 -2
  129. data/lib/active_record/core.rb +41 -61
  130. data/lib/active_record/counter_cache.rb +20 -15
  131. data/lib/active_record/define_callbacks.rb +5 -3
  132. data/lib/active_record/dynamic_matchers.rb +9 -9
  133. data/lib/active_record/enum.rb +18 -13
  134. data/lib/active_record/errors.rb +60 -15
  135. data/lib/active_record/explain.rb +3 -1
  136. data/lib/active_record/explain_registry.rb +2 -0
  137. data/lib/active_record/explain_subscriber.rb +2 -0
  138. data/lib/active_record/fixture_set/file.rb +2 -0
  139. data/lib/active_record/fixtures.rb +67 -60
  140. data/lib/active_record/gem_version.rb +4 -2
  141. data/lib/active_record/inheritance.rb +49 -19
  142. data/lib/active_record/integration.rb +58 -19
  143. data/lib/active_record/internal_metadata.rb +2 -0
  144. data/lib/active_record/legacy_yaml_adapter.rb +3 -1
  145. data/lib/active_record/locking/optimistic.rb +30 -42
  146. data/lib/active_record/locking/pessimistic.rb +10 -7
  147. data/lib/active_record/log_subscriber.rb +46 -4
  148. data/lib/active_record/migration.rb +189 -139
  149. data/lib/active_record/migration/command_recorder.rb +11 -9
  150. data/lib/active_record/migration/compatibility.rb +81 -29
  151. data/lib/active_record/migration/join_table.rb +2 -0
  152. data/lib/active_record/model_schema.rb +74 -58
  153. data/lib/active_record/nested_attributes.rb +18 -6
  154. data/lib/active_record/no_touching.rb +3 -1
  155. data/lib/active_record/null_relation.rb +2 -0
  156. data/lib/active_record/persistence.rb +199 -54
  157. data/lib/active_record/query_cache.rb +8 -10
  158. data/lib/active_record/querying.rb +5 -3
  159. data/lib/active_record/railtie.rb +62 -6
  160. data/lib/active_record/railties/console_sandbox.rb +2 -0
  161. data/lib/active_record/railties/controller_runtime.rb +2 -0
  162. data/lib/active_record/railties/databases.rake +48 -38
  163. data/lib/active_record/readonly_attributes.rb +3 -2
  164. data/lib/active_record/reflection.rb +137 -207
  165. data/lib/active_record/relation.rb +132 -207
  166. data/lib/active_record/relation/batches.rb +32 -17
  167. data/lib/active_record/relation/batches/batch_enumerator.rb +2 -0
  168. data/lib/active_record/relation/calculations.rb +66 -25
  169. data/lib/active_record/relation/delegation.rb +45 -29
  170. data/lib/active_record/relation/finder_methods.rb +76 -85
  171. data/lib/active_record/relation/from_clause.rb +2 -8
  172. data/lib/active_record/relation/merger.rb +53 -23
  173. data/lib/active_record/relation/predicate_builder.rb +60 -79
  174. data/lib/active_record/relation/predicate_builder/array_handler.rb +10 -7
  175. data/lib/active_record/relation/predicate_builder/association_query_value.rb +46 -0
  176. data/lib/active_record/relation/predicate_builder/base_handler.rb +2 -2
  177. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +12 -1
  178. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +56 -0
  179. data/lib/active_record/relation/predicate_builder/range_handler.rb +26 -9
  180. data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
  181. data/lib/active_record/relation/query_attribute.rb +28 -2
  182. data/lib/active_record/relation/query_methods.rb +135 -103
  183. data/lib/active_record/relation/record_fetch_warning.rb +2 -0
  184. data/lib/active_record/relation/spawn_methods.rb +4 -2
  185. data/lib/active_record/relation/where_clause.rb +65 -67
  186. data/lib/active_record/relation/where_clause_factory.rb +5 -48
  187. data/lib/active_record/result.rb +2 -0
  188. data/lib/active_record/runtime_registry.rb +2 -0
  189. data/lib/active_record/sanitization.rb +129 -121
  190. data/lib/active_record/schema.rb +4 -2
  191. data/lib/active_record/schema_dumper.rb +36 -26
  192. data/lib/active_record/schema_migration.rb +2 -0
  193. data/lib/active_record/scoping.rb +12 -10
  194. data/lib/active_record/scoping/default.rb +10 -7
  195. data/lib/active_record/scoping/named.rb +40 -12
  196. data/lib/active_record/secure_token.rb +2 -0
  197. data/lib/active_record/serialization.rb +2 -0
  198. data/lib/active_record/statement_cache.rb +22 -12
  199. data/lib/active_record/store.rb +3 -1
  200. data/lib/active_record/suppressor.rb +2 -0
  201. data/lib/active_record/table_metadata.rb +12 -3
  202. data/lib/active_record/tasks/database_tasks.rb +38 -26
  203. data/lib/active_record/tasks/mysql_database_tasks.rb +11 -50
  204. data/lib/active_record/tasks/postgresql_database_tasks.rb +11 -3
  205. data/lib/active_record/tasks/sqlite_database_tasks.rb +25 -3
  206. data/lib/active_record/timestamp.rb +13 -6
  207. data/lib/active_record/touch_later.rb +2 -0
  208. data/lib/active_record/transactions.rb +32 -27
  209. data/lib/active_record/translation.rb +2 -0
  210. data/lib/active_record/type.rb +4 -1
  211. data/lib/active_record/type/adapter_specific_registry.rb +2 -0
  212. data/lib/active_record/type/date.rb +2 -0
  213. data/lib/active_record/type/date_time.rb +2 -0
  214. data/lib/active_record/type/decimal_without_scale.rb +2 -0
  215. data/lib/active_record/type/hash_lookup_type_map.rb +2 -0
  216. data/lib/active_record/type/internal/timezone.rb +2 -0
  217. data/lib/active_record/type/json.rb +30 -0
  218. data/lib/active_record/type/serialized.rb +6 -0
  219. data/lib/active_record/type/text.rb +2 -0
  220. data/lib/active_record/type/time.rb +2 -0
  221. data/lib/active_record/type/type_map.rb +2 -0
  222. data/lib/active_record/type/unsigned_integer.rb +2 -0
  223. data/lib/active_record/type_caster.rb +2 -0
  224. data/lib/active_record/type_caster/connection.rb +2 -0
  225. data/lib/active_record/type_caster/map.rb +3 -1
  226. data/lib/active_record/validations.rb +2 -0
  227. data/lib/active_record/validations/absence.rb +2 -0
  228. data/lib/active_record/validations/associated.rb +2 -0
  229. data/lib/active_record/validations/length.rb +2 -0
  230. data/lib/active_record/validations/presence.rb +2 -0
  231. data/lib/active_record/validations/uniqueness.rb +36 -6
  232. data/lib/active_record/version.rb +2 -0
  233. data/lib/rails/generators/active_record.rb +3 -1
  234. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
  235. data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
  236. data/lib/rails/generators/active_record/migration.rb +2 -0
  237. data/lib/rails/generators/active_record/migration/migration_generator.rb +3 -1
  238. data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +0 -0
  239. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +0 -0
  240. data/lib/rails/generators/active_record/model/model_generator.rb +2 -23
  241. data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +0 -0
  242. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  243. metadata +24 -36
  244. data/lib/active_record/associations/preloader/belongs_to.rb +0 -15
  245. data/lib/active_record/associations/preloader/collection_association.rb +0 -17
  246. data/lib/active_record/associations/preloader/has_many.rb +0 -15
  247. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  248. data/lib/active_record/associations/preloader/has_one.rb +0 -15
  249. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  250. data/lib/active_record/associations/preloader/singular_association.rb +0 -18
  251. data/lib/active_record/attribute.rb +0 -240
  252. data/lib/active_record/attribute/user_provided_default.rb +0 -30
  253. data/lib/active_record/attribute_mutation_tracker.rb +0 -113
  254. data/lib/active_record/attribute_set.rb +0 -113
  255. data/lib/active_record/attribute_set/builder.rb +0 -124
  256. data/lib/active_record/attribute_set/yaml_encoder.rb +0 -41
  257. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -10
  258. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  259. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
  260. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -59
  261. data/lib/active_record/type/internal/abstract_json.rb +0 -33
@@ -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?
@@ -12,11 +17,23 @@ module ActiveRecord
12
17
  end
13
18
 
14
19
  def committed?
15
- @state == :committed
20
+ @state == :committed || @state == :fully_committed
21
+ end
22
+
23
+ def fully_committed?
24
+ @state == :fully_committed
16
25
  end
17
26
 
18
27
  def rolledback?
19
- @state == :rolledback
28
+ @state == :rolledback || @state == :fully_rolledback
29
+ end
30
+
31
+ def fully_rolledback?
32
+ @state == :fully_rolledback
33
+ end
34
+
35
+ def fully_completed?
36
+ completed?
20
37
  end
21
38
 
22
39
  def completed?
@@ -24,10 +41,43 @@ module ActiveRecord
24
41
  end
25
42
 
26
43
  def set_state(state)
27
- unless VALID_STATES.include?(state)
44
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
45
+ The set_state method is deprecated and will be removed in
46
+ Rails 6.0. Please use rollback! or commit! to set transaction
47
+ state directly.
48
+ MSG
49
+ case state
50
+ when :rolledback
51
+ rollback!
52
+ when :committed
53
+ commit!
54
+ when nil
55
+ nullify!
56
+ else
28
57
  raise ArgumentError, "Invalid transaction state: #{state}"
29
58
  end
30
- @state = state
59
+ end
60
+
61
+ def rollback!
62
+ @children.each { |c| c.rollback! }
63
+ @state = :rolledback
64
+ end
65
+
66
+ def full_rollback!
67
+ @children.each { |c| c.rollback! }
68
+ @state = :fully_rolledback
69
+ end
70
+
71
+ def commit!
72
+ @state = :committed
73
+ end
74
+
75
+ def full_commit!
76
+ @state = :fully_committed
77
+ end
78
+
79
+ def nullify!
80
+ @state = nil
31
81
  end
32
82
  end
33
83
 
@@ -56,10 +106,6 @@ module ActiveRecord
56
106
  records << record
57
107
  end
58
108
 
59
- def rollback
60
- @state.set_state(:rolledback)
61
- end
62
-
63
109
  def rollback_records
64
110
  ite = records.uniq
65
111
  while record = ite.shift
@@ -71,10 +117,6 @@ module ActiveRecord
71
117
  end
72
118
  end
73
119
 
74
- def commit
75
- @state.set_state(:committed)
76
- end
77
-
78
120
  def before_commit_records
79
121
  records.uniq.each(&:before_committed!) if @run_commit_callbacks
80
122
  end
@@ -100,8 +142,11 @@ module ActiveRecord
100
142
  end
101
143
 
102
144
  class SavepointTransaction < Transaction
103
- def initialize(connection, savepoint_name, options, *args)
145
+ def initialize(connection, savepoint_name, parent_transaction, options, *args)
104
146
  super(connection, options, *args)
147
+
148
+ parent_transaction.state.add_child(@state)
149
+
105
150
  if options[:isolation]
106
151
  raise ActiveRecord::TransactionIsolationError, "cannot set transaction isolation in a nested transaction"
107
152
  end
@@ -110,12 +155,12 @@ module ActiveRecord
110
155
 
111
156
  def rollback
112
157
  connection.rollback_to_savepoint(savepoint_name)
113
- super
158
+ @state.rollback!
114
159
  end
115
160
 
116
161
  def commit
117
162
  connection.release_savepoint(savepoint_name)
118
- super
163
+ @state.commit!
119
164
  end
120
165
 
121
166
  def full_rollback?; false; end
@@ -133,12 +178,12 @@ module ActiveRecord
133
178
 
134
179
  def rollback
135
180
  connection.rollback_db_transaction
136
- super
181
+ @state.full_rollback!
137
182
  end
138
183
 
139
184
  def commit
140
185
  connection.commit_db_transaction
141
- super
186
+ @state.full_commit!
142
187
  end
143
188
  end
144
189
 
@@ -155,7 +200,7 @@ module ActiveRecord
155
200
  if @stack.empty?
156
201
  RealTransaction.new(@connection, options, run_commit_callbacks: run_commit_callbacks)
157
202
  else
158
- SavepointTransaction.new(@connection, "active_record_#{@stack.size}", options,
203
+ SavepointTransaction.new(@connection, "active_record_#{@stack.size}", @stack.last, options,
159
204
  run_commit_callbacks: run_commit_callbacks)
160
205
  end
161
206
 
@@ -204,7 +249,7 @@ module ActiveRecord
204
249
  rollback_transaction if transaction
205
250
  else
206
251
  begin
207
- commit_transaction
252
+ commit_transaction if transaction
208
253
  rescue Exception
209
254
  rollback_transaction(transaction) unless transaction.state.completed?
210
255
  raise
@@ -1,11 +1,15 @@
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"
5
6
  require "active_record/connection_adapters/abstract/schema_dumper"
6
7
  require "active_record/connection_adapters/abstract/schema_creation"
8
+ require "active_support/concurrency/load_interlock_aware_monitor"
7
9
  require "arel/collectors/bind"
10
+ require "arel/collectors/composite"
8
11
  require "arel/collectors/sql_string"
12
+ require "arel/collectors/substitute_binds"
9
13
 
10
14
  module ActiveRecord
11
15
  module ConnectionAdapters # :nodoc:
@@ -68,7 +72,6 @@ module ActiveRecord
68
72
  include Quoting, DatabaseStatements, SchemaStatements
69
73
  include DatabaseLimits
70
74
  include QueryCache
71
- include ColumnDumper
72
75
  include Savepoints
73
76
 
74
77
  SIMPLE_INT = /\A\d+\z/
@@ -78,7 +81,9 @@ module ActiveRecord
78
81
  alias :in_use? :owner
79
82
 
80
83
  def self.type_cast_config_to_integer(config)
81
- if config =~ SIMPLE_INT
84
+ if config.is_a?(Integer)
85
+ config
86
+ elsif config =~ SIMPLE_INT
82
87
  config.to_i
83
88
  else
84
89
  config
@@ -102,10 +107,11 @@ module ActiveRecord
102
107
  @logger = logger
103
108
  @config = config
104
109
  @pool = nil
110
+ @idle_since = Concurrent.monotonic_time
105
111
  @schema_cache = SchemaCache.new self
106
112
  @quoted_column_names, @quoted_table_names = {}, {}
107
113
  @visitor = arel_visitor
108
- @lock = Monitor.new
114
+ @lock = ActiveSupport::Concurrency::LoadInterlockAwareMonitor.new
109
115
 
110
116
  if self.class.type_cast_config_to_boolean(config.fetch(:prepared_statements) { true })
111
117
  @prepared_statements = true
@@ -115,6 +121,14 @@ module ActiveRecord
115
121
  end
116
122
  end
117
123
 
124
+ def migrations_paths # :nodoc:
125
+ @config[:migrations_paths] || Migrator.migrations_paths
126
+ end
127
+
128
+ def migration_context # :nodoc:
129
+ MigrationContext.new(migrations_paths)
130
+ end
131
+
118
132
  class Version
119
133
  include Comparable
120
134
 
@@ -127,51 +141,14 @@ module ActiveRecord
127
141
  end
128
142
  end
129
143
 
130
- class BindCollector < Arel::Collectors::Bind
131
- def compile(bvs, conn)
132
- casted_binds = bvs.map(&:value_for_database)
133
- super(casted_binds.map { |value| conn.quote(value) })
134
- end
135
- end
136
-
137
- class SQLString < Arel::Collectors::SQLString
138
- def compile(bvs, conn)
139
- super(bvs)
140
- end
141
- end
142
-
143
- def collector
144
- if prepared_statements
145
- SQLString.new
146
- else
147
- BindCollector.new
148
- end
149
- end
150
-
151
- def arel_visitor # :nodoc:
152
- Arel::Visitors::ToSql.new(self)
153
- end
154
-
155
144
  def valid_type?(type) # :nodoc:
156
145
  !native_database_types[type].nil?
157
146
  end
158
147
 
159
- def schema_creation
160
- SchemaCreation.new self
161
- end
162
-
163
- # Returns an array of +Column+ objects for the table specified by +table_name+.
164
- def columns(table_name) # :nodoc:
165
- table_name = table_name.to_s
166
- column_definitions(table_name).map do |field|
167
- new_column_from_field(table_name, field)
168
- end
169
- end
170
-
171
148
  # this method must only be called while holding connection pool's mutex
172
149
  def lease
173
150
  if in_use?
174
- msg = "Cannot lease connection, "
151
+ msg = "Cannot lease connection, ".dup
175
152
  if @owner == Thread.current
176
153
  msg << "it is already leased by the current thread."
177
154
  else
@@ -198,6 +175,7 @@ module ActiveRecord
198
175
  "Current thread: #{Thread.current}."
199
176
  end
200
177
 
178
+ @idle_since = Concurrent.monotonic_time
201
179
  @owner = nil
202
180
  else
203
181
  raise ActiveRecordError, "Cannot expire connection, it is not currently leased."
@@ -217,6 +195,12 @@ module ActiveRecord
217
195
  end
218
196
  end
219
197
 
198
+ # Seconds since this connection was returned to the pool
199
+ def seconds_idle # :nodoc:
200
+ return 0 if in_use?
201
+ Concurrent.monotonic_time - @idle_since
202
+ end
203
+
220
204
  def unprepared_statement
221
205
  old_prepared_statements, @prepared_statements = @prepared_statements, false
222
206
  yield
@@ -230,16 +214,6 @@ module ActiveRecord
230
214
  self.class::ADAPTER_NAME
231
215
  end
232
216
 
233
- def supports_migrations? # :nodoc:
234
- true
235
- end
236
- deprecate :supports_migrations?
237
-
238
- def supports_primary_key? # :nodoc:
239
- true
240
- end
241
- deprecate :supports_primary_key?
242
-
243
217
  # Does this adapter support DDL rollbacks in transactions? That is, would
244
218
  # CREATE TABLE or ALTER TABLE get rolled back by a transaction?
245
219
  def supports_ddl_transactions?
@@ -308,6 +282,11 @@ module ActiveRecord
308
282
  false
309
283
  end
310
284
 
285
+ # Does this adapter support creating invalid constraints?
286
+ def supports_validate_constraints?
287
+ false
288
+ end
289
+
311
290
  # Does this adapter support creating foreign key constraints
312
291
  # in the same statement as creating the table?
313
292
  def supports_foreign_keys_in_create?
@@ -349,6 +328,11 @@ module ActiveRecord
349
328
  false
350
329
  end
351
330
 
331
+ # Does this adapter support foreign/external tables?
332
+ def supports_foreign_tables?
333
+ false
334
+ end
335
+
352
336
  # This is meant to be implemented by the adapters that support extensions
353
337
  def disable_extension(name)
354
338
  end
@@ -411,6 +395,19 @@ module ActiveRecord
411
395
  reset_transaction
412
396
  end
413
397
 
398
+ # Immediately forget this connection ever existed. Unlike disconnect!,
399
+ # this will not communicate with the server.
400
+ #
401
+ # After calling this method, the behavior of all other methods becomes
402
+ # undefined. This is called internally just before a forked process gets
403
+ # rid of a connection that belonged to its parent.
404
+ def discard!
405
+ # This should be overridden by concrete adapters.
406
+ #
407
+ # Prevent @connection's finalizer from touching the socket, or
408
+ # otherwise communicating with its server, when it is collected.
409
+ end
410
+
414
411
  # Reset the state of this connection, directing the DBMS to clear
415
412
  # transactions and other connection-related server-side state. Usually a
416
413
  # database-dependent operation.
@@ -436,10 +433,7 @@ module ActiveRecord
436
433
  # Checks whether the connection to the database is still active (i.e. not stale).
437
434
  # This is done under the hood by calling #active?. If the connection
438
435
  # is no longer active, then this method will reconnect to the database.
439
- def verify!(*ignored)
440
- if ignored.size > 0
441
- 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.")
442
- end
436
+ def verify!
443
437
  reconnect! unless active?
444
438
  end
445
439
 
@@ -475,40 +469,12 @@ module ActiveRecord
475
469
  pool.checkin self
476
470
  end
477
471
 
478
- def type_map # :nodoc:
479
- @type_map ||= Type::TypeMap.new.tap do |mapping|
480
- initialize_type_map(mapping)
481
- end
482
- end
483
-
484
- def new_column(name, default, sql_type_metadata, null, table_name, default_function = nil, collation = nil) # :nodoc:
485
- Column.new(name, default, sql_type_metadata, null, table_name, default_function, collation)
472
+ def column_name_for_operation(operation, node) # :nodoc:
473
+ column_name_from_arel_node(node)
486
474
  end
487
475
 
488
- def lookup_cast_type(sql_type) # :nodoc:
489
- type_map.lookup(sql_type)
490
- end
491
-
492
- def column_name_for_operation(operation, node) # :nodoc:
493
- visitor.accept(node, collector).value
494
- end
495
-
496
- def combine_bind_parameters(
497
- from_clause: [],
498
- join_clause: [],
499
- where_clause: [],
500
- having_clause: [],
501
- limit: nil,
502
- offset: nil
503
- ) # :nodoc:
504
- result = from_clause + join_clause + where_clause + having_clause
505
- if limit
506
- result << limit
507
- end
508
- if offset
509
- result << offset
510
- end
511
- result
476
+ def column_name_from_arel_node(node) # :nodoc:
477
+ visitor.accept(node, Arel::Collectors::SQLString.new).value
512
478
  end
513
479
 
514
480
  def default_index_type?(index) # :nodoc:
@@ -516,8 +482,13 @@ module ActiveRecord
516
482
  end
517
483
 
518
484
  private
485
+ def type_map
486
+ @type_map ||= Type::TypeMap.new.tap do |mapping|
487
+ initialize_type_map(mapping)
488
+ end
489
+ end
519
490
 
520
- def initialize_type_map(m)
491
+ def initialize_type_map(m = type_map)
521
492
  register_class_with_limit m, %r(boolean)i, Type::Boolean
522
493
  register_class_with_limit m, %r(char)i, Type::String
523
494
  register_class_with_limit m, %r(binary)i, Type::Binary
@@ -535,6 +506,8 @@ module ActiveRecord
535
506
  m.alias_type %r(number)i, "decimal"
536
507
  m.alias_type %r(double)i, "float"
537
508
 
509
+ m.register_type %r(^json)i, Type::Json.new
510
+
538
511
  m.register_type(%r(decimal)i) do |sql_type|
539
512
  scale = extract_scale(sql_type)
540
513
  precision = extract_precision(sql_type)
@@ -550,7 +523,7 @@ module ActiveRecord
550
523
 
551
524
  def reload_type_map
552
525
  type_map.clear
553
- initialize_type_map(type_map)
526
+ initialize_type_map
554
527
  end
555
528
 
556
529
  def register_class_with_limit(mapping, key, klass)
@@ -579,12 +552,7 @@ module ActiveRecord
579
552
  end
580
553
 
581
554
  def extract_limit(sql_type)
582
- case sql_type
583
- when /^bigint/i
584
- 8
585
- when /\((.*)\)/
586
- $1.to_i
587
- end
555
+ $1.to_i if sql_type =~ /\((.*)\)/
588
556
  end
589
557
 
590
558
  def translate_exception_class(e, sql)
@@ -608,12 +576,14 @@ module ActiveRecord
608
576
  type_casted_binds: type_casted_binds,
609
577
  statement_name: statement_name,
610
578
  connection_id: object_id) do
579
+ begin
611
580
  @lock.synchronize do
612
581
  yield
613
582
  end
583
+ rescue => e
584
+ raise translate_exception_class(e, sql)
614
585
  end
615
- rescue => e
616
- raise translate_exception_class(e, sql)
586
+ end
617
587
  end
618
588
 
619
589
  def translate_exception(exception, message)
@@ -635,6 +605,24 @@ module ActiveRecord
635
605
  columns(table_name).detect { |c| c.name == column_name } ||
636
606
  raise(ActiveRecordError, "No such column: #{table_name}.#{column_name}")
637
607
  end
608
+
609
+ def collector
610
+ if prepared_statements
611
+ Arel::Collectors::Composite.new(
612
+ Arel::Collectors::SQLString.new,
613
+ Arel::Collectors::Bind.new,
614
+ )
615
+ else
616
+ Arel::Collectors::SubstituteBinds.new(
617
+ self,
618
+ Arel::Collectors::SQLString.new,
619
+ )
620
+ end
621
+ end
622
+
623
+ def arel_visitor
624
+ Arel::Visitors::ToSql.new(self)
625
+ end
638
626
  end
639
627
  end
640
628
  end