activerecord 5.1.7 → 5.2.0

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 +372 -765
  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 +16 -27
  11. data/lib/active_record/associations/association_scope.rb +38 -50
  12. data/lib/active_record/associations/belongs_to_association.rb +20 -10
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +4 -7
  14. data/lib/active_record/associations/builder/association.rb +4 -7
  15. data/lib/active_record/associations/builder/belongs_to.rb +4 -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 +43 -35
  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 +7 -18
  26. data/lib/active_record/associations/has_one_association.rb +4 -1
  27. data/lib/active_record/associations/has_one_through_association.rb +8 -7
  28. data/lib/active_record/associations/join_dependency/join_association.rb +17 -56
  29. data/lib/active_record/associations/join_dependency/join_base.rb +9 -8
  30. data/lib/active_record/associations/join_dependency/join_part.rb +2 -9
  31. data/lib/active_record/associations/join_dependency.rb +23 -43
  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 -10
  36. data/lib/active_record/associations/through_association.rb +25 -10
  37. data/lib/active_record/associations.rb +31 -54
  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 +8 -2
  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 +6 -5
  50. data/lib/active_record/autosave_association.rb +8 -11
  51. data/lib/active_record/base.rb +2 -0
  52. data/lib/active_record/callbacks.rb +8 -10
  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 +111 -38
  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 +13 -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 +57 -2
  64. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +31 -53
  65. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +158 -78
  66. data/lib/active_record/connection_adapters/abstract/transaction.rb +45 -9
  67. data/lib/active_record/connection_adapters/abstract_adapter.rb +81 -96
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +111 -183
  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 +11 -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 +3 -11
  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 +2 -0
  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 +4 -6
  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 +246 -110
  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 +58 -82
  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 +18 -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 +71 -1
  125. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +80 -90
  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 +15 -12
  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 +54 -21
  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 +14 -17
  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 +16 -21
  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 +166 -16
  156. data/lib/active_record/query_cache.rb +11 -6
  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 +30 -8
  167. data/lib/active_record/relation/delegation.rb +15 -27
  168. data/lib/active_record/relation/finder_methods.rb +75 -78
  169. data/lib/active_record/relation/from_clause.rb +2 -8
  170. data/lib/active_record/relation/merger.rb +51 -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 +53 -78
  179. data/lib/active_record/relation/query_attribute.rb +26 -2
  180. data/lib/active_record/relation/query_methods.rb +89 -88
  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 +95 -208
  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 +26 -15
  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 +5 -12
  206. data/lib/active_record/touch_later.rb +2 -0
  207. data/lib/active_record/transactions.rb +9 -7
  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 +2 -4
  217. data/lib/active_record/type/text.rb +2 -0
  218. data/lib/active_record/type/time.rb +2 -0
  219. data/lib/active_record/type/type_map.rb +2 -0
  220. data/lib/active_record/type/unsigned_integer.rb +2 -0
  221. data/lib/active_record/type.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 +35 -5
  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 +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/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 -122
  254. data/lib/active_record/attribute_set/builder.rb +0 -126
  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
@@ -120,7 +122,7 @@ module ActiveRecord
120
122
  $stderr.puts "Database '#{configuration['database']}' already exists"
121
123
  rescue Exception => error
122
124
  $stderr.puts error
123
- $stderr.puts "Couldn't create '#{configuration['database']}' database. Please check your configuration."
125
+ $stderr.puts "Couldn't create database for #{configuration.inspect}"
124
126
  raise
125
127
  end
126
128
 
@@ -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:
@@ -53,13 +53,6 @@ module ActiveRecord
53
53
  end
54
54
 
55
55
  class_methods do
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
-
63
56
  private
64
57
  def timestamp_attributes_for_create_in_model
65
58
  timestamp_attributes_for_create.select { |c| column_names.include?(c) }
@@ -94,7 +87,7 @@ module ActiveRecord
94
87
 
95
88
  all_timestamp_attributes_in_model.each do |column|
96
89
  if !attribute_present?(column)
97
- write_attribute(column, current_time)
90
+ _write_attribute(column, current_time)
98
91
  end
99
92
  end
100
93
  end
@@ -108,7 +101,7 @@ module ActiveRecord
108
101
 
109
102
  timestamp_attributes_for_update_in_model.each do |column|
110
103
  next if will_save_change_to_attribute?(column)
111
- write_attribute(column, current_time)
104
+ _write_attribute(column, current_time)
112
105
  end
113
106
  end
114
107
  super(*args)
@@ -134,7 +127,7 @@ module ActiveRecord
134
127
  self.class.send(:current_time_from_proper_timezone)
135
128
  end
136
129
 
137
- def max_updated_column_timestamp(timestamp_names = self.class.send(:timestamp_attributes_for_update))
130
+ def max_updated_column_timestamp(timestamp_names = timestamp_attributes_for_update_in_model)
138
131
  timestamp_names
139
132
  .map { |attr| self[attr] }
140
133
  .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
 
@@ -430,8 +432,8 @@ module ActiveRecord
430
432
  @new_record = restore_state[:new_record]
431
433
  @destroyed = restore_state[:destroyed]
432
434
  pk = self.class.primary_key
433
- if pk && read_attribute(pk) != restore_state[:id]
434
- write_attribute(pk, restore_state[:id])
435
+ if pk && _read_attribute(pk) != restore_state[:id]
436
+ _write_attribute(pk, restore_state[:id])
435
437
  end
436
438
  freeze if restore_state[:frozen?]
437
439
  end
@@ -470,7 +472,7 @@ module ActiveRecord
470
472
  # if it's associated with a transaction, then the state of the Active Record
471
473
  # object will be updated to reflect the current state of the transaction.
472
474
  #
473
- # The +@transaction_state+ variable stores the states of the associated
475
+ # The <tt>@transaction_state</tt> variable stores the states of the associated
474
476
  # transaction. This relies on the fact that a transaction can only be in
475
477
  # one rollback or commit (otherwise a list of states would be required).
476
478
  # Each Active Record object inside of a transaction carries that transaction's
@@ -490,7 +492,7 @@ module ActiveRecord
490
492
  def update_attributes_from_transaction_state(transaction_state)
491
493
  if transaction_state && transaction_state.finalized?
492
494
  restore_transaction_record_state if transaction_state.rolledback?
493
- clear_transaction_record_state
495
+ clear_transaction_record_state if transaction_state.fully_completed?
494
496
  end
495
497
  end
496
498
  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
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module Type
5
+ class Json < ActiveModel::Type::Value
6
+ include ActiveModel::Type::Helpers::Mutable
7
+
8
+ def type
9
+ :json
10
+ end
11
+
12
+ def deserialize(value)
13
+ return value unless value.is_a?(::String)
14
+ ActiveSupport::JSON.decode(value) rescue nil
15
+ end
16
+
17
+ def serialize(value)
18
+ ActiveSupport::JSON.encode(value) unless value.nil?
19
+ end
20
+
21
+ def changed_in_place?(raw_old_value, new_value)
22
+ deserialize(raw_old_value) != new_value
23
+ end
24
+
25
+ def accessor
26
+ ActiveRecord::Store::StringKeyedHashAccessor
27
+ end
28
+ end
29
+ end
30
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module Type
3
5
  class Serialized < DelegateClass(ActiveModel::Type::Value) # :nodoc:
@@ -49,10 +51,6 @@ module ActiveRecord
49
51
  end
50
52
  end
51
53
 
52
- def force_equality?(value)
53
- coder.respond_to?(:object_class) && value.is_a?(coder.object_class)
54
- end
55
-
56
54
  private
57
55
 
58
56
  def default_value?(value)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module Type
3
5
  class Text < ActiveModel::Type::String # :nodoc:
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module Type
3
5
  class Time < ActiveModel::Type::Time
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "concurrent/map"
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 UnsignedInteger < ActiveModel::Type::Integer # :nodoc:
@@ -1,11 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_model/type"
2
4
 
3
- require "active_record/type/internal/abstract_json"
4
5
  require "active_record/type/internal/timezone"
5
6
 
6
7
  require "active_record/type/date"
7
8
  require "active_record/type/date_time"
8
9
  require "active_record/type/decimal_without_scale"
10
+ require "active_record/type/json"
9
11
  require "active_record/type/time"
10
12
  require "active_record/type/text"
11
13
  require "active_record/type/unsigned_integer"
@@ -69,6 +71,7 @@ module ActiveRecord
69
71
  register(:decimal, Type::Decimal, override: false)
70
72
  register(:float, Type::Float, override: false)
71
73
  register(:integer, Type::Integer, override: false)
74
+ register(:json, Type::Json, override: false)
72
75
  register(:string, Type::String, override: false)
73
76
  register(:text, Type::Text, override: false)
74
77
  register(:time, Type::Time, override: false)