activerecord 5.1.5 → 5.2.1

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 +4 -4
  2. data/CHANGELOG.md +450 -699
  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/aggregations.rb +6 -5
  8. data/lib/active_record/association_relation.rb +4 -2
  9. data/lib/active_record/associations/alias_tracker.rb +19 -27
  10. data/lib/active_record/associations/association.rb +33 -37
  11. data/lib/active_record/associations/association_scope.rb +38 -50
  12. data/lib/active_record/associations/belongs_to_association.rb +28 -9
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -8
  14. data/lib/active_record/associations/builder/association.rb +4 -7
  15. data/lib/active_record/associations/builder/belongs_to.rb +14 -5
  16. data/lib/active_record/associations/builder/collection_association.rb +1 -1
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -1
  18. data/lib/active_record/associations/builder/has_many.rb +2 -0
  19. data/lib/active_record/associations/builder/has_one.rb +2 -0
  20. data/lib/active_record/associations/builder/singular_association.rb +2 -0
  21. data/lib/active_record/associations/collection_association.rb +52 -41
  22. data/lib/active_record/associations/collection_proxy.rb +12 -15
  23. data/lib/active_record/associations/foreign_association.rb +2 -0
  24. data/lib/active_record/associations/has_many_association.rb +3 -1
  25. data/lib/active_record/associations/has_many_through_association.rb +8 -19
  26. data/lib/active_record/associations/has_one_association.rb +12 -1
  27. data/lib/active_record/associations/has_one_through_association.rb +13 -8
  28. data/lib/active_record/associations/join_dependency/join_association.rb +22 -67
  29. data/lib/active_record/associations/join_dependency/join_base.rb +9 -8
  30. data/lib/active_record/associations/join_dependency/join_part.rb +9 -9
  31. data/lib/active_record/associations/join_dependency.rb +48 -93
  32. data/lib/active_record/associations/preloader/association.rb +45 -61
  33. data/lib/active_record/associations/preloader/through_association.rb +71 -79
  34. data/lib/active_record/associations/preloader.rb +17 -37
  35. data/lib/active_record/associations/singular_association.rb +14 -16
  36. data/lib/active_record/associations/through_association.rb +26 -11
  37. data/lib/active_record/associations.rb +40 -63
  38. data/lib/active_record/attribute_assignment.rb +2 -5
  39. data/lib/active_record/attribute_decorators.rb +3 -2
  40. data/lib/active_record/attribute_methods/before_type_cast.rb +2 -0
  41. data/lib/active_record/attribute_methods/dirty.rb +25 -214
  42. data/lib/active_record/attribute_methods/primary_key.rb +7 -6
  43. data/lib/active_record/attribute_methods/query.rb +2 -0
  44. data/lib/active_record/attribute_methods/read.rb +9 -3
  45. data/lib/active_record/attribute_methods/serialization.rb +23 -0
  46. data/lib/active_record/attribute_methods/time_zone_conversion.rb +6 -8
  47. data/lib/active_record/attribute_methods/write.rb +21 -9
  48. data/lib/active_record/attribute_methods.rb +65 -24
  49. data/lib/active_record/attributes.rb +7 -6
  50. data/lib/active_record/autosave_association.rb +16 -14
  51. data/lib/active_record/base.rb +2 -0
  52. data/lib/active_record/callbacks.rb +12 -6
  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 +11 -7
  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 +157 -29
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +7 -2
  60. data/lib/active_record/connection_adapters/abstract/quoting.rb +15 -32
  61. data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
  62. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +14 -5
  63. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +64 -6
  64. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +31 -53
  65. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +149 -78
  66. data/lib/active_record/connection_adapters/abstract/transaction.rb +66 -21
  67. data/lib/active_record/connection_adapters/abstract_adapter.rb +81 -96
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +92 -165
  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 +47 -2
  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 -10
  78. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +30 -30
  79. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +106 -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/array.rb +6 -0
  86. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +2 -0
  87. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +2 -0
  90. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -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 +8 -2
  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/oid.rb +3 -1
  108. data/lib/active_record/connection_adapters/postgresql/quoting.rb +18 -0
  109. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
  110. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +14 -0
  111. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +24 -11
  112. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +20 -13
  113. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +248 -112
  114. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +2 -0
  115. data/lib/active_record/connection_adapters/postgresql/utils.rb +2 -0
  116. data/lib/active_record/connection_adapters/postgresql_adapter.rb +57 -73
  117. data/lib/active_record/connection_adapters/schema_cache.rb +4 -2
  118. data/lib/active_record/connection_adapters/sql_type_metadata.rb +2 -0
  119. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +2 -0
  120. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +20 -1
  121. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +2 -0
  122. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +6 -15
  123. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +3 -2
  124. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +75 -1
  125. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +79 -92
  126. data/lib/active_record/connection_adapters/statement_pool.rb +2 -0
  127. data/lib/active_record/connection_handling.rb +4 -2
  128. data/lib/active_record/core.rb +39 -60
  129. data/lib/active_record/counter_cache.rb +20 -15
  130. data/lib/active_record/define_callbacks.rb +5 -3
  131. data/lib/active_record/dynamic_matchers.rb +9 -9
  132. data/lib/active_record/enum.rb +17 -13
  133. data/lib/active_record/errors.rb +42 -3
  134. data/lib/active_record/explain.rb +3 -1
  135. data/lib/active_record/explain_registry.rb +2 -0
  136. data/lib/active_record/explain_subscriber.rb +2 -0
  137. data/lib/active_record/fixture_set/file.rb +2 -0
  138. data/lib/active_record/fixtures.rb +67 -60
  139. data/lib/active_record/gem_version.rb +4 -2
  140. data/lib/active_record/inheritance.rb +49 -19
  141. data/lib/active_record/integration.rb +58 -19
  142. data/lib/active_record/internal_metadata.rb +2 -0
  143. data/lib/active_record/legacy_yaml_adapter.rb +3 -1
  144. data/lib/active_record/locking/optimistic.rb +30 -42
  145. data/lib/active_record/locking/pessimistic.rb +9 -6
  146. data/lib/active_record/log_subscriber.rb +43 -0
  147. data/lib/active_record/migration/command_recorder.rb +11 -9
  148. data/lib/active_record/migration/compatibility.rb +40 -2
  149. data/lib/active_record/migration/join_table.rb +2 -0
  150. data/lib/active_record/migration.rb +189 -139
  151. data/lib/active_record/model_schema.rb +19 -24
  152. data/lib/active_record/nested_attributes.rb +18 -6
  153. data/lib/active_record/no_touching.rb +3 -1
  154. data/lib/active_record/null_relation.rb +2 -0
  155. data/lib/active_record/persistence.rb +196 -48
  156. data/lib/active_record/query_cache.rb +12 -14
  157. data/lib/active_record/querying.rb +3 -1
  158. data/lib/active_record/railtie.rb +61 -3
  159. data/lib/active_record/railties/console_sandbox.rb +2 -0
  160. data/lib/active_record/railties/controller_runtime.rb +2 -0
  161. data/lib/active_record/railties/databases.rake +46 -36
  162. data/lib/active_record/readonly_attributes.rb +3 -2
  163. data/lib/active_record/reflection.rb +110 -192
  164. data/lib/active_record/relation/batches/batch_enumerator.rb +2 -0
  165. data/lib/active_record/relation/batches.rb +20 -5
  166. data/lib/active_record/relation/calculations.rb +31 -9
  167. data/lib/active_record/relation/delegation.rb +15 -27
  168. data/lib/active_record/relation/finder_methods.rb +71 -76
  169. data/lib/active_record/relation/from_clause.rb +2 -8
  170. data/lib/active_record/relation/merger.rb +47 -20
  171. data/lib/active_record/relation/predicate_builder/array_handler.rb +10 -7
  172. data/lib/active_record/relation/predicate_builder/association_query_value.rb +46 -0
  173. data/lib/active_record/relation/predicate_builder/base_handler.rb +2 -2
  174. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +12 -1
  175. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +56 -0
  176. data/lib/active_record/relation/predicate_builder/range_handler.rb +26 -9
  177. data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
  178. data/lib/active_record/relation/predicate_builder.rb +55 -79
  179. data/lib/active_record/relation/query_attribute.rb +26 -2
  180. data/lib/active_record/relation/query_methods.rb +95 -91
  181. data/lib/active_record/relation/record_fetch_warning.rb +2 -0
  182. data/lib/active_record/relation/spawn_methods.rb +3 -1
  183. data/lib/active_record/relation/where_clause.rb +65 -68
  184. data/lib/active_record/relation/where_clause_factory.rb +5 -48
  185. data/lib/active_record/relation.rb +106 -219
  186. data/lib/active_record/result.rb +2 -0
  187. data/lib/active_record/runtime_registry.rb +2 -0
  188. data/lib/active_record/sanitization.rb +129 -121
  189. data/lib/active_record/schema.rb +4 -2
  190. data/lib/active_record/schema_dumper.rb +36 -26
  191. data/lib/active_record/schema_migration.rb +2 -0
  192. data/lib/active_record/scoping/default.rb +6 -7
  193. data/lib/active_record/scoping/named.rb +21 -7
  194. data/lib/active_record/scoping.rb +9 -8
  195. data/lib/active_record/secure_token.rb +2 -0
  196. data/lib/active_record/serialization.rb +2 -0
  197. data/lib/active_record/statement_cache.rb +22 -12
  198. data/lib/active_record/store.rb +3 -1
  199. data/lib/active_record/suppressor.rb +2 -0
  200. data/lib/active_record/table_metadata.rb +12 -3
  201. data/lib/active_record/tasks/database_tasks.rb +25 -14
  202. data/lib/active_record/tasks/mysql_database_tasks.rb +9 -48
  203. data/lib/active_record/tasks/postgresql_database_tasks.rb +10 -2
  204. data/lib/active_record/tasks/sqlite_database_tasks.rb +25 -3
  205. data/lib/active_record/timestamp.rb +13 -6
  206. data/lib/active_record/touch_later.rb +2 -0
  207. data/lib/active_record/transactions.rb +32 -27
  208. data/lib/active_record/translation.rb +2 -0
  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 +6 -0
  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.rb +4 -1
  222. data/lib/active_record/type_caster/connection.rb +2 -0
  223. data/lib/active_record/type_caster/map.rb +3 -1
  224. data/lib/active_record/type_caster.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/validations.rb +2 -0
  231. data/lib/active_record/version.rb +2 -0
  232. data/lib/active_record.rb +11 -4
  233. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
  234. data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -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/migration.rb +2 -0
  239. data/lib/rails/generators/active_record/model/model_generator.rb +2 -23
  240. data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +0 -0
  241. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  242. data/lib/rails/generators/active_record.rb +3 -1
  243. metadata +23 -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/user_provided_default.rb +0 -30
  252. data/lib/active_record/attribute.rb +0 -240
  253. data/lib/active_record/attribute_mutation_tracker.rb +0 -114
  254. data/lib/active_record/attribute_set/builder.rb +0 -124
  255. data/lib/active_record/attribute_set/yaml_encoder.rb +0 -41
  256. data/lib/active_record/attribute_set.rb +0 -113
  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 -37
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  # Statement cache is used to cache a single statement in order to avoid creating the AST again.
3
5
  # Initializing the cache is done by passing the statement in the create block:
@@ -9,7 +11,7 @@ module ActiveRecord
9
11
  # The cached statement is executed by using the
10
12
  # {connection.execute}[rdoc-ref:ConnectionAdapters::DatabaseStatements#execute] method:
11
13
  #
12
- # cache.execute([], Book, Book.connection)
14
+ # cache.execute([], Book.connection)
13
15
  #
14
16
  # The relation returned by the block is cached, and for each
15
17
  # {execute}[rdoc-ref:ConnectionAdapters::DatabaseStatements#execute]
@@ -24,7 +26,7 @@ module ActiveRecord
24
26
  #
25
27
  # And pass the bind values as the first argument of +execute+ call.
26
28
  #
27
- # cache.execute(["my book"], Book, Book.connection)
29
+ # cache.execute(["my book"], Book.connection)
28
30
  class StatementCache # :nodoc:
29
31
  class Substitute; end # :nodoc:
30
32
 
@@ -85,27 +87,35 @@ module ActiveRecord
85
87
  end
86
88
  end
87
89
 
88
- attr_reader :bind_map, :query_builder
89
-
90
90
  def self.create(connection, block = Proc.new)
91
- relation = block.call Params.new
92
- bind_map = BindMap.new relation.bound_attributes
93
- query_builder = connection.cacheable_query(self, relation.arel)
94
- new query_builder, bind_map
91
+ relation = block.call Params.new
92
+ query_builder, binds = connection.cacheable_query(self, relation.arel)
93
+ bind_map = BindMap.new(binds)
94
+ new(query_builder, bind_map, relation.klass)
95
95
  end
96
96
 
97
- def initialize(query_builder, bind_map)
97
+ def initialize(query_builder, bind_map, klass)
98
98
  @query_builder = query_builder
99
- @bind_map = bind_map
99
+ @bind_map = bind_map
100
+ @klass = klass
100
101
  end
101
102
 
102
- def execute(params, klass, connection, &block)
103
+ def execute(params, connection, &block)
103
104
  bind_values = bind_map.bind params
104
105
 
105
106
  sql = query_builder.sql_for bind_values, connection
106
107
 
107
108
  klass.find_by_sql(sql, bind_values, preparable: true, &block)
108
109
  end
109
- alias :call :execute
110
+
111
+ def self.unsupported_value?(value)
112
+ case value
113
+ when NilClass, Array, Range, Hash, Relation, Base then true
114
+ end
115
+ end
116
+
117
+ protected
118
+
119
+ attr_reader :query_builder, :bind_map, :klass
110
120
  end
111
121
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/hash/indifferent_access"
2
4
 
3
5
  module ActiveRecord
@@ -133,7 +135,7 @@ module ActiveRecord
133
135
  end
134
136
 
135
137
  def store_accessor_for(store_attribute)
136
- type_for_attribute(store_attribute.to_s).accessor
138
+ type_for_attribute(store_attribute).accessor
137
139
  end
138
140
 
139
141
  class HashAccessor # :nodoc:
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  # ActiveRecord::Suppressor prevents the receiver from being saved during
3
5
  # a given block.
@@ -1,7 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  class TableMetadata # :nodoc:
3
- delegate :foreign_type, :foreign_key, to: :association, prefix: true
4
- delegate :association_primary_key, to: :association
5
+ delegate :foreign_type, :foreign_key, :join_primary_key, :join_foreign_key, to: :association, prefix: true
5
6
 
6
7
  def initialize(klass, arel_table, association = nil)
7
8
  @klass = klass
@@ -29,7 +30,7 @@ module ActiveRecord
29
30
 
30
31
  def type(column_name)
31
32
  if klass
32
- klass.type_for_attribute(column_name.to_s)
33
+ klass.type_for_attribute(column_name)
33
34
  else
34
35
  Type.default_value
35
36
  end
@@ -64,6 +65,14 @@ module ActiveRecord
64
65
  association && association.polymorphic?
65
66
  end
66
67
 
68
+ def aggregated_with?(aggregation_name)
69
+ klass && reflect_on_aggregation(aggregation_name)
70
+ end
71
+
72
+ def reflect_on_aggregation(aggregation_name)
73
+ klass.reflect_on_aggregation(aggregation_name)
74
+ end
75
+
67
76
  # TODO Change this to private once we've dropped Ruby 2.2 support.
68
77
  # Workaround for Ruby 2.2 "private attribute?" warning.
69
78
  protected
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module Tasks # :nodoc:
3
5
  class DatabaseAlreadyExists < StandardError; end # :nodoc:
@@ -52,10 +54,10 @@ module ActiveRecord
52
54
 
53
55
  def check_protected_environments!
54
56
  unless ENV["DISABLE_DATABASE_ENVIRONMENT_CHECK"]
55
- current = ActiveRecord::Migrator.current_environment
56
- stored = ActiveRecord::Migrator.last_stored_environment
57
+ current = ActiveRecord::Base.connection.migration_context.current_environment
58
+ stored = ActiveRecord::Base.connection.migration_context.last_stored_environment
57
59
 
58
- if ActiveRecord::Migrator.protected_environment?
60
+ if ActiveRecord::Base.connection.migration_context.protected_environment?
59
61
  raise ActiveRecord::ProtectedEnvironmentError.new(stored)
60
62
  end
61
63
 
@@ -71,9 +73,9 @@ module ActiveRecord
71
73
  @tasks[pattern] = task
72
74
  end
73
75
 
74
- register_task(/mysql/, ActiveRecord::Tasks::MySQLDatabaseTasks)
75
- register_task(/postgresql/, ActiveRecord::Tasks::PostgreSQLDatabaseTasks)
76
- register_task(/sqlite/, ActiveRecord::Tasks::SQLiteDatabaseTasks)
76
+ register_task(/mysql/, "ActiveRecord::Tasks::MySQLDatabaseTasks")
77
+ register_task(/postgresql/, "ActiveRecord::Tasks::PostgreSQLDatabaseTasks")
78
+ register_task(/sqlite/, "ActiveRecord::Tasks::SQLiteDatabaseTasks")
77
79
 
78
80
  def db_dir
79
81
  @db_dir ||= Rails.application.config.paths["db"].first
@@ -162,13 +164,12 @@ module ActiveRecord
162
164
  end
163
165
 
164
166
  def migrate
165
- raise "Empty VERSION provided" if ENV["VERSION"] && ENV["VERSION"].empty?
167
+ check_target_version
166
168
 
167
- verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true
168
- version = ENV["VERSION"] ? ENV["VERSION"].to_i : nil
169
+ verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] != "false" : true
169
170
  scope = ENV["SCOPE"]
170
171
  verbose_was, Migration.verbose = Migration.verbose, verbose
171
- Migrator.migrate(migrations_paths, version) do |migration|
172
+ Base.connection.migration_context.migrate(target_version) do |migration|
172
173
  scope.blank? || scope == migration.scope
173
174
  end
174
175
  ActiveRecord::Base.clear_cache!
@@ -176,6 +177,16 @@ module ActiveRecord
176
177
  Migration.verbose = verbose_was
177
178
  end
178
179
 
180
+ def check_target_version
181
+ if target_version && !(Migration::MigrationFilenameRegexp.match?(ENV["VERSION"]) || /\A\d+\z/.match?(ENV["VERSION"]))
182
+ raise "Invalid format of target version: `VERSION=#{ENV['VERSION']}`"
183
+ end
184
+ end
185
+
186
+ def target_version
187
+ ENV["VERSION"].to_i if ENV["VERSION"] && !ENV["VERSION"].empty?
188
+ end
189
+
179
190
  def charset_current(environment = env)
180
191
  charset ActiveRecord::Base.configurations[environment]
181
192
  end
@@ -259,7 +270,7 @@ module ActiveRecord
259
270
 
260
271
  def check_schema_file(filename)
261
272
  unless File.exist?(filename)
262
- message = %{#{filename} doesn't exist yet. Run `rails db:migrate` to create it, then try again.}
273
+ message = %{#{filename} doesn't exist yet. Run `rails db:migrate` to create it, then try again.}.dup
263
274
  message << %{ If you do not intend to use a database, you should instead alter #{Rails.root}/config/application.rb to limit the frameworks that will be loaded.} if defined?(::Rails.root)
264
275
  Kernel.abort message
265
276
  end
@@ -288,11 +299,11 @@ module ActiveRecord
288
299
  private
289
300
 
290
301
  def class_for_adapter(adapter)
291
- key = @tasks.keys.detect { |pattern| adapter[pattern] }
292
- unless key
302
+ _key, task = @tasks.each_pair.detect { |pattern, _task| adapter[pattern] }
303
+ unless task
293
304
  raise DatabaseNotSupported, "Rake tasks not supported by '#{adapter}' adapter"
294
305
  end
295
- @tasks[key]
306
+ task.is_a?(String) ? task.constantize : task
296
307
  end
297
308
 
298
309
  def each_current_configuration(environment)
@@ -1,8 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module Tasks # :nodoc:
3
5
  class MySQLDatabaseTasks # :nodoc:
4
- ACCESS_DENIED_ERROR = 1045
5
-
6
6
  delegate :connection, :establish_connection, to: ActiveRecord::Base
7
7
 
8
8
  def initialize(configuration)
@@ -19,20 +19,6 @@ module ActiveRecord
19
19
  else
20
20
  raise
21
21
  end
22
- rescue error_class => error
23
- if error.respond_to?(:errno) && error.errno == ACCESS_DENIED_ERROR
24
- $stdout.print error.message
25
- establish_connection root_configuration_without_database
26
- connection.create_database configuration["database"], creation_options
27
- if configuration["username"] != "root"
28
- connection.execute grant_statement.gsub(/\s+/, " ").strip
29
- end
30
- establish_connection configuration
31
- else
32
- $stderr.puts error.inspect
33
- $stderr.puts "Couldn't create database for #{configuration.inspect}, #{creation_options.inspect}"
34
- $stderr.puts "(If you set the charset manually, make sure you have a matching collation)" if configuration["encoding"]
35
- end
36
22
  end
37
23
 
38
24
  def drop
@@ -59,6 +45,12 @@ module ActiveRecord
59
45
  args.concat(["--no-data"])
60
46
  args.concat(["--routines"])
61
47
  args.concat(["--skip-comments"])
48
+
49
+ ignore_tables = ActiveRecord::SchemaDumper.ignore_tables
50
+ if ignore_tables.any?
51
+ args += ignore_tables.map { |table| "--ignore-table=#{configuration['database']}.#{table}" }
52
+ end
53
+
62
54
  args.concat(["#{configuration['database']}"])
63
55
  args.unshift(*extra_flags) if extra_flags
64
56
 
@@ -91,37 +83,6 @@ module ActiveRecord
91
83
  end
92
84
  end
93
85
 
94
- def error_class
95
- if configuration["adapter"].include?("jdbc")
96
- require "active_record/railties/jdbcmysql_error"
97
- ArJdbcMySQL::Error
98
- elsif defined?(Mysql2)
99
- Mysql2::Error
100
- else
101
- StandardError
102
- end
103
- end
104
-
105
- def grant_statement
106
- <<-SQL
107
- GRANT ALL PRIVILEGES ON `#{configuration['database']}`.*
108
- TO '#{configuration['username']}'@'localhost'
109
- IDENTIFIED BY '#{configuration['password']}' WITH GRANT OPTION;
110
- SQL
111
- end
112
-
113
- def root_configuration_without_database
114
- configuration_without_database.merge(
115
- "username" => "root",
116
- "password" => root_password
117
- )
118
- end
119
-
120
- def root_password
121
- $stdout.print "Please provide the root password for your MySQL installation\n>"
122
- $stdin.gets.strip
123
- end
124
-
125
86
  def prepare_command_options
126
87
  args = {
127
88
  "host" => "--host",
@@ -145,7 +106,7 @@ IDENTIFIED BY '#{configuration['password']}' WITH GRANT OPTION;
145
106
  end
146
107
 
147
108
  def run_cmd_error(cmd, args, action)
148
- msg = "failed to execute: `#{cmd}`\n"
109
+ msg = "failed to execute: `#{cmd}`\n".dup
149
110
  msg << "Please check the output above for any errors and make sure that `#{cmd}` is installed in your PATH and has proper permissions.\n\n"
150
111
  msg
151
112
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "tempfile"
2
4
 
3
5
  module ActiveRecord
@@ -66,6 +68,12 @@ module ActiveRecord
66
68
  "--schema=#{part.strip}"
67
69
  end
68
70
  end
71
+
72
+ ignore_tables = ActiveRecord::SchemaDumper.ignore_tables
73
+ if ignore_tables.any?
74
+ args += ignore_tables.flat_map { |table| ["-T", table] }
75
+ end
76
+
69
77
  args << configuration["database"]
70
78
  run_cmd("pg_dump", args, "dumping")
71
79
  remove_sql_header_comments(filename)
@@ -109,7 +117,7 @@ module ActiveRecord
109
117
  end
110
118
 
111
119
  def run_cmd_error(cmd, args, action)
112
- msg = "failed to execute:\n"
120
+ msg = "failed to execute:\n".dup
113
121
  msg << "#{cmd} #{args.join(' ')}\n\n"
114
122
  msg << "Please check the output above for any errors and make sure that `#{cmd}` is installed in your PATH and has proper permissions.\n\n"
115
123
  msg
@@ -128,7 +136,7 @@ module ActiveRecord
128
136
  ensure
129
137
  tempfile.close
130
138
  end
131
- FileUtils.mv(tempfile.path, filename)
139
+ FileUtils.cp(tempfile.path, filename)
132
140
  end
133
141
  end
134
142
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module Tasks # :nodoc:
3
5
  class SQLiteDatabaseTasks # :nodoc:
@@ -36,9 +38,18 @@ module ActiveRecord
36
38
  end
37
39
 
38
40
  def structure_dump(filename, extra_flags)
39
- dbfile = configuration["database"]
40
- flags = extra_flags.join(" ") if extra_flags
41
- `sqlite3 #{flags} #{dbfile} .schema > #{filename}`
41
+ args = []
42
+ args.concat(Array(extra_flags)) if extra_flags
43
+ args << configuration["database"]
44
+
45
+ ignore_tables = ActiveRecord::SchemaDumper.ignore_tables
46
+ if ignore_tables.any?
47
+ condition = ignore_tables.map { |table| connection.quote(table) }.join(", ")
48
+ args << "SELECT sql FROM sqlite_master WHERE tbl_name NOT IN (#{condition}) ORDER BY tbl_name, type DESC, name"
49
+ else
50
+ args << ".schema"
51
+ end
52
+ run_cmd("sqlite3", args, filename)
42
53
  end
43
54
 
44
55
  def structure_load(filename, extra_flags)
@@ -56,6 +67,17 @@ module ActiveRecord
56
67
  def root
57
68
  @root
58
69
  end
70
+
71
+ def run_cmd(cmd, args, out)
72
+ fail run_cmd_error(cmd, args) unless Kernel.system(cmd, *args, out: out)
73
+ end
74
+
75
+ def run_cmd_error(cmd, args)
76
+ msg = "failed to execute:\n".dup
77
+ msg << "#{cmd} #{args.join(' ')}\n\n"
78
+ msg << "Please check the output above for any errors and make sure that `#{cmd}` is installed in your PATH and has proper permissions.\n\n"
79
+ msg
80
+ end
59
81
  end
60
82
  end
61
83
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module ActiveRecord
3
4
  # = Active Record \Timestamp
4
5
  #
@@ -43,8 +44,7 @@ module ActiveRecord
43
44
  extend ActiveSupport::Concern
44
45
 
45
46
  included do
46
- class_attribute :record_timestamps
47
- self.record_timestamps = true
47
+ class_attribute :record_timestamps, default: true
48
48
  end
49
49
 
50
50
  def initialize_dup(other) # :nodoc:
@@ -52,7 +52,14 @@ module ActiveRecord
52
52
  clear_timestamp_attributes
53
53
  end
54
54
 
55
- class_methods do
55
+ module ClassMethods # :nodoc:
56
+ def touch_attributes_with_time(*names, time: nil)
57
+ attribute_names = timestamp_attributes_for_update_in_model
58
+ attribute_names |= names.map(&:to_s)
59
+ time ||= current_time_from_proper_timezone
60
+ attribute_names.each_with_object({}) { |attr_name, result| result[attr_name] = time }
61
+ end
62
+
56
63
  private
57
64
  def timestamp_attributes_for_create_in_model
58
65
  timestamp_attributes_for_create.select { |c| column_names.include?(c) }
@@ -87,7 +94,7 @@ module ActiveRecord
87
94
 
88
95
  all_timestamp_attributes_in_model.each do |column|
89
96
  if !attribute_present?(column)
90
- write_attribute(column, current_time)
97
+ _write_attribute(column, current_time)
91
98
  end
92
99
  end
93
100
  end
@@ -101,7 +108,7 @@ module ActiveRecord
101
108
 
102
109
  timestamp_attributes_for_update_in_model.each do |column|
103
110
  next if will_save_change_to_attribute?(column)
104
- write_attribute(column, current_time)
111
+ _write_attribute(column, current_time)
105
112
  end
106
113
  end
107
114
  super(*args)
@@ -127,7 +134,7 @@ module ActiveRecord
127
134
  self.class.send(:current_time_from_proper_timezone)
128
135
  end
129
136
 
130
- def max_updated_column_timestamp(timestamp_names = self.class.send(:timestamp_attributes_for_update))
137
+ def max_updated_column_timestamp(timestamp_names = timestamp_attributes_for_update_in_model)
131
138
  timestamp_names
132
139
  .map { |attr| self[attr] }
133
140
  .compact
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  # = Active Record Touch Later
3
5
  module TouchLater
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  # See ActiveRecord::Transactions::ClassMethods for documentation.
3
5
  module Transactions
@@ -168,7 +170,7 @@ module ActiveRecord
168
170
  # writing, the only database that we're aware of that supports true nested
169
171
  # transactions, is MS-SQL. Because of this, Active Record emulates nested
170
172
  # transactions by using savepoints on MySQL and PostgreSQL. See
171
- # http://dev.mysql.com/doc/refman/5.7/en/savepoint.html
173
+ # https://dev.mysql.com/doc/refman/5.7/en/savepoint.html
172
174
  # for more information about savepoints.
173
175
  #
174
176
  # === \Callbacks
@@ -188,7 +190,7 @@ module ActiveRecord
188
190
  #
189
191
  # === Caveats
190
192
  #
191
- # If you're on MySQL, then do not use Data Definition Language(DDL) operations in nested
193
+ # If you're on MySQL, then do not use Data Definition Language (DDL) operations in nested
192
194
  # transactions blocks that are emulated with savepoints. That is, do not execute statements
193
195
  # like 'CREATE TABLE' inside such blocks. This is because MySQL automatically
194
196
  # releases all savepoints upon executing a DDL operation. When +transaction+
@@ -283,7 +285,7 @@ module ActiveRecord
283
285
  fire_on = Array(options[:on])
284
286
  assert_valid_transaction_action(fire_on)
285
287
  options[:if] = Array(options[:if])
286
- options[:if].unshift("transaction_include_any_action?(#{fire_on})")
288
+ options[:if].unshift(-> { transaction_include_any_action?(fire_on) })
287
289
  end
288
290
  end
289
291
 
@@ -338,11 +340,13 @@ module ActiveRecord
338
340
  # Ensure that it is not called if the object was never persisted (failed create),
339
341
  # but call it after the commit of a destroyed object.
340
342
  def committed!(should_run_callbacks: true) #:nodoc:
341
- if should_run_callbacks && destroyed? || persisted?
343
+ if should_run_callbacks && (destroyed? || persisted?)
344
+ @_committed_already_called = true
342
345
  _run_commit_without_transaction_enrollment_callbacks
343
346
  _run_commit_callbacks
344
347
  end
345
348
  ensure
349
+ @_committed_already_called = false
346
350
  force_clear_transaction_record_state
347
351
  end
348
352
 
@@ -380,13 +384,7 @@ module ActiveRecord
380
384
  status = nil
381
385
  self.class.transaction do
382
386
  add_to_transaction
383
- begin
384
- status = yield
385
- rescue ActiveRecord::Rollback
386
- clear_transaction_record_state
387
- status = nil
388
- end
389
-
387
+ status = yield
390
388
  raise ActiveRecord::Rollback unless status
391
389
  end
392
390
  status
@@ -396,17 +394,29 @@ module ActiveRecord
396
394
  end
397
395
  end
398
396
 
397
+ protected
398
+ attr_reader :_committed_already_called, :_trigger_update_callback, :_trigger_destroy_callback
399
+
399
400
  private
400
401
 
401
402
  # Save the new record state and id of a record so it can be restored later if a transaction fails.
402
403
  def remember_transaction_record_state
403
- @_start_transaction_state[:id] = id
404
404
  @_start_transaction_state.reverse_merge!(
405
+ id: id,
405
406
  new_record: @new_record,
406
407
  destroyed: @destroyed,
407
408
  frozen?: frozen?,
408
409
  )
409
410
  @_start_transaction_state[:level] = (@_start_transaction_state[:level] || 0) + 1
411
+ remember_new_record_before_last_commit
412
+ end
413
+
414
+ def remember_new_record_before_last_commit
415
+ if _committed_already_called
416
+ @_new_record_before_last_commit = false
417
+ else
418
+ @_new_record_before_last_commit = @_start_transaction_state[:new_record]
419
+ end
410
420
  end
411
421
 
412
422
  # Clear the new record state and id of a record.
@@ -430,30 +440,24 @@ module ActiveRecord
430
440
  @new_record = restore_state[:new_record]
431
441
  @destroyed = restore_state[:destroyed]
432
442
  pk = self.class.primary_key
433
- if pk && read_attribute(pk) != restore_state[:id]
434
- write_attribute(pk, restore_state[:id])
443
+ if pk && _read_attribute(pk) != restore_state[:id]
444
+ _write_attribute(pk, restore_state[:id])
435
445
  end
436
446
  freeze if restore_state[:frozen?]
437
447
  end
438
448
  end
439
449
  end
440
450
 
441
- # Determine if a record was created or destroyed in a transaction. State should be one of :new_record or :destroyed.
442
- def transaction_record_state(state)
443
- @_start_transaction_state[state]
444
- end
445
-
446
451
  # Determine if a transaction included an action for :create, :update, or :destroy. Used in filtering callbacks.
447
452
  def transaction_include_any_action?(actions)
448
453
  actions.any? do |action|
449
454
  case action
450
455
  when :create
451
- transaction_record_state(:new_record)
452
- when :destroy
453
- defined?(@_trigger_destroy_callback) && @_trigger_destroy_callback
456
+ persisted? && @_new_record_before_last_commit
454
457
  when :update
455
- !(transaction_record_state(:new_record) || destroyed?) &&
456
- (defined?(@_trigger_update_callback) && @_trigger_update_callback)
458
+ !(@_new_record_before_last_commit || destroyed?) && _trigger_update_callback
459
+ when :destroy
460
+ _trigger_destroy_callback
457
461
  end
458
462
  end
459
463
  end
@@ -470,7 +474,7 @@ module ActiveRecord
470
474
  # if it's associated with a transaction, then the state of the Active Record
471
475
  # object will be updated to reflect the current state of the transaction.
472
476
  #
473
- # The +@transaction_state+ variable stores the states of the associated
477
+ # The <tt>@transaction_state</tt> variable stores the states of the associated
474
478
  # transaction. This relies on the fact that a transaction can only be in
475
479
  # one rollback or commit (otherwise a list of states would be required).
476
480
  # Each Active Record object inside of a transaction carries that transaction's
@@ -489,8 +493,9 @@ module ActiveRecord
489
493
 
490
494
  def update_attributes_from_transaction_state(transaction_state)
491
495
  if transaction_state && transaction_state.finalized?
492
- restore_transaction_record_state if transaction_state.rolledback?
493
- clear_transaction_record_state
496
+ restore_transaction_record_state(transaction_state.fully_rolledback?) if transaction_state.rolledback?
497
+ force_clear_transaction_record_state if transaction_state.fully_committed?
498
+ clear_transaction_record_state if transaction_state.fully_completed?
494
499
  end
495
500
  end
496
501
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module Translation
3
5
  include ActiveModel::Translation
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_model/type/registry"
2
4
 
3
5
  module ActiveRecord
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module Type
3
5
  class Date < ActiveModel::Type::Date
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module Type
3
5
  class DateTime < ActiveModel::Type::DateTime
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module Type
3
5
  class DecimalWithoutScale < ActiveModel::Type::BigInteger # :nodoc:
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module Type
3
5
  class HashLookupTypeMap < TypeMap # :nodoc:
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module Type
3
5
  module Internal