activerecord 5.1.0 → 5.2.0.rc1

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 (260) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +410 -530
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +4 -4
  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 +23 -32
  10. data/lib/active_record/associations/association.rb +20 -21
  11. data/lib/active_record/associations/association_scope.rb +49 -49
  12. data/lib/active_record/associations/belongs_to_association.rb +12 -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 +10 -6
  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 +50 -41
  22. data/lib/active_record/associations/collection_proxy.rb +22 -39
  23. data/lib/active_record/associations/foreign_association.rb +2 -0
  24. data/lib/active_record/associations/has_many_association.rb +4 -2
  25. data/lib/active_record/associations/has_many_through_association.rb +12 -18
  26. data/lib/active_record/associations/has_one_association.rb +5 -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 -64
  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 +27 -44
  32. data/lib/active_record/associations/preloader/association.rb +53 -92
  33. data/lib/active_record/associations/preloader/through_association.rb +72 -73
  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 +26 -11
  37. data/lib/active_record/associations.rb +68 -76
  38. data/lib/active_record/attribute_assignment.rb +2 -0
  39. data/lib/active_record/attribute_decorators.rb +3 -2
  40. data/lib/active_record/attribute_methods/before_type_cast.rb +2 -0
  41. data/lib/active_record/attribute_methods/dirty.rb +24 -214
  42. data/lib/active_record/attribute_methods/primary_key.rb +10 -13
  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 +22 -19
  48. data/lib/active_record/attribute_methods.rb +48 -12
  49. data/lib/active_record/attributes.rb +7 -6
  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 -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 +14 -10
  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 +175 -33
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +8 -2
  60. data/lib/active_record/connection_adapters/abstract/quoting.rb +13 -24
  61. data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
  62. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +15 -6
  63. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +58 -3
  64. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +31 -53
  65. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +165 -85
  66. data/lib/active_record/connection_adapters/abstract/transaction.rb +45 -9
  67. data/lib/active_record/connection_adapters/abstract_adapter.rb +83 -97
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +118 -180
  69. data/lib/active_record/connection_adapters/column.rb +4 -2
  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 -17
  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 -23
  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 +30 -1
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +6 -32
  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 +2 -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_time.rb +2 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  92. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +2 -0
  93. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +2 -0
  94. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  95. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  96. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -1
  98. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +2 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +4 -2
  101. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +2 -0
  102. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +4 -2
  103. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +3 -1
  104. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
  105. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
  106. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -1
  107. data/lib/active_record/connection_adapters/postgresql/quoting.rb +22 -1
  108. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
  109. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +14 -0
  110. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +24 -11
  111. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +20 -13
  112. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +269 -126
  113. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +2 -0
  114. data/lib/active_record/connection_adapters/postgresql/utils.rb +2 -0
  115. data/lib/active_record/connection_adapters/postgresql_adapter.rb +64 -85
  116. data/lib/active_record/connection_adapters/schema_cache.rb +4 -2
  117. data/lib/active_record/connection_adapters/sql_type_metadata.rb +2 -0
  118. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +2 -0
  119. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +18 -0
  120. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +2 -0
  121. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +6 -15
  122. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +3 -2
  123. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +71 -1
  124. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +92 -95
  125. data/lib/active_record/connection_adapters/statement_pool.rb +2 -0
  126. data/lib/active_record/connection_handling.rb +4 -2
  127. data/lib/active_record/core.rb +39 -60
  128. data/lib/active_record/counter_cache.rb +3 -2
  129. data/lib/active_record/define_callbacks.rb +5 -3
  130. data/lib/active_record/dynamic_matchers.rb +9 -9
  131. data/lib/active_record/enum.rb +17 -13
  132. data/lib/active_record/errors.rb +42 -3
  133. data/lib/active_record/explain.rb +3 -1
  134. data/lib/active_record/explain_registry.rb +2 -0
  135. data/lib/active_record/explain_subscriber.rb +2 -0
  136. data/lib/active_record/fixture_set/file.rb +2 -0
  137. data/lib/active_record/fixtures.rb +67 -60
  138. data/lib/active_record/gem_version.rb +4 -2
  139. data/lib/active_record/inheritance.rb +9 -9
  140. data/lib/active_record/integration.rb +58 -19
  141. data/lib/active_record/internal_metadata.rb +2 -0
  142. data/lib/active_record/legacy_yaml_adapter.rb +3 -1
  143. data/lib/active_record/locking/optimistic.rb +8 -6
  144. data/lib/active_record/locking/pessimistic.rb +9 -6
  145. data/lib/active_record/log_subscriber.rb +46 -4
  146. data/lib/active_record/migration/command_recorder.rb +11 -9
  147. data/lib/active_record/migration/compatibility.rb +74 -22
  148. data/lib/active_record/migration/join_table.rb +2 -0
  149. data/lib/active_record/migration.rb +181 -137
  150. data/lib/active_record/model_schema.rb +73 -58
  151. data/lib/active_record/nested_attributes.rb +18 -6
  152. data/lib/active_record/no_touching.rb +3 -1
  153. data/lib/active_record/null_relation.rb +2 -0
  154. data/lib/active_record/persistence.rb +153 -18
  155. data/lib/active_record/query_cache.rb +17 -12
  156. data/lib/active_record/querying.rb +4 -2
  157. data/lib/active_record/railtie.rb +61 -3
  158. data/lib/active_record/railties/console_sandbox.rb +2 -0
  159. data/lib/active_record/railties/controller_runtime.rb +2 -0
  160. data/lib/active_record/railties/databases.rake +47 -37
  161. data/lib/active_record/readonly_attributes.rb +3 -2
  162. data/lib/active_record/reflection.rb +131 -204
  163. data/lib/active_record/relation/batches/batch_enumerator.rb +2 -0
  164. data/lib/active_record/relation/batches.rb +32 -17
  165. data/lib/active_record/relation/calculations.rb +58 -20
  166. data/lib/active_record/relation/delegation.rb +10 -29
  167. data/lib/active_record/relation/finder_methods.rb +74 -85
  168. data/lib/active_record/relation/from_clause.rb +2 -8
  169. data/lib/active_record/relation/merger.rb +51 -20
  170. data/lib/active_record/relation/predicate_builder/array_handler.rb +10 -7
  171. data/lib/active_record/relation/predicate_builder/association_query_value.rb +46 -0
  172. data/lib/active_record/relation/predicate_builder/base_handler.rb +2 -2
  173. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +12 -1
  174. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +54 -0
  175. data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -6
  176. data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
  177. data/lib/active_record/relation/predicate_builder.rb +53 -78
  178. data/lib/active_record/relation/query_attribute.rb +9 -2
  179. data/lib/active_record/relation/query_methods.rb +101 -95
  180. data/lib/active_record/relation/record_fetch_warning.rb +2 -0
  181. data/lib/active_record/relation/spawn_methods.rb +3 -1
  182. data/lib/active_record/relation/where_clause.rb +65 -67
  183. data/lib/active_record/relation/where_clause_factory.rb +5 -48
  184. data/lib/active_record/relation.rb +99 -202
  185. data/lib/active_record/result.rb +2 -0
  186. data/lib/active_record/runtime_registry.rb +2 -0
  187. data/lib/active_record/sanitization.rb +129 -121
  188. data/lib/active_record/schema.rb +4 -2
  189. data/lib/active_record/schema_dumper.rb +36 -26
  190. data/lib/active_record/schema_migration.rb +2 -0
  191. data/lib/active_record/scoping/default.rb +10 -7
  192. data/lib/active_record/scoping/named.rb +38 -12
  193. data/lib/active_record/scoping.rb +12 -10
  194. data/lib/active_record/secure_token.rb +2 -0
  195. data/lib/active_record/serialization.rb +2 -0
  196. data/lib/active_record/statement_cache.rb +22 -12
  197. data/lib/active_record/store.rb +3 -1
  198. data/lib/active_record/suppressor.rb +2 -0
  199. data/lib/active_record/table_metadata.rb +12 -3
  200. data/lib/active_record/tasks/database_tasks.rb +37 -25
  201. data/lib/active_record/tasks/mysql_database_tasks.rb +11 -50
  202. data/lib/active_record/tasks/postgresql_database_tasks.rb +11 -3
  203. data/lib/active_record/tasks/sqlite_database_tasks.rb +25 -3
  204. data/lib/active_record/timestamp.rb +5 -5
  205. data/lib/active_record/touch_later.rb +2 -0
  206. data/lib/active_record/transactions.rb +9 -7
  207. data/lib/active_record/translation.rb +2 -0
  208. data/lib/active_record/type/adapter_specific_registry.rb +2 -0
  209. data/lib/active_record/type/date.rb +2 -0
  210. data/lib/active_record/type/date_time.rb +2 -0
  211. data/lib/active_record/type/decimal_without_scale.rb +2 -0
  212. data/lib/active_record/type/hash_lookup_type_map.rb +2 -0
  213. data/lib/active_record/type/internal/timezone.rb +2 -0
  214. data/lib/active_record/type/json.rb +30 -0
  215. data/lib/active_record/type/serialized.rb +2 -0
  216. data/lib/active_record/type/text.rb +2 -0
  217. data/lib/active_record/type/time.rb +2 -0
  218. data/lib/active_record/type/type_map.rb +2 -0
  219. data/lib/active_record/type/unsigned_integer.rb +2 -0
  220. data/lib/active_record/type.rb +4 -1
  221. data/lib/active_record/type_caster/connection.rb +2 -0
  222. data/lib/active_record/type_caster/map.rb +3 -1
  223. data/lib/active_record/type_caster.rb +2 -0
  224. data/lib/active_record/validations/absence.rb +2 -0
  225. data/lib/active_record/validations/associated.rb +2 -0
  226. data/lib/active_record/validations/length.rb +2 -0
  227. data/lib/active_record/validations/presence.rb +2 -0
  228. data/lib/active_record/validations/uniqueness.rb +35 -5
  229. data/lib/active_record/validations.rb +2 -0
  230. data/lib/active_record/version.rb +2 -0
  231. data/lib/active_record.rb +11 -4
  232. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
  233. data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
  234. data/lib/rails/generators/active_record/migration/migration_generator.rb +3 -1
  235. data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +0 -0
  236. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +0 -0
  237. data/lib/rails/generators/active_record/migration.rb +2 -0
  238. data/lib/rails/generators/active_record/model/model_generator.rb +2 -23
  239. data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +0 -0
  240. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  241. data/lib/rails/generators/active_record.rb +3 -1
  242. metadata +25 -37
  243. data/lib/active_record/associations/preloader/belongs_to.rb +0 -15
  244. data/lib/active_record/associations/preloader/collection_association.rb +0 -17
  245. data/lib/active_record/associations/preloader/has_many.rb +0 -15
  246. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  247. data/lib/active_record/associations/preloader/has_one.rb +0 -15
  248. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  249. data/lib/active_record/associations/preloader/singular_association.rb +0 -18
  250. data/lib/active_record/attribute/user_provided_default.rb +0 -30
  251. data/lib/active_record/attribute.rb +0 -240
  252. data/lib/active_record/attribute_mutation_tracker.rb +0 -113
  253. data/lib/active_record/attribute_set/builder.rb +0 -124
  254. data/lib/active_record/attribute_set/yaml_encoder.rb +0 -41
  255. data/lib/active_record/attribute_set.rb +0 -113
  256. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -10
  257. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  258. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
  259. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -59
  260. data/lib/active_record/type/internal/abstract_json.rb +0 -33
@@ -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
@@ -223,22 +234,22 @@ module ActiveRecord
223
234
  class_for_adapter(configuration["adapter"]).new(*arguments).structure_load(filename, structure_load_flags)
224
235
  end
225
236
 
226
- def load_schema(configuration, format = ActiveRecord::Base.schema_format, file = nil) # :nodoc:
237
+ def load_schema(configuration, format = ActiveRecord::Base.schema_format, file = nil, environment = env) # :nodoc:
227
238
  file ||= schema_file(format)
228
239
 
240
+ check_schema_file(file)
241
+ ActiveRecord::Base.establish_connection(configuration)
242
+
229
243
  case format
230
244
  when :ruby
231
- check_schema_file(file)
232
- ActiveRecord::Base.establish_connection(configuration)
233
245
  load(file)
234
246
  when :sql
235
- check_schema_file(file)
236
247
  structure_load(configuration, file)
237
248
  else
238
249
  raise ArgumentError, "unknown format #{format.inspect}"
239
250
  end
240
251
  ActiveRecord::InternalMetadata.create_table
241
- ActiveRecord::InternalMetadata[:environment] = ActiveRecord::Migrator.current_environment
252
+ ActiveRecord::InternalMetadata[:environment] = environment
242
253
  end
243
254
 
244
255
  def schema_file(format = ActiveRecord::Base.schema_format)
@@ -251,16 +262,16 @@ module ActiveRecord
251
262
  end
252
263
 
253
264
  def load_schema_current(format = ActiveRecord::Base.schema_format, file = nil, environment = env)
254
- each_current_configuration(environment) { |configuration|
255
- load_schema configuration, format, file
265
+ each_current_configuration(environment) { |configuration, configuration_environment|
266
+ load_schema configuration, format, file, configuration_environment
256
267
  }
257
268
  ActiveRecord::Base.establish_connection(environment.to_sym)
258
269
  end
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.}
263
- 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)
273
+ message = %{#{filename} doesn't exist yet. Run `rails db:migrate` to create it, then try again.}.dup
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
266
277
  end
@@ -288,20 +299,21 @@ 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)
299
310
  environments = [environment]
300
311
  environments << "test" if environment == "development"
301
312
 
302
- configurations = ActiveRecord::Base.configurations.values_at(*environments)
303
- configurations.compact.each do |configuration|
304
- yield configuration unless configuration["database"].blank?
313
+ ActiveRecord::Base.configurations.slice(*environments).each do |configuration_environment, configuration|
314
+ next unless configuration["database"]
315
+
316
+ yield configuration, configuration_environment
305
317
  end
306
318
  end
307
319
 
@@ -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,8 +45,14 @@ module ActiveRecord
59
45
  args.concat(["--no-data"])
60
46
  args.concat(["--routines"])
61
47
  args.concat(["--skip-comments"])
62
- args.concat(Array(extra_flags)) if extra_flags
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
+
63
54
  args.concat(["#{configuration['database']}"])
55
+ args.unshift(*extra_flags) if extra_flags
64
56
 
65
57
  run_cmd("mysqldump", args, "dumping")
66
58
  end
@@ -69,7 +61,7 @@ module ActiveRecord
69
61
  args = prepare_command_options
70
62
  args.concat(["--execute", %{SET FOREIGN_KEY_CHECKS = 0; SOURCE #{filename}; SET FOREIGN_KEY_CHECKS = 1}])
71
63
  args.concat(["--database", "#{configuration['database']}"])
72
- args.concat(Array(extra_flags)) if extra_flags
64
+ args.unshift(*extra_flags) if extra_flags
73
65
 
74
66
  run_cmd("mysql", args, "loading")
75
67
  end
@@ -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
@@ -20,7 +22,7 @@ module ActiveRecord
20
22
  configuration.merge("encoding" => encoding)
21
23
  establish_connection configuration
22
24
  rescue ActiveRecord::StatementInvalid => error
23
- if /database .* already exists/.match?(error.message)
25
+ if error.cause.is_a?(PG::DuplicateDatabase)
24
26
  raise DatabaseAlreadyExists
25
27
  else
26
28
  raise
@@ -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:
@@ -87,7 +87,7 @@ module ActiveRecord
87
87
 
88
88
  all_timestamp_attributes_in_model.each do |column|
89
89
  if !attribute_present?(column)
90
- write_attribute(column, current_time)
90
+ _write_attribute(column, current_time)
91
91
  end
92
92
  end
93
93
  end
@@ -101,7 +101,7 @@ module ActiveRecord
101
101
 
102
102
  timestamp_attributes_for_update_in_model.each do |column|
103
103
  next if will_save_change_to_attribute?(column)
104
- write_attribute(column, current_time)
104
+ _write_attribute(column, current_time)
105
105
  end
106
106
  end
107
107
  super(*args)
@@ -127,7 +127,7 @@ module ActiveRecord
127
127
  self.class.send(:current_time_from_proper_timezone)
128
128
  end
129
129
 
130
- 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)
131
131
  timestamp_names
132
132
  .map { |attr| self[attr] }
133
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:
@@ -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