activerecord 5.2.4.3 → 6.0.2.2

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 (269) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +715 -571
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +4 -2
  5. data/examples/performance.rb +1 -1
  6. data/lib/active_record.rb +9 -2
  7. data/lib/active_record/aggregations.rb +4 -2
  8. data/lib/active_record/association_relation.rb +15 -6
  9. data/lib/active_record/associations.rb +20 -15
  10. data/lib/active_record/associations/association.rb +61 -20
  11. data/lib/active_record/associations/association_scope.rb +4 -6
  12. data/lib/active_record/associations/belongs_to_association.rb +36 -42
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +0 -4
  14. data/lib/active_record/associations/builder/association.rb +14 -18
  15. data/lib/active_record/associations/builder/belongs_to.rb +19 -52
  16. data/lib/active_record/associations/builder/collection_association.rb +3 -13
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +17 -38
  18. data/lib/active_record/associations/builder/has_many.rb +2 -0
  19. data/lib/active_record/associations/builder/has_one.rb +35 -1
  20. data/lib/active_record/associations/builder/singular_association.rb +2 -0
  21. data/lib/active_record/associations/collection_association.rb +12 -23
  22. data/lib/active_record/associations/collection_proxy.rb +12 -15
  23. data/lib/active_record/associations/foreign_association.rb +7 -0
  24. data/lib/active_record/associations/has_many_association.rb +2 -10
  25. data/lib/active_record/associations/has_many_through_association.rb +14 -14
  26. data/lib/active_record/associations/has_one_association.rb +28 -30
  27. data/lib/active_record/associations/has_one_through_association.rb +5 -5
  28. data/lib/active_record/associations/join_dependency.rb +28 -28
  29. data/lib/active_record/associations/join_dependency/join_association.rb +9 -10
  30. data/lib/active_record/associations/join_dependency/join_part.rb +2 -2
  31. data/lib/active_record/associations/preloader.rb +39 -31
  32. data/lib/active_record/associations/preloader/association.rb +38 -36
  33. data/lib/active_record/associations/preloader/through_association.rb +48 -39
  34. data/lib/active_record/associations/singular_association.rb +2 -16
  35. data/lib/active_record/attribute_assignment.rb +7 -10
  36. data/lib/active_record/attribute_methods.rb +28 -100
  37. data/lib/active_record/attribute_methods/before_type_cast.rb +4 -1
  38. data/lib/active_record/attribute_methods/dirty.rb +111 -40
  39. data/lib/active_record/attribute_methods/primary_key.rb +15 -22
  40. data/lib/active_record/attribute_methods/query.rb +2 -3
  41. data/lib/active_record/attribute_methods/read.rb +15 -53
  42. data/lib/active_record/attribute_methods/serialization.rb +1 -1
  43. data/lib/active_record/attribute_methods/time_zone_conversion.rb +1 -1
  44. data/lib/active_record/attribute_methods/write.rb +17 -24
  45. data/lib/active_record/attributes.rb +13 -0
  46. data/lib/active_record/autosave_association.rb +2 -2
  47. data/lib/active_record/base.rb +2 -3
  48. data/lib/active_record/callbacks.rb +5 -19
  49. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +104 -16
  50. data/lib/active_record/connection_adapters/abstract/database_limits.rb +17 -4
  51. data/lib/active_record/connection_adapters/abstract/database_statements.rb +99 -123
  52. data/lib/active_record/connection_adapters/abstract/query_cache.rb +18 -8
  53. data/lib/active_record/connection_adapters/abstract/quoting.rb +68 -17
  54. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +19 -12
  55. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +76 -48
  56. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +1 -3
  57. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +132 -53
  58. data/lib/active_record/connection_adapters/abstract/transaction.rb +96 -56
  59. data/lib/active_record/connection_adapters/abstract_adapter.rb +187 -43
  60. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +138 -195
  61. data/lib/active_record/connection_adapters/column.rb +17 -13
  62. data/lib/active_record/connection_adapters/connection_specification.rb +53 -43
  63. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +6 -10
  64. data/lib/active_record/connection_adapters/mysql/database_statements.rb +75 -13
  65. data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -7
  66. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +3 -4
  67. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +40 -32
  68. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +14 -6
  69. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +129 -13
  70. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +6 -10
  71. data/lib/active_record/connection_adapters/mysql2_adapter.rb +26 -9
  72. data/lib/active_record/connection_adapters/postgresql/column.rb +17 -31
  73. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +22 -1
  74. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
  75. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
  76. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +1 -1
  77. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +1 -1
  78. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
  79. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +1 -1
  80. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +1 -1
  81. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +9 -7
  82. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +6 -3
  83. data/lib/active_record/connection_adapters/postgresql/quoting.rb +44 -7
  84. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +12 -1
  85. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -91
  86. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +55 -53
  87. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +24 -27
  88. data/lib/active_record/connection_adapters/postgresql_adapter.rb +164 -74
  89. data/lib/active_record/connection_adapters/schema_cache.rb +37 -14
  90. data/lib/active_record/connection_adapters/sql_type_metadata.rb +11 -8
  91. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +120 -0
  92. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +42 -6
  93. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +42 -11
  94. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +129 -141
  95. data/lib/active_record/connection_handling.rb +155 -26
  96. data/lib/active_record/core.rb +103 -59
  97. data/lib/active_record/counter_cache.rb +4 -29
  98. data/lib/active_record/database_configurations.rb +233 -0
  99. data/lib/active_record/database_configurations/database_config.rb +37 -0
  100. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  101. data/lib/active_record/database_configurations/url_config.rb +79 -0
  102. data/lib/active_record/dynamic_matchers.rb +1 -1
  103. data/lib/active_record/enum.rb +37 -7
  104. data/lib/active_record/errors.rb +15 -7
  105. data/lib/active_record/explain.rb +1 -1
  106. data/lib/active_record/fixture_set/model_metadata.rb +33 -0
  107. data/lib/active_record/fixture_set/render_context.rb +17 -0
  108. data/lib/active_record/fixture_set/table_row.rb +153 -0
  109. data/lib/active_record/fixture_set/table_rows.rb +47 -0
  110. data/lib/active_record/fixtures.rb +145 -472
  111. data/lib/active_record/gem_version.rb +4 -4
  112. data/lib/active_record/inheritance.rb +13 -3
  113. data/lib/active_record/insert_all.rb +179 -0
  114. data/lib/active_record/integration.rb +68 -16
  115. data/lib/active_record/internal_metadata.rb +10 -2
  116. data/lib/active_record/locking/optimistic.rb +5 -6
  117. data/lib/active_record/locking/pessimistic.rb +3 -3
  118. data/lib/active_record/log_subscriber.rb +7 -26
  119. data/lib/active_record/middleware/database_selector.rb +75 -0
  120. data/lib/active_record/middleware/database_selector/resolver.rb +88 -0
  121. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  122. data/lib/active_record/migration.rb +100 -81
  123. data/lib/active_record/migration/command_recorder.rb +50 -6
  124. data/lib/active_record/migration/compatibility.rb +76 -49
  125. data/lib/active_record/model_schema.rb +33 -9
  126. data/lib/active_record/nested_attributes.rb +2 -2
  127. data/lib/active_record/no_touching.rb +7 -0
  128. data/lib/active_record/persistence.rb +228 -24
  129. data/lib/active_record/query_cache.rb +11 -4
  130. data/lib/active_record/querying.rb +32 -20
  131. data/lib/active_record/railtie.rb +80 -43
  132. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  133. data/lib/active_record/railties/controller_runtime.rb +30 -35
  134. data/lib/active_record/railties/databases.rake +199 -46
  135. data/lib/active_record/reflection.rb +32 -30
  136. data/lib/active_record/relation.rb +311 -80
  137. data/lib/active_record/relation/batches.rb +13 -10
  138. data/lib/active_record/relation/calculations.rb +53 -47
  139. data/lib/active_record/relation/delegation.rb +26 -43
  140. data/lib/active_record/relation/finder_methods.rb +23 -27
  141. data/lib/active_record/relation/merger.rb +11 -20
  142. data/lib/active_record/relation/predicate_builder.rb +4 -6
  143. data/lib/active_record/relation/predicate_builder/array_handler.rb +5 -4
  144. data/lib/active_record/relation/predicate_builder/association_query_value.rb +1 -4
  145. data/lib/active_record/relation/predicate_builder/base_handler.rb +1 -2
  146. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
  147. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +1 -4
  148. data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
  149. data/lib/active_record/relation/query_attribute.rb +13 -8
  150. data/lib/active_record/relation/query_methods.rb +213 -64
  151. data/lib/active_record/relation/spawn_methods.rb +1 -1
  152. data/lib/active_record/relation/where_clause.rb +14 -10
  153. data/lib/active_record/relation/where_clause_factory.rb +1 -2
  154. data/lib/active_record/result.rb +30 -11
  155. data/lib/active_record/sanitization.rb +32 -40
  156. data/lib/active_record/schema.rb +2 -11
  157. data/lib/active_record/schema_dumper.rb +22 -7
  158. data/lib/active_record/schema_migration.rb +5 -1
  159. data/lib/active_record/scoping.rb +8 -8
  160. data/lib/active_record/scoping/default.rb +4 -5
  161. data/lib/active_record/scoping/named.rb +20 -15
  162. data/lib/active_record/statement_cache.rb +30 -3
  163. data/lib/active_record/store.rb +87 -8
  164. data/lib/active_record/table_metadata.rb +10 -17
  165. data/lib/active_record/tasks/database_tasks.rb +194 -25
  166. data/lib/active_record/tasks/mysql_database_tasks.rb +5 -5
  167. data/lib/active_record/tasks/postgresql_database_tasks.rb +5 -7
  168. data/lib/active_record/tasks/sqlite_database_tasks.rb +2 -8
  169. data/lib/active_record/test_databases.rb +23 -0
  170. data/lib/active_record/test_fixtures.rb +225 -0
  171. data/lib/active_record/timestamp.rb +39 -25
  172. data/lib/active_record/touch_later.rb +4 -2
  173. data/lib/active_record/transactions.rb +56 -65
  174. data/lib/active_record/translation.rb +1 -1
  175. data/lib/active_record/type.rb +3 -4
  176. data/lib/active_record/type/adapter_specific_registry.rb +1 -8
  177. data/lib/active_record/type_caster/connection.rb +15 -14
  178. data/lib/active_record/type_caster/map.rb +1 -4
  179. data/lib/active_record/validations.rb +1 -0
  180. data/lib/active_record/validations/uniqueness.rb +15 -27
  181. data/lib/arel.rb +58 -0
  182. data/lib/arel/alias_predication.rb +9 -0
  183. data/lib/arel/attributes.rb +22 -0
  184. data/lib/arel/attributes/attribute.rb +37 -0
  185. data/lib/arel/collectors/bind.rb +24 -0
  186. data/lib/arel/collectors/composite.rb +31 -0
  187. data/lib/arel/collectors/plain_string.rb +20 -0
  188. data/lib/arel/collectors/sql_string.rb +20 -0
  189. data/lib/arel/collectors/substitute_binds.rb +28 -0
  190. data/lib/arel/crud.rb +42 -0
  191. data/lib/arel/delete_manager.rb +18 -0
  192. data/lib/arel/errors.rb +9 -0
  193. data/lib/arel/expressions.rb +29 -0
  194. data/lib/arel/factory_methods.rb +49 -0
  195. data/lib/arel/insert_manager.rb +49 -0
  196. data/lib/arel/math.rb +45 -0
  197. data/lib/arel/nodes.rb +68 -0
  198. data/lib/arel/nodes/and.rb +32 -0
  199. data/lib/arel/nodes/ascending.rb +23 -0
  200. data/lib/arel/nodes/binary.rb +52 -0
  201. data/lib/arel/nodes/bind_param.rb +36 -0
  202. data/lib/arel/nodes/case.rb +55 -0
  203. data/lib/arel/nodes/casted.rb +50 -0
  204. data/lib/arel/nodes/comment.rb +29 -0
  205. data/lib/arel/nodes/count.rb +12 -0
  206. data/lib/arel/nodes/delete_statement.rb +45 -0
  207. data/lib/arel/nodes/descending.rb +23 -0
  208. data/lib/arel/nodes/equality.rb +18 -0
  209. data/lib/arel/nodes/extract.rb +24 -0
  210. data/lib/arel/nodes/false.rb +16 -0
  211. data/lib/arel/nodes/full_outer_join.rb +8 -0
  212. data/lib/arel/nodes/function.rb +44 -0
  213. data/lib/arel/nodes/grouping.rb +8 -0
  214. data/lib/arel/nodes/in.rb +8 -0
  215. data/lib/arel/nodes/infix_operation.rb +80 -0
  216. data/lib/arel/nodes/inner_join.rb +8 -0
  217. data/lib/arel/nodes/insert_statement.rb +37 -0
  218. data/lib/arel/nodes/join_source.rb +20 -0
  219. data/lib/arel/nodes/matches.rb +18 -0
  220. data/lib/arel/nodes/named_function.rb +23 -0
  221. data/lib/arel/nodes/node.rb +50 -0
  222. data/lib/arel/nodes/node_expression.rb +13 -0
  223. data/lib/arel/nodes/outer_join.rb +8 -0
  224. data/lib/arel/nodes/over.rb +15 -0
  225. data/lib/arel/nodes/regexp.rb +16 -0
  226. data/lib/arel/nodes/right_outer_join.rb +8 -0
  227. data/lib/arel/nodes/select_core.rb +67 -0
  228. data/lib/arel/nodes/select_statement.rb +41 -0
  229. data/lib/arel/nodes/sql_literal.rb +16 -0
  230. data/lib/arel/nodes/string_join.rb +11 -0
  231. data/lib/arel/nodes/table_alias.rb +27 -0
  232. data/lib/arel/nodes/terminal.rb +16 -0
  233. data/lib/arel/nodes/true.rb +16 -0
  234. data/lib/arel/nodes/unary.rb +45 -0
  235. data/lib/arel/nodes/unary_operation.rb +20 -0
  236. data/lib/arel/nodes/unqualified_column.rb +22 -0
  237. data/lib/arel/nodes/update_statement.rb +41 -0
  238. data/lib/arel/nodes/values_list.rb +9 -0
  239. data/lib/arel/nodes/window.rb +126 -0
  240. data/lib/arel/nodes/with.rb +11 -0
  241. data/lib/arel/order_predications.rb +13 -0
  242. data/lib/arel/predications.rb +257 -0
  243. data/lib/arel/select_manager.rb +271 -0
  244. data/lib/arel/table.rb +110 -0
  245. data/lib/arel/tree_manager.rb +72 -0
  246. data/lib/arel/update_manager.rb +34 -0
  247. data/lib/arel/visitors.rb +20 -0
  248. data/lib/arel/visitors/depth_first.rb +204 -0
  249. data/lib/arel/visitors/dot.rb +297 -0
  250. data/lib/arel/visitors/ibm_db.rb +34 -0
  251. data/lib/arel/visitors/informix.rb +62 -0
  252. data/lib/arel/visitors/mssql.rb +157 -0
  253. data/lib/arel/visitors/mysql.rb +83 -0
  254. data/lib/arel/visitors/oracle.rb +159 -0
  255. data/lib/arel/visitors/oracle12.rb +66 -0
  256. data/lib/arel/visitors/postgresql.rb +110 -0
  257. data/lib/arel/visitors/sqlite.rb +39 -0
  258. data/lib/arel/visitors/to_sql.rb +889 -0
  259. data/lib/arel/visitors/visitor.rb +46 -0
  260. data/lib/arel/visitors/where_sql.rb +23 -0
  261. data/lib/arel/window_predications.rb +9 -0
  262. data/lib/rails/generators/active_record/migration.rb +14 -1
  263. data/lib/rails/generators/active_record/migration/migration_generator.rb +2 -5
  264. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +1 -1
  265. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +4 -2
  266. data/lib/rails/generators/active_record/model/model_generator.rb +1 -0
  267. data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
  268. metadata +111 -26
  269. data/lib/active_record/collection_cache_key.rb +0 -53
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_record/middleware/database_selector/resolver"
4
+
5
+ module ActiveRecord
6
+ module Middleware
7
+ # The DatabaseSelector Middleware provides a framework for automatically
8
+ # swapping from the primary to the replica database connection. Rails
9
+ # provides a basic framework to determine when to swap and allows for
10
+ # applications to write custom strategy classes to override the default
11
+ # behavior.
12
+ #
13
+ # The resolver class defines when the application should switch (i.e. read
14
+ # from the primary if a write occurred less than 2 seconds ago) and a
15
+ # resolver context class that sets a value that helps the resolver class
16
+ # decide when to switch.
17
+ #
18
+ # Rails default middleware uses the request's session to set a timestamp
19
+ # that informs the application when to read from a primary or read from a
20
+ # replica.
21
+ #
22
+ # To use the DatabaseSelector in your application with default settings add
23
+ # the following options to your environment config:
24
+ #
25
+ # config.active_record.database_selector = { delay: 2.seconds }
26
+ # config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver
27
+ # config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session
28
+ #
29
+ # New applications will include these lines commented out in the production.rb.
30
+ #
31
+ # The default behavior can be changed by setting the config options to a
32
+ # custom class:
33
+ #
34
+ # config.active_record.database_selector = { delay: 2.seconds }
35
+ # config.active_record.database_resolver = MyResolver
36
+ # config.active_record.database_resolver_context = MyResolver::MySession
37
+ class DatabaseSelector
38
+ def initialize(app, resolver_klass = nil, context_klass = nil, options = {})
39
+ @app = app
40
+ @resolver_klass = resolver_klass || Resolver
41
+ @context_klass = context_klass || Resolver::Session
42
+ @options = options
43
+ end
44
+
45
+ attr_reader :resolver_klass, :context_klass, :options
46
+
47
+ # Middleware that determines which database connection to use in a multiple
48
+ # database application.
49
+ def call(env)
50
+ request = ActionDispatch::Request.new(env)
51
+
52
+ select_database(request) do
53
+ @app.call(env)
54
+ end
55
+ end
56
+
57
+ private
58
+
59
+ def select_database(request, &blk)
60
+ context = context_klass.call(request)
61
+ resolver = resolver_klass.call(context, options)
62
+
63
+ if reading_request?(request)
64
+ resolver.read(&blk)
65
+ else
66
+ resolver.write(&blk)
67
+ end
68
+ end
69
+
70
+ def reading_request?(request)
71
+ request.get? || request.head?
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_record/middleware/database_selector/resolver/session"
4
+
5
+ module ActiveRecord
6
+ module Middleware
7
+ class DatabaseSelector
8
+ # The Resolver class is used by the DatabaseSelector middleware to
9
+ # determine which database the request should use.
10
+ #
11
+ # To change the behavior of the Resolver class in your application,
12
+ # create a custom resolver class that inherits from
13
+ # DatabaseSelector::Resolver and implements the methods that need to
14
+ # be changed.
15
+ #
16
+ # By default the Resolver class will send read traffic to the replica
17
+ # if it's been 2 seconds since the last write.
18
+ class Resolver # :nodoc:
19
+ SEND_TO_REPLICA_DELAY = 2.seconds
20
+
21
+ def self.call(context, options = {})
22
+ new(context, options)
23
+ end
24
+
25
+ def initialize(context, options = {})
26
+ @context = context
27
+ @options = options
28
+ @delay = @options && @options[:delay] ? @options[:delay] : SEND_TO_REPLICA_DELAY
29
+ @instrumenter = ActiveSupport::Notifications.instrumenter
30
+ end
31
+
32
+ attr_reader :context, :delay, :instrumenter
33
+
34
+ def read(&blk)
35
+ if read_from_primary?
36
+ read_from_primary(&blk)
37
+ else
38
+ read_from_replica(&blk)
39
+ end
40
+ end
41
+
42
+ def write(&blk)
43
+ write_to_primary(&blk)
44
+ end
45
+
46
+ private
47
+
48
+ def read_from_primary(&blk)
49
+ ActiveRecord::Base.connected_to(role: ActiveRecord::Base.writing_role, prevent_writes: true) do
50
+ instrumenter.instrument("database_selector.active_record.read_from_primary") do
51
+ yield
52
+ end
53
+ end
54
+ end
55
+
56
+ def read_from_replica(&blk)
57
+ ActiveRecord::Base.connected_to(role: ActiveRecord::Base.reading_role) do
58
+ instrumenter.instrument("database_selector.active_record.read_from_replica") do
59
+ yield
60
+ end
61
+ end
62
+ end
63
+
64
+ def write_to_primary(&blk)
65
+ ActiveRecord::Base.connected_to(role: ActiveRecord::Base.writing_role, prevent_writes: false) do
66
+ instrumenter.instrument("database_selector.active_record.wrote_to_primary") do
67
+ yield
68
+ ensure
69
+ context.update_last_write_timestamp
70
+ end
71
+ end
72
+ end
73
+
74
+ def read_from_primary?
75
+ !time_since_last_write_ok?
76
+ end
77
+
78
+ def send_to_replica_delay
79
+ delay
80
+ end
81
+
82
+ def time_since_last_write_ok?
83
+ Time.now - context.last_write_timestamp >= send_to_replica_delay
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module Middleware
5
+ class DatabaseSelector
6
+ class Resolver
7
+ # The session class is used by the DatabaseSelector::Resolver to save
8
+ # timestamps of the last write in the session.
9
+ #
10
+ # The last_write is used to determine whether it's safe to read
11
+ # from the replica or the request needs to be sent to the primary.
12
+ class Session # :nodoc:
13
+ def self.call(request)
14
+ new(request.session)
15
+ end
16
+
17
+ # Converts time to a timestamp that represents milliseconds since
18
+ # epoch.
19
+ def self.convert_time_to_timestamp(time)
20
+ time.to_i * 1000 + time.usec / 1000
21
+ end
22
+
23
+ # Converts milliseconds since epoch timestamp into a time object.
24
+ def self.convert_timestamp_to_time(timestamp)
25
+ timestamp ? Time.at(timestamp / 1000, (timestamp % 1000) * 1000) : Time.at(0)
26
+ end
27
+
28
+ def initialize(session)
29
+ @session = session
30
+ end
31
+
32
+ attr_reader :session
33
+
34
+ def last_write_timestamp
35
+ self.class.convert_timestamp_to_time(session[:last_write])
36
+ end
37
+
38
+ def update_last_write_timestamp
39
+ session[:last_write] = self.class.convert_time_to_timestamp(Time.now)
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -1,11 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "benchmark"
3
4
  require "set"
4
5
  require "zlib"
5
6
  require "active_support/core_ext/module/attribute_accessors"
7
+ require "active_support/actionable_error"
6
8
 
7
9
  module ActiveRecord
8
- class MigrationError < ActiveRecordError#:nodoc:
10
+ class MigrationError < ActiveRecordError #:nodoc:
9
11
  def initialize(message = nil)
10
12
  message = "\n\n#{message}\n\n" if message
11
13
  super
@@ -22,7 +24,7 @@ module ActiveRecord
22
24
  # t.string :zipcode
23
25
  # end
24
26
  #
25
- # execute <<-SQL
27
+ # execute <<~SQL
26
28
  # ALTER TABLE distributors
27
29
  # ADD CONSTRAINT zipchk
28
30
  # CHECK (char_length(zipcode) = 5) NO INHERIT;
@@ -40,7 +42,7 @@ module ActiveRecord
40
42
  # t.string :zipcode
41
43
  # end
42
44
  #
43
- # execute <<-SQL
45
+ # execute <<~SQL
44
46
  # ALTER TABLE distributors
45
47
  # ADD CONSTRAINT zipchk
46
48
  # CHECK (char_length(zipcode) = 5) NO INHERIT;
@@ -48,7 +50,7 @@ module ActiveRecord
48
50
  # end
49
51
  #
50
52
  # def down
51
- # execute <<-SQL
53
+ # execute <<~SQL
52
54
  # ALTER TABLE distributors
53
55
  # DROP CONSTRAINT zipchk
54
56
  # SQL
@@ -67,7 +69,7 @@ module ActiveRecord
67
69
  #
68
70
  # reversible do |dir|
69
71
  # dir.up do
70
- # execute <<-SQL
72
+ # execute <<~SQL
71
73
  # ALTER TABLE distributors
72
74
  # ADD CONSTRAINT zipchk
73
75
  # CHECK (char_length(zipcode) = 5) NO INHERIT;
@@ -75,7 +77,7 @@ module ActiveRecord
75
77
  # end
76
78
  #
77
79
  # dir.down do
78
- # execute <<-SQL
80
+ # execute <<~SQL
79
81
  # ALTER TABLE distributors
80
82
  # DROP CONSTRAINT zipchk
81
83
  # SQL
@@ -86,7 +88,7 @@ module ActiveRecord
86
88
  class IrreversibleMigration < MigrationError
87
89
  end
88
90
 
89
- class DuplicateMigrationVersionError < MigrationError#:nodoc:
91
+ class DuplicateMigrationVersionError < MigrationError #:nodoc:
90
92
  def initialize(version = nil)
91
93
  if version
92
94
  super("Multiple migrations have the version number #{version}.")
@@ -96,7 +98,7 @@ module ActiveRecord
96
98
  end
97
99
  end
98
100
 
99
- class DuplicateMigrationNameError < MigrationError#:nodoc:
101
+ class DuplicateMigrationNameError < MigrationError #:nodoc:
100
102
  def initialize(name = nil)
101
103
  if name
102
104
  super("Multiple migrations have the name #{name}.")
@@ -116,7 +118,7 @@ module ActiveRecord
116
118
  end
117
119
  end
118
120
 
119
- class IllegalMigrationNameError < MigrationError#:nodoc:
121
+ class IllegalMigrationNameError < MigrationError #:nodoc:
120
122
  def initialize(name = nil)
121
123
  if name
122
124
  super("Illegal name for migration file: #{name}\n\t(only lower case letters, numbers, and '_' allowed).")
@@ -126,12 +128,18 @@ module ActiveRecord
126
128
  end
127
129
  end
128
130
 
129
- class PendingMigrationError < MigrationError#:nodoc:
131
+ class PendingMigrationError < MigrationError #:nodoc:
132
+ include ActiveSupport::ActionableError
133
+
134
+ action "Run pending migrations" do
135
+ ActiveRecord::Tasks::DatabaseTasks.migrate
136
+ end
137
+
130
138
  def initialize(message = nil)
131
139
  if !message && defined?(Rails.env)
132
- super("Migrations are pending. To resolve this issue, run:\n\n bin/rails db:migrate RAILS_ENV=#{::Rails.env}")
140
+ super("Migrations are pending. To resolve this issue, run:\n\n rails db:migrate RAILS_ENV=#{::Rails.env}")
133
141
  elsif !message
134
- super("Migrations are pending. To resolve this issue, run:\n\n bin/rails db:migrate")
142
+ super("Migrations are pending. To resolve this issue, run:\n\n rails db:migrate")
135
143
  else
136
144
  super
137
145
  end
@@ -139,8 +147,8 @@ module ActiveRecord
139
147
  end
140
148
 
141
149
  class ConcurrentMigrationError < MigrationError #:nodoc:
142
- DEFAULT_MESSAGE = "Cannot run migrations because another migration process is currently running.".freeze
143
- RELEASE_LOCK_FAILED_MESSAGE = "Failed to release advisory lock".freeze
150
+ DEFAULT_MESSAGE = "Cannot run migrations because another migration process is currently running."
151
+ RELEASE_LOCK_FAILED_MESSAGE = "Failed to release advisory lock"
144
152
 
145
153
  def initialize(message = DEFAULT_MESSAGE)
146
154
  super
@@ -149,7 +157,7 @@ module ActiveRecord
149
157
 
150
158
  class NoEnvironmentInSchemaError < MigrationError #:nodoc:
151
159
  def initialize
152
- msg = "Environment data not found in the schema. To resolve this issue, run: \n\n bin/rails db:environment:set"
160
+ msg = "Environment data not found in the schema. To resolve this issue, run: \n\n rails db:environment:set"
153
161
  if defined?(Rails.env)
154
162
  super("#{msg} RAILS_ENV=#{::Rails.env}")
155
163
  else
@@ -160,7 +168,7 @@ module ActiveRecord
160
168
 
161
169
  class ProtectedEnvironmentError < ActiveRecordError #:nodoc:
162
170
  def initialize(env = "production")
163
- msg = "You are attempting to run a destructive action against your '#{env}' database.\n".dup
171
+ msg = +"You are attempting to run a destructive action against your '#{env}' database.\n"
164
172
  msg << "If you are sure you want to continue, run the same command with the environment variable:\n"
165
173
  msg << "DISABLE_DATABASE_ENVIRONMENT_CHECK=1"
166
174
  super(msg)
@@ -169,10 +177,10 @@ module ActiveRecord
169
177
 
170
178
  class EnvironmentMismatchError < ActiveRecordError
171
179
  def initialize(current: nil, stored: nil)
172
- msg = "You are attempting to modify a database that was last run in `#{ stored }` environment.\n".dup
180
+ msg = +"You are attempting to modify a database that was last run in `#{ stored }` environment.\n"
173
181
  msg << "You are running in `#{ current }` environment. "
174
182
  msg << "If you are sure you want to continue, first set the environment using:\n\n"
175
- msg << " bin/rails db:environment:set"
183
+ msg << " rails db:environment:set"
176
184
  if defined?(Rails.env)
177
185
  super("#{msg} RAILS_ENV=#{::Rails.env}\n\n")
178
186
  else
@@ -307,7 +315,7 @@ module ActiveRecord
307
315
  # named +column_name+ from the table called +table_name+.
308
316
  # * <tt>remove_columns(table_name, *column_names)</tt>: Removes the given
309
317
  # columns from the table definition.
310
- # * <tt>remove_foreign_key(from_table, options_or_to_table)</tt>: Removes the
318
+ # * <tt>remove_foreign_key(from_table, to_table = nil, **options)</tt>: Removes the
311
319
  # given foreign key from the table called +table_name+.
312
320
  # * <tt>remove_index(table_name, column: column_names)</tt>: Removes the index
313
321
  # specified by +column_names+.
@@ -351,7 +359,7 @@ module ActiveRecord
351
359
  # <tt>rails db:migrate</tt>. This will update the database by running all of the
352
360
  # pending migrations, creating the <tt>schema_migrations</tt> table
353
361
  # (see "About the schema_migrations table" section below) if missing. It will also
354
- # invoke the db:schema:dump task, which will update your db/schema.rb file
362
+ # invoke the db:schema:dump command, which will update your db/schema.rb file
355
363
  # to match the structure of your database.
356
364
  #
357
365
  # To roll the database back to a previous migration version, use
@@ -486,9 +494,9 @@ module ActiveRecord
486
494
  # This migration will create the horses table for you on the way up, and
487
495
  # automatically figure out how to drop the table on the way down.
488
496
  #
489
- # Some commands like +remove_column+ cannot be reversed. If you care to
490
- # define how to move up and down in these cases, you should define the +up+
491
- # and +down+ methods as before.
497
+ # Some commands cannot be reversed. If you care to define how to move up
498
+ # and down in these cases, you should define the +up+ and +down+ methods
499
+ # as before.
492
500
  #
493
501
  # If a command cannot be reversed, an
494
502
  # <tt>ActiveRecord::IrreversibleMigration</tt> exception will be raised when
@@ -519,10 +527,10 @@ module ActiveRecord
519
527
  autoload :Compatibility, "active_record/migration/compatibility"
520
528
 
521
529
  # This must be defined before the inherited hook, below
522
- class Current < Migration # :nodoc:
530
+ class Current < Migration #:nodoc:
523
531
  end
524
532
 
525
- def self.inherited(subclass) # :nodoc:
533
+ def self.inherited(subclass) #:nodoc:
526
534
  super
527
535
  if subclass.superclass == Migration
528
536
  raise StandardError, "Directly inheriting from ActiveRecord::Migration is not supported. " \
@@ -540,7 +548,7 @@ module ActiveRecord
540
548
  ActiveRecord::VERSION::STRING.to_f
541
549
  end
542
550
 
543
- MigrationFilenameRegexp = /\A([0-9]+)_([_a-z0-9]*)\.?([_a-z0-9]*)?\.rb\z/ # :nodoc:
551
+ MigrationFilenameRegexp = /\A([0-9]+)_([_a-z0-9]*)\.?([_a-z0-9]*)?\.rb\z/ #:nodoc:
544
552
 
545
553
  # This class is used to verify that all migrations have been run before
546
554
  # loading a web page if <tt>config.active_record.migration_error</tt> is set to :page_load
@@ -567,10 +575,10 @@ module ActiveRecord
567
575
  end
568
576
 
569
577
  class << self
570
- attr_accessor :delegate # :nodoc:
571
- attr_accessor :disable_ddl_transaction # :nodoc:
578
+ attr_accessor :delegate #:nodoc:
579
+ attr_accessor :disable_ddl_transaction #:nodoc:
572
580
 
573
- def nearest_delegate # :nodoc:
581
+ def nearest_delegate #:nodoc:
574
582
  delegate || superclass.nearest_delegate
575
583
  end
576
584
 
@@ -580,27 +588,35 @@ module ActiveRecord
580
588
  end
581
589
 
582
590
  def load_schema_if_pending!
583
- if Base.connection.migration_context.needs_migration? || !Base.connection.migration_context.any_migrations?
591
+ current_config = Base.connection_config
592
+ all_configs = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env)
593
+
594
+ needs_update = !all_configs.all? do |db_config|
595
+ Tasks::DatabaseTasks.schema_up_to_date?(db_config.config, ActiveRecord::Base.schema_format, nil, Rails.env, db_config.spec_name)
596
+ end
597
+
598
+ if needs_update
584
599
  # Roundtrip to Rake to allow plugins to hook into database initialization.
585
600
  root = defined?(ENGINE_ROOT) ? ENGINE_ROOT : Rails.root
586
601
  FileUtils.cd(root) do
587
- current_config = Base.connection_config
588
602
  Base.clear_all_connections!
589
603
  system("bin/rails db:test:prepare")
590
- # Establish a new connection, the old database may be gone (db:test:prepare uses purge)
591
- Base.establish_connection(current_config)
592
604
  end
593
- check_pending!
594
605
  end
606
+
607
+ # Establish a new connection, the old database may be gone (db:test:prepare uses purge)
608
+ Base.establish_connection(current_config)
609
+
610
+ check_pending!
595
611
  end
596
612
 
597
- def maintain_test_schema! # :nodoc:
613
+ def maintain_test_schema! #:nodoc:
598
614
  if ActiveRecord::Base.maintain_test_schema
599
615
  suppress_messages { load_schema_if_pending! }
600
616
  end
601
617
  end
602
618
 
603
- def method_missing(name, *args, &block) # :nodoc:
619
+ def method_missing(name, *args, &block) #:nodoc:
604
620
  nearest_delegate.send(name, *args, &block)
605
621
  end
606
622
 
@@ -617,7 +633,7 @@ module ActiveRecord
617
633
  end
618
634
  end
619
635
 
620
- def disable_ddl_transaction # :nodoc:
636
+ def disable_ddl_transaction #:nodoc:
621
637
  self.class.disable_ddl_transaction
622
638
  end
623
639
 
@@ -677,15 +693,13 @@ module ActiveRecord
677
693
  if connection.respond_to? :revert
678
694
  connection.revert { yield }
679
695
  else
680
- recorder = CommandRecorder.new(connection)
696
+ recorder = command_recorder
681
697
  @connection = recorder
682
698
  suppress_messages do
683
699
  connection.revert { yield }
684
700
  end
685
701
  @connection = recorder.delegate
686
- recorder.commands.each do |cmd, args, block|
687
- send(cmd, *args, &block)
688
- end
702
+ recorder.replay(self)
689
703
  end
690
704
  end
691
705
  end
@@ -694,7 +708,7 @@ module ActiveRecord
694
708
  connection.respond_to?(:reverting) && connection.reverting
695
709
  end
696
710
 
697
- ReversibleBlockHelper = Struct.new(:reverting) do # :nodoc:
711
+ ReversibleBlockHelper = Struct.new(:reverting) do #:nodoc:
698
712
  def up
699
713
  yield unless reverting
700
714
  end
@@ -830,10 +844,14 @@ module ActiveRecord
830
844
  write "== %s %s" % [text, "=" * length]
831
845
  end
832
846
 
847
+ # Takes a message argument and outputs it as is.
848
+ # A second boolean argument can be passed to specify whether to indent or not.
833
849
  def say(message, subitem = false)
834
850
  write "#{subitem ? " ->" : "--"} #{message}"
835
851
  end
836
852
 
853
+ # Outputs text along with how long it took to run its block.
854
+ # If the block returns an integer it assumes it is the number of rows affected.
837
855
  def say_with_time(message)
838
856
  say(message)
839
857
  result = nil
@@ -843,6 +861,7 @@ module ActiveRecord
843
861
  result
844
862
  end
845
863
 
864
+ # Takes a block as an argument and suppresses any output generated by the block.
846
865
  def suppress_messages
847
866
  save, self.verbose = verbose, false
848
867
  yield
@@ -874,18 +893,19 @@ module ActiveRecord
874
893
 
875
894
  def copy(destination, sources, options = {})
876
895
  copied = []
896
+ schema_migration = options[:schema_migration] || ActiveRecord::SchemaMigration
877
897
 
878
898
  FileUtils.mkdir_p(destination) unless File.exist?(destination)
879
899
 
880
- destination_migrations = ActiveRecord::MigrationContext.new(destination).migrations
900
+ destination_migrations = ActiveRecord::MigrationContext.new(destination, schema_migration).migrations
881
901
  last = destination_migrations.last
882
902
  sources.each do |scope, path|
883
- source_migrations = ActiveRecord::MigrationContext.new(path).migrations
903
+ source_migrations = ActiveRecord::MigrationContext.new(path, schema_migration).migrations
884
904
 
885
905
  source_migrations.each do |migration|
886
906
  source = File.binread(migration.filename)
887
907
  inserted_comment = "# This migration comes from #{scope} (originally #{migration.version})\n"
888
- magic_comments = "".dup
908
+ magic_comments = +""
889
909
  loop do
890
910
  # If we have a magic comment in the original migration,
891
911
  # insert our comment after the first newline(end of the magic comment line)
@@ -956,6 +976,10 @@ module ActiveRecord
956
976
  yield
957
977
  end
958
978
  end
979
+
980
+ def command_recorder
981
+ CommandRecorder.new(connection)
982
+ end
959
983
  end
960
984
 
961
985
  # MigrationProxy is used to defer loading of the actual migration classes
@@ -998,11 +1022,12 @@ module ActiveRecord
998
1022
  end
999
1023
  end
1000
1024
 
1001
- class MigrationContext # :nodoc:
1002
- attr_reader :migrations_paths
1025
+ class MigrationContext #:nodoc:
1026
+ attr_reader :migrations_paths, :schema_migration
1003
1027
 
1004
- def initialize(migrations_paths)
1028
+ def initialize(migrations_paths, schema_migration)
1005
1029
  @migrations_paths = migrations_paths
1030
+ @schema_migration = schema_migration
1006
1031
  end
1007
1032
 
1008
1033
  def migrate(target_version = nil, &block)
@@ -1033,7 +1058,7 @@ module ActiveRecord
1033
1058
  migrations
1034
1059
  end
1035
1060
 
1036
- Migrator.new(:up, selected_migrations, target_version).migrate
1061
+ Migrator.new(:up, selected_migrations, schema_migration, target_version).migrate
1037
1062
  end
1038
1063
 
1039
1064
  def down(target_version = nil)
@@ -1043,20 +1068,20 @@ module ActiveRecord
1043
1068
  migrations
1044
1069
  end
1045
1070
 
1046
- Migrator.new(:down, selected_migrations, target_version).migrate
1071
+ Migrator.new(:down, selected_migrations, schema_migration, target_version).migrate
1047
1072
  end
1048
1073
 
1049
1074
  def run(direction, target_version)
1050
- Migrator.new(direction, migrations, target_version).run
1075
+ Migrator.new(direction, migrations, schema_migration, target_version).run
1051
1076
  end
1052
1077
 
1053
1078
  def open
1054
- Migrator.new(:up, migrations, nil)
1079
+ Migrator.new(:up, migrations, schema_migration)
1055
1080
  end
1056
1081
 
1057
1082
  def get_all_versions
1058
- if SchemaMigration.table_exists?
1059
- SchemaMigration.all_versions.map(&:to_i)
1083
+ if schema_migration.table_exists?
1084
+ schema_migration.all_versions.map(&:to_i)
1060
1085
  else
1061
1086
  []
1062
1087
  end
@@ -1079,10 +1104,6 @@ module ActiveRecord
1079
1104
  migrations.last || NullMigration.new
1080
1105
  end
1081
1106
 
1082
- def parse_migration_filename(filename) # :nodoc:
1083
- File.basename(filename).scan(Migration::MigrationFilenameRegexp).first
1084
- end
1085
-
1086
1107
  def migrations
1087
1108
  migrations = migration_files.map do |file|
1088
1109
  version, name, scope = parse_migration_filename(file)
@@ -1097,12 +1118,12 @@ module ActiveRecord
1097
1118
  end
1098
1119
 
1099
1120
  def migrations_status
1100
- db_list = ActiveRecord::SchemaMigration.normalized_versions
1121
+ db_list = schema_migration.normalized_versions
1101
1122
 
1102
1123
  file_list = migration_files.map do |file|
1103
1124
  version, name, scope = parse_migration_filename(file)
1104
1125
  raise IllegalMigrationNameError.new(file) unless version
1105
- version = ActiveRecord::SchemaMigration.normalize_migration_number(version)
1126
+ version = schema_migration.normalize_migration_number(version)
1106
1127
  status = db_list.delete(version) ? "up" : "down"
1107
1128
  [status, version, (name + scope).humanize]
1108
1129
  end.compact
@@ -1114,11 +1135,6 @@ module ActiveRecord
1114
1135
  (db_list + file_list).sort_by { |_, version, _| version }
1115
1136
  end
1116
1137
 
1117
- def migration_files
1118
- paths = Array(migrations_paths)
1119
- Dir[*paths.flat_map { |path| "#{path}/**/[0-9]*_*.rb" }]
1120
- end
1121
-
1122
1138
  def current_environment
1123
1139
  ActiveRecord::ConnectionHandling::DEFAULT_ENV.call
1124
1140
  end
@@ -1137,8 +1153,17 @@ module ActiveRecord
1137
1153
  end
1138
1154
 
1139
1155
  private
1156
+ def migration_files
1157
+ paths = Array(migrations_paths)
1158
+ Dir[*paths.flat_map { |path| "#{path}/**/[0-9]*_*.rb" }]
1159
+ end
1160
+
1161
+ def parse_migration_filename(filename)
1162
+ File.basename(filename).scan(Migration::MigrationFilenameRegexp).first
1163
+ end
1164
+
1140
1165
  def move(direction, steps)
1141
- migrator = Migrator.new(direction, migrations)
1166
+ migrator = Migrator.new(direction, migrations, schema_migration)
1142
1167
 
1143
1168
  if current_version != 0 && !migrator.current_migration
1144
1169
  raise UnknownMigrationVersionError.new(current_version)
@@ -1161,30 +1186,24 @@ module ActiveRecord
1161
1186
  class << self
1162
1187
  attr_accessor :migrations_paths
1163
1188
 
1164
- def migrations_path=(path)
1165
- ActiveSupport::Deprecation.warn \
1166
- "`ActiveRecord::Migrator.migrations_path=` is now deprecated and will be removed in Rails 6.0. " \
1167
- "You can set the `migrations_paths` on the `connection` instead through the `database.yml`."
1168
- self.migrations_paths = [path]
1169
- end
1170
-
1171
1189
  # For cases where a table doesn't exist like loading from schema cache
1172
1190
  def current_version
1173
- MigrationContext.new(migrations_paths).current_version
1191
+ MigrationContext.new(migrations_paths, SchemaMigration).current_version
1174
1192
  end
1175
1193
  end
1176
1194
 
1177
1195
  self.migrations_paths = ["db/migrate"]
1178
1196
 
1179
- def initialize(direction, migrations, target_version = nil)
1197
+ def initialize(direction, migrations, schema_migration, target_version = nil)
1180
1198
  @direction = direction
1181
1199
  @target_version = target_version
1182
1200
  @migrated_versions = nil
1183
1201
  @migrations = migrations
1202
+ @schema_migration = schema_migration
1184
1203
 
1185
1204
  validate(@migrations)
1186
1205
 
1187
- ActiveRecord::SchemaMigration.create_table
1206
+ @schema_migration.create_table
1188
1207
  ActiveRecord::InternalMetadata.create_table
1189
1208
  end
1190
1209
 
@@ -1238,7 +1257,7 @@ module ActiveRecord
1238
1257
  end
1239
1258
 
1240
1259
  def load_migrated
1241
- @migrated_versions = Set.new(Base.connection.migration_context.get_all_versions)
1260
+ @migrated_versions = Set.new(@schema_migration.all_versions.map(&:to_i))
1242
1261
  end
1243
1262
 
1244
1263
  private
@@ -1293,7 +1312,7 @@ module ActiveRecord
1293
1312
  record_version_state_after_migrating(migration.version)
1294
1313
  end
1295
1314
  rescue => e
1296
- msg = "An error has occurred, ".dup
1315
+ msg = +"An error has occurred, "
1297
1316
  msg << "this and " if use_transaction?(migration)
1298
1317
  msg << "all later migrations canceled:\n\n#{e}"
1299
1318
  raise StandardError, msg, e.backtrace
@@ -1322,10 +1341,10 @@ module ActiveRecord
1322
1341
  def record_version_state_after_migrating(version)
1323
1342
  if down?
1324
1343
  migrated.delete(version)
1325
- ActiveRecord::SchemaMigration.where(version: version.to_s).delete_all
1344
+ @schema_migration.delete_by(version: version.to_s)
1326
1345
  else
1327
1346
  migrated << version
1328
- ActiveRecord::SchemaMigration.create!(version: version.to_s)
1347
+ @schema_migration.create!(version: version.to_s)
1329
1348
  end
1330
1349
  end
1331
1350
 
@@ -1351,7 +1370,7 @@ module ActiveRecord
1351
1370
  end
1352
1371
 
1353
1372
  def use_advisory_lock?
1354
- Base.connection.supports_advisory_locks?
1373
+ Base.connection.advisory_locks_enabled?
1355
1374
  end
1356
1375
 
1357
1376
  def with_advisory_lock