activerecord 5.1.0 → 5.2.3

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

Files changed (261) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +596 -450
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +5 -5
  5. data/examples/performance.rb +2 -0
  6. data/examples/simple.rb +2 -0
  7. data/lib/active_record.rb +11 -4
  8. data/lib/active_record/aggregations.rb +6 -5
  9. data/lib/active_record/association_relation.rb +7 -5
  10. data/lib/active_record/associations.rb +77 -85
  11. data/lib/active_record/associations/alias_tracker.rb +23 -32
  12. data/lib/active_record/associations/association.rb +49 -35
  13. data/lib/active_record/associations/association_scope.rb +55 -55
  14. data/lib/active_record/associations/belongs_to_association.rb +30 -11
  15. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -8
  16. data/lib/active_record/associations/builder/association.rb +4 -7
  17. data/lib/active_record/associations/builder/belongs_to.rb +21 -8
  18. data/lib/active_record/associations/builder/collection_association.rb +1 -1
  19. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -1
  20. data/lib/active_record/associations/builder/has_many.rb +2 -0
  21. data/lib/active_record/associations/builder/has_one.rb +2 -0
  22. data/lib/active_record/associations/builder/singular_association.rb +2 -0
  23. data/lib/active_record/associations/collection_association.rb +66 -53
  24. data/lib/active_record/associations/collection_proxy.rb +30 -73
  25. data/lib/active_record/associations/foreign_association.rb +2 -0
  26. data/lib/active_record/associations/has_many_association.rb +13 -2
  27. data/lib/active_record/associations/has_many_through_association.rb +37 -19
  28. data/lib/active_record/associations/has_one_association.rb +14 -1
  29. data/lib/active_record/associations/has_one_through_association.rb +13 -8
  30. data/lib/active_record/associations/join_dependency.rb +52 -96
  31. data/lib/active_record/associations/join_dependency/join_association.rb +22 -75
  32. data/lib/active_record/associations/join_dependency/join_base.rb +9 -8
  33. data/lib/active_record/associations/join_dependency/join_part.rb +9 -9
  34. data/lib/active_record/associations/preloader.rb +17 -37
  35. data/lib/active_record/associations/preloader/association.rb +53 -92
  36. data/lib/active_record/associations/preloader/through_association.rb +72 -73
  37. data/lib/active_record/associations/singular_association.rb +14 -16
  38. data/lib/active_record/associations/through_association.rb +27 -12
  39. data/lib/active_record/attribute_assignment.rb +2 -5
  40. data/lib/active_record/attribute_decorators.rb +3 -2
  41. data/lib/active_record/attribute_methods.rb +65 -24
  42. data/lib/active_record/attribute_methods/before_type_cast.rb +2 -0
  43. data/lib/active_record/attribute_methods/dirty.rb +33 -216
  44. data/lib/active_record/attribute_methods/primary_key.rb +10 -13
  45. data/lib/active_record/attribute_methods/query.rb +2 -0
  46. data/lib/active_record/attribute_methods/read.rb +9 -3
  47. data/lib/active_record/attribute_methods/serialization.rb +23 -0
  48. data/lib/active_record/attribute_methods/time_zone_conversion.rb +6 -8
  49. data/lib/active_record/attribute_methods/write.rb +22 -19
  50. data/lib/active_record/attributes.rb +7 -6
  51. data/lib/active_record/autosave_association.rb +15 -13
  52. data/lib/active_record/base.rb +2 -0
  53. data/lib/active_record/callbacks.rb +12 -6
  54. data/lib/active_record/coders/json.rb +2 -0
  55. data/lib/active_record/coders/yaml_column.rb +2 -0
  56. data/lib/active_record/collection_cache_key.rb +15 -11
  57. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +120 -39
  58. data/lib/active_record/connection_adapters/abstract/database_limits.rb +7 -0
  59. data/lib/active_record/connection_adapters/abstract/database_statements.rb +192 -37
  60. data/lib/active_record/connection_adapters/abstract/query_cache.rb +13 -2
  61. data/lib/active_record/connection_adapters/abstract/quoting.rb +15 -25
  62. data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
  63. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +15 -6
  64. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +65 -7
  65. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +31 -53
  66. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +158 -87
  67. data/lib/active_record/connection_adapters/abstract/transaction.rb +66 -21
  68. data/lib/active_record/connection_adapters/abstract_adapter.rb +86 -98
  69. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +126 -189
  70. data/lib/active_record/connection_adapters/column.rb +4 -2
  71. data/lib/active_record/connection_adapters/connection_specification.rb +17 -3
  72. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +13 -2
  73. data/lib/active_record/connection_adapters/mysql/column.rb +2 -0
  74. data/lib/active_record/connection_adapters/mysql/database_statements.rb +45 -15
  75. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +2 -0
  76. data/lib/active_record/connection_adapters/mysql/quoting.rb +9 -10
  77. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +5 -3
  78. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +7 -10
  79. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +30 -23
  80. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +106 -1
  81. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +2 -0
  82. data/lib/active_record/connection_adapters/mysql2_adapter.rb +8 -2
  83. data/lib/active_record/connection_adapters/postgresql/column.rb +30 -1
  84. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +6 -32
  85. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +2 -0
  86. data/lib/active_record/connection_adapters/postgresql/oid.rb +3 -1
  87. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +13 -1
  88. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +2 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  90. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +2 -0
  92. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
  93. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -0
  94. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  95. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +2 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +2 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  99. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -1
  101. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +2 -0
  102. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -0
  103. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +8 -2
  104. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +2 -0
  105. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +4 -2
  106. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +3 -1
  107. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
  108. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
  109. data/lib/active_record/connection_adapters/postgresql/quoting.rb +22 -1
  110. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
  111. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +50 -0
  112. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +24 -11
  113. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +20 -13
  114. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +258 -129
  115. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +2 -0
  116. data/lib/active_record/connection_adapters/postgresql/utils.rb +3 -1
  117. data/lib/active_record/connection_adapters/postgresql_adapter.rb +75 -87
  118. data/lib/active_record/connection_adapters/schema_cache.rb +4 -2
  119. data/lib/active_record/connection_adapters/sql_type_metadata.rb +2 -0
  120. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +2 -0
  121. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +24 -1
  122. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +2 -0
  123. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +6 -15
  124. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +3 -2
  125. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +75 -1
  126. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +90 -96
  127. data/lib/active_record/connection_adapters/statement_pool.rb +2 -0
  128. data/lib/active_record/connection_handling.rb +4 -2
  129. data/lib/active_record/core.rb +41 -61
  130. data/lib/active_record/counter_cache.rb +20 -15
  131. data/lib/active_record/define_callbacks.rb +5 -3
  132. data/lib/active_record/dynamic_matchers.rb +9 -9
  133. data/lib/active_record/enum.rb +18 -13
  134. data/lib/active_record/errors.rb +60 -15
  135. data/lib/active_record/explain.rb +3 -1
  136. data/lib/active_record/explain_registry.rb +2 -0
  137. data/lib/active_record/explain_subscriber.rb +2 -0
  138. data/lib/active_record/fixture_set/file.rb +2 -0
  139. data/lib/active_record/fixtures.rb +67 -60
  140. data/lib/active_record/gem_version.rb +4 -2
  141. data/lib/active_record/inheritance.rb +49 -19
  142. data/lib/active_record/integration.rb +58 -19
  143. data/lib/active_record/internal_metadata.rb +2 -0
  144. data/lib/active_record/legacy_yaml_adapter.rb +3 -1
  145. data/lib/active_record/locking/optimistic.rb +30 -42
  146. data/lib/active_record/locking/pessimistic.rb +10 -7
  147. data/lib/active_record/log_subscriber.rb +46 -4
  148. data/lib/active_record/migration.rb +189 -139
  149. data/lib/active_record/migration/command_recorder.rb +11 -9
  150. data/lib/active_record/migration/compatibility.rb +81 -29
  151. data/lib/active_record/migration/join_table.rb +2 -0
  152. data/lib/active_record/model_schema.rb +74 -58
  153. data/lib/active_record/nested_attributes.rb +18 -6
  154. data/lib/active_record/no_touching.rb +3 -1
  155. data/lib/active_record/null_relation.rb +2 -0
  156. data/lib/active_record/persistence.rb +199 -54
  157. data/lib/active_record/query_cache.rb +8 -10
  158. data/lib/active_record/querying.rb +5 -3
  159. data/lib/active_record/railtie.rb +62 -6
  160. data/lib/active_record/railties/console_sandbox.rb +2 -0
  161. data/lib/active_record/railties/controller_runtime.rb +2 -0
  162. data/lib/active_record/railties/databases.rake +48 -38
  163. data/lib/active_record/readonly_attributes.rb +3 -2
  164. data/lib/active_record/reflection.rb +137 -207
  165. data/lib/active_record/relation.rb +132 -207
  166. data/lib/active_record/relation/batches.rb +32 -17
  167. data/lib/active_record/relation/batches/batch_enumerator.rb +2 -0
  168. data/lib/active_record/relation/calculations.rb +66 -25
  169. data/lib/active_record/relation/delegation.rb +45 -29
  170. data/lib/active_record/relation/finder_methods.rb +76 -85
  171. data/lib/active_record/relation/from_clause.rb +2 -8
  172. data/lib/active_record/relation/merger.rb +53 -23
  173. data/lib/active_record/relation/predicate_builder.rb +60 -79
  174. data/lib/active_record/relation/predicate_builder/array_handler.rb +10 -7
  175. data/lib/active_record/relation/predicate_builder/association_query_value.rb +46 -0
  176. data/lib/active_record/relation/predicate_builder/base_handler.rb +2 -2
  177. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +12 -1
  178. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +56 -0
  179. data/lib/active_record/relation/predicate_builder/range_handler.rb +26 -9
  180. data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
  181. data/lib/active_record/relation/query_attribute.rb +28 -2
  182. data/lib/active_record/relation/query_methods.rb +135 -103
  183. data/lib/active_record/relation/record_fetch_warning.rb +2 -0
  184. data/lib/active_record/relation/spawn_methods.rb +4 -2
  185. data/lib/active_record/relation/where_clause.rb +65 -67
  186. data/lib/active_record/relation/where_clause_factory.rb +5 -48
  187. data/lib/active_record/result.rb +2 -0
  188. data/lib/active_record/runtime_registry.rb +2 -0
  189. data/lib/active_record/sanitization.rb +129 -121
  190. data/lib/active_record/schema.rb +4 -2
  191. data/lib/active_record/schema_dumper.rb +36 -26
  192. data/lib/active_record/schema_migration.rb +2 -0
  193. data/lib/active_record/scoping.rb +12 -10
  194. data/lib/active_record/scoping/default.rb +10 -7
  195. data/lib/active_record/scoping/named.rb +40 -12
  196. data/lib/active_record/secure_token.rb +2 -0
  197. data/lib/active_record/serialization.rb +2 -0
  198. data/lib/active_record/statement_cache.rb +22 -12
  199. data/lib/active_record/store.rb +3 -1
  200. data/lib/active_record/suppressor.rb +2 -0
  201. data/lib/active_record/table_metadata.rb +12 -3
  202. data/lib/active_record/tasks/database_tasks.rb +38 -26
  203. data/lib/active_record/tasks/mysql_database_tasks.rb +11 -50
  204. data/lib/active_record/tasks/postgresql_database_tasks.rb +11 -3
  205. data/lib/active_record/tasks/sqlite_database_tasks.rb +25 -3
  206. data/lib/active_record/timestamp.rb +13 -6
  207. data/lib/active_record/touch_later.rb +2 -0
  208. data/lib/active_record/transactions.rb +32 -27
  209. data/lib/active_record/translation.rb +2 -0
  210. data/lib/active_record/type.rb +4 -1
  211. data/lib/active_record/type/adapter_specific_registry.rb +2 -0
  212. data/lib/active_record/type/date.rb +2 -0
  213. data/lib/active_record/type/date_time.rb +2 -0
  214. data/lib/active_record/type/decimal_without_scale.rb +2 -0
  215. data/lib/active_record/type/hash_lookup_type_map.rb +2 -0
  216. data/lib/active_record/type/internal/timezone.rb +2 -0
  217. data/lib/active_record/type/json.rb +30 -0
  218. data/lib/active_record/type/serialized.rb +6 -0
  219. data/lib/active_record/type/text.rb +2 -0
  220. data/lib/active_record/type/time.rb +2 -0
  221. data/lib/active_record/type/type_map.rb +2 -0
  222. data/lib/active_record/type/unsigned_integer.rb +2 -0
  223. data/lib/active_record/type_caster.rb +2 -0
  224. data/lib/active_record/type_caster/connection.rb +2 -0
  225. data/lib/active_record/type_caster/map.rb +3 -1
  226. data/lib/active_record/validations.rb +2 -0
  227. data/lib/active_record/validations/absence.rb +2 -0
  228. data/lib/active_record/validations/associated.rb +2 -0
  229. data/lib/active_record/validations/length.rb +2 -0
  230. data/lib/active_record/validations/presence.rb +2 -0
  231. data/lib/active_record/validations/uniqueness.rb +36 -6
  232. data/lib/active_record/version.rb +2 -0
  233. data/lib/rails/generators/active_record.rb +3 -1
  234. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
  235. data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
  236. data/lib/rails/generators/active_record/migration.rb +2 -0
  237. data/lib/rails/generators/active_record/migration/migration_generator.rb +3 -1
  238. data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +0 -0
  239. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +0 -0
  240. data/lib/rails/generators/active_record/model/model_generator.rb +2 -23
  241. data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +0 -0
  242. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  243. metadata +24 -36
  244. data/lib/active_record/associations/preloader/belongs_to.rb +0 -15
  245. data/lib/active_record/associations/preloader/collection_association.rb +0 -17
  246. data/lib/active_record/associations/preloader/has_many.rb +0 -15
  247. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  248. data/lib/active_record/associations/preloader/has_one.rb +0 -15
  249. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  250. data/lib/active_record/associations/preloader/singular_association.rb +0 -18
  251. data/lib/active_record/attribute.rb +0 -240
  252. data/lib/active_record/attribute/user_provided_default.rb +0 -30
  253. data/lib/active_record/attribute_mutation_tracker.rb +0 -113
  254. data/lib/active_record/attribute_set.rb +0 -113
  255. data/lib/active_record/attribute_set/builder.rb +0 -124
  256. data/lib/active_record/attribute_set/yaml_encoder.rb +0 -41
  257. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -10
  258. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  259. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
  260. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -59
  261. data/lib/active_record/type/internal/abstract_json.rb +0 -33
@@ -1,3 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "concurrent/map"
4
+
1
5
  module ActiveRecord
2
6
  module ConnectionAdapters # :nodoc:
3
7
  module QueryCache
@@ -90,8 +94,13 @@ module ActiveRecord
90
94
 
91
95
  def select_all(arel, name = nil, binds = [], preparable: nil)
92
96
  if @query_cache_enabled && !locked?(arel)
93
- arel, binds = binds_from_relation arel, binds
94
- sql = to_sql(arel, binds)
97
+ arel = arel_from_relation(arel)
98
+ sql, binds = to_sql_and_binds(arel, binds)
99
+
100
+ if preparable.nil?
101
+ preparable = prepared_statements ? visitor.preparable : false
102
+ end
103
+
95
104
  cache_sql(sql, name, binds) { super(sql, name, binds, preparable: preparable) }
96
105
  else
97
106
  super
@@ -108,6 +117,7 @@ module ActiveRecord
108
117
  "sql.active_record",
109
118
  sql: sql,
110
119
  binds: binds,
120
+ type_casted_binds: -> { type_casted_binds(binds) },
111
121
  name: name,
112
122
  connection_id: object_id,
113
123
  cached: true,
@@ -123,6 +133,7 @@ module ActiveRecord
123
133
  # If arel is locked this is a SELECT ... FOR UPDATE or somesuch. Such
124
134
  # queries should not be cached.
125
135
  def locked?(arel)
136
+ arel = arel.arel if arel.is_a?(Relation)
126
137
  arel.respond_to?(:locked) && arel.locked
127
138
  end
128
139
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/big_decimal/conversions"
2
4
  require "active_support/multibyte/chars"
3
5
 
@@ -5,14 +7,12 @@ module ActiveRecord
5
7
  module ConnectionAdapters # :nodoc:
6
8
  module Quoting
7
9
  # Quotes the column value to help prevent
8
- # {SQL injection attacks}[http://en.wikipedia.org/wiki/SQL_injection].
10
+ # {SQL injection attacks}[https://en.wikipedia.org/wiki/SQL_injection].
9
11
  def quote(value)
10
12
  value = id_value_for_database(value) if value.is_a?(Base)
11
13
 
12
- if value.respond_to?(:quoted_id)
13
- ActiveSupport::Deprecation.warn \
14
- "Using #quoted_id is deprecated and will be removed in Rails 5.2."
15
- return value.quoted_id
14
+ if value.respond_to?(:value_for_database)
15
+ value = value.value_for_database
16
16
  end
17
17
 
18
18
  _quote(value)
@@ -24,10 +24,6 @@ module ActiveRecord
24
24
  def type_cast(value, column = nil)
25
25
  value = id_value_for_database(value) if value.is_a?(Base)
26
26
 
27
- if value.respond_to?(:quoted_id) && value.respond_to?(:id)
28
- return value.id
29
- end
30
-
31
27
  if column
32
28
  value = type_cast_from_column(column, value)
33
29
  end
@@ -61,17 +57,6 @@ module ActiveRecord
61
57
  lookup_cast_type(column.sql_type)
62
58
  end
63
59
 
64
- def fetch_type_metadata(sql_type)
65
- cast_type = lookup_cast_type(sql_type)
66
- SqlTypeMetadata.new(
67
- sql_type: sql_type,
68
- type: cast_type.type,
69
- limit: cast_type.limit,
70
- precision: cast_type.precision,
71
- scale: cast_type.scale,
72
- )
73
- end
74
-
75
60
  # Quotes a string, escaping any ' (single quote) and \ (backslash)
76
61
  # characters.
77
62
  def quote_string(s)
@@ -110,19 +95,19 @@ module ActiveRecord
110
95
  end
111
96
 
112
97
  def quoted_true
113
- "'t'".freeze
98
+ "TRUE".freeze
114
99
  end
115
100
 
116
101
  def unquoted_true
117
- "t".freeze
102
+ true
118
103
  end
119
104
 
120
105
  def quoted_false
121
- "'f'".freeze
106
+ "FALSE".freeze
122
107
  end
123
108
 
124
109
  def unquoted_false
125
- "f".freeze
110
+ false
126
111
  end
127
112
 
128
113
  # Quote date/time values for use in SQL input. Includes microseconds
@@ -145,7 +130,8 @@ module ActiveRecord
145
130
  end
146
131
 
147
132
  def quoted_time(value) # :nodoc:
148
- quoted_date(value).sub(/\A2000-01-01 /, "")
133
+ value = value.change(year: 2000, month: 1, day: 1)
134
+ quoted_date(value).sub(/\A\d\d\d\d-\d\d-\d\d /, "")
149
135
  end
150
136
 
151
137
  def quoted_binary(value) # :nodoc:
@@ -161,6 +147,10 @@ module ActiveRecord
161
147
  end
162
148
 
163
149
  private
150
+ def lookup_cast_type(sql_type)
151
+ type_map.lookup(sql_type)
152
+ end
153
+
164
154
  def id_value_for_database(value)
165
155
  if primary_key = value.class.primary_key
166
156
  value.instance_variable_get(:@attributes)[primary_key].value_for_database
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module Savepoints
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/string/strip"
2
4
 
3
5
  module ActiveRecord
@@ -22,7 +24,7 @@ module ActiveRecord
22
24
  private
23
25
 
24
26
  def visit_AlterTable(o)
25
- sql = "ALTER TABLE #{quote_table_name(o.name)} "
27
+ sql = "ALTER TABLE #{quote_table_name(o.name)} ".dup
26
28
  sql << o.adds.map { |col| accept col }.join(" ")
27
29
  sql << o.foreign_key_adds.map { |fk| visit_AddForeignKey fk }.join(" ")
28
30
  sql << o.foreign_key_drops.map { |fk| visit_DropForeignKey fk }.join(" ")
@@ -30,17 +32,17 @@ module ActiveRecord
30
32
 
31
33
  def visit_ColumnDefinition(o)
32
34
  o.sql_type = type_to_sql(o.type, o.options)
33
- column_sql = "#{quote_column_name(o.name)} #{o.sql_type}"
35
+ column_sql = "#{quote_column_name(o.name)} #{o.sql_type}".dup
34
36
  add_column_options!(column_sql, column_options(o)) unless o.type == :primary_key
35
37
  column_sql
36
38
  end
37
39
 
38
40
  def visit_AddColumnDefinition(o)
39
- "ADD #{accept(o.column)}"
41
+ "ADD #{accept(o.column)}".dup
40
42
  end
41
43
 
42
44
  def visit_TableDefinition(o)
43
- create_sql = "CREATE#{' TEMPORARY' if o.temporary} TABLE #{quote_table_name(o.name)} "
45
+ create_sql = "CREATE#{' TEMPORARY' if o.temporary} TABLE #{quote_table_name(o.name)} ".dup
44
46
 
45
47
  statements = o.columns.map { |c| accept c }
46
48
  statements << accept(o.primary_keys) if o.primary_keys
@@ -55,12 +57,12 @@ module ActiveRecord
55
57
 
56
58
  create_sql << "(#{statements.join(', ')})" if statements.present?
57
59
  add_table_options!(create_sql, table_options(o))
58
- create_sql << " AS #{@conn.to_sql(o.as)}" if o.as
60
+ create_sql << " AS #{to_sql(o.as)}" if o.as
59
61
  create_sql
60
62
  end
61
63
 
62
64
  def visit_PrimaryKeyDefinition(o)
63
- "PRIMARY KEY (#{o.name.join(', ')})"
65
+ "PRIMARY KEY (#{o.name.map { |name| quote_column_name(name) }.join(', ')})"
64
66
  end
65
67
 
66
68
  def visit_ForeignKeyDefinition(o)
@@ -93,6 +95,7 @@ module ActiveRecord
93
95
  if options_sql = options[:options]
94
96
  create_sql << " #{options_sql}"
95
97
  end
98
+ create_sql
96
99
  end
97
100
 
98
101
  def column_options(o)
@@ -114,6 +117,11 @@ module ActiveRecord
114
117
  sql
115
118
  end
116
119
 
120
+ def to_sql(sql)
121
+ sql = sql.to_sql if sql.respond_to?(:to_sql)
122
+ sql
123
+ end
124
+
117
125
  def foreign_key_in_create(from_table, to_table, options)
118
126
  options = foreign_key_options(from_table, to_table, options)
119
127
  accept ForeignKeyDefinition.new(from_table, to_table, options)
@@ -133,5 +141,6 @@ module ActiveRecord
133
141
  end
134
142
  end
135
143
  end
144
+ SchemaCreation = AbstractAdapter::SchemaCreation # :nodoc:
136
145
  end
137
146
  end
@@ -1,9 +1,47 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters #:nodoc:
3
5
  # Abstract representation of an index definition on a table. Instances of
4
6
  # this type are typically created and returned by methods in database
5
- # adapters. e.g. ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter#indexes
6
- IndexDefinition = Struct.new(:table, :name, :unique, :columns, :lengths, :orders, :where, :type, :using, :comment) #:nodoc:
7
+ # adapters. e.g. ActiveRecord::ConnectionAdapters::MySQL::SchemaStatements#indexes
8
+ class IndexDefinition # :nodoc:
9
+ attr_reader :table, :name, :unique, :columns, :lengths, :orders, :opclasses, :where, :type, :using, :comment
10
+
11
+ def initialize(
12
+ table, name,
13
+ unique = false,
14
+ columns = [],
15
+ lengths: {},
16
+ orders: {},
17
+ opclasses: {},
18
+ where: nil,
19
+ type: nil,
20
+ using: nil,
21
+ comment: nil
22
+ )
23
+ @table = table
24
+ @name = name
25
+ @unique = unique
26
+ @columns = columns
27
+ @lengths = concise_options(lengths)
28
+ @orders = concise_options(orders)
29
+ @opclasses = concise_options(opclasses)
30
+ @where = where
31
+ @type = type
32
+ @using = using
33
+ @comment = comment
34
+ end
35
+
36
+ private
37
+ def concise_options(options)
38
+ if columns.size == options.size && options.values.uniq.size == 1
39
+ options.values.first
40
+ else
41
+ options
42
+ end
43
+ end
44
+ end
7
45
 
8
46
  # Abstract representation of a column definition. Instances of this type
9
47
  # are typically created by methods in TableDefinition, and added to the
@@ -58,6 +96,11 @@ module ActiveRecord
58
96
  options[:primary_key] != default_primary_key
59
97
  end
60
98
 
99
+ def validate?
100
+ options.fetch(:validate, true)
101
+ end
102
+ alias validated? validate?
103
+
61
104
  def defined_for?(to_table_ord = nil, to_table: nil, **options)
62
105
  if to_table_ord
63
106
  self.to_table == to_table_ord.to_s
@@ -121,7 +164,7 @@ module ActiveRecord
121
164
  end
122
165
 
123
166
  def polymorphic_options
124
- as_options(polymorphic)
167
+ as_options(polymorphic).merge(options.slice(:null, :first, :after))
125
168
  end
126
169
 
127
170
  def index_options
@@ -177,6 +220,7 @@ module ActiveRecord
177
220
  :decimal,
178
221
  :float,
179
222
  :integer,
223
+ :json,
180
224
  :string,
181
225
  :text,
182
226
  :time,
@@ -369,6 +413,9 @@ module ActiveRecord
369
413
  alias :belongs_to :references
370
414
 
371
415
  def new_column_definition(name, type, **options) # :nodoc:
416
+ if integer_like_primary_key?(type, options)
417
+ type = integer_like_primary_key_type(type, options)
418
+ end
372
419
  type = aliased_types(type.to_s, type)
373
420
  options[:primary_key] ||= type == :primary_key
374
421
  options[:null] = false if options[:primary_key]
@@ -383,6 +430,14 @@ module ActiveRecord
383
430
  def aliased_types(name, fallback)
384
431
  "timestamp" == name ? :datetime : fallback
385
432
  end
433
+
434
+ def integer_like_primary_key?(type, options)
435
+ options[:primary_key] && [:integer, :bigint].include?(type) && !options.key?(:default)
436
+ end
437
+
438
+ def integer_like_primary_key_type(type, options)
439
+ type
440
+ end
386
441
  end
387
442
 
388
443
  class AlterTable # :nodoc:
@@ -443,6 +498,9 @@ module ActiveRecord
443
498
  # t.date
444
499
  # t.binary
445
500
  # t.boolean
501
+ # t.foreign_key
502
+ # t.json
503
+ # t.virtual
446
504
  # t.remove
447
505
  # t.remove_references
448
506
  # t.remove_belongs_to
@@ -607,19 +665,19 @@ module ActiveRecord
607
665
 
608
666
  # Adds a foreign key.
609
667
  #
610
- # t.foreign_key(:authors)
668
+ # t.foreign_key(:authors)
611
669
  #
612
670
  # See {connection.add_foreign_key}[rdoc-ref:SchemaStatements#add_foreign_key]
613
- def foreign_key(*args) # :nodoc:
671
+ def foreign_key(*args)
614
672
  @base.add_foreign_key(name, *args)
615
673
  end
616
674
 
617
675
  # Checks to see if a foreign key exists.
618
676
  #
619
- # t.foreign_key(:authors) unless t.foreign_key_exists?(:authors)
677
+ # t.foreign_key(:authors) unless t.foreign_key_exists?(:authors)
620
678
  #
621
679
  # See {connection.foreign_key_exists?}[rdoc-ref:SchemaStatements#foreign_key_exists?]
622
- def foreign_key_exists?(*args) # :nodoc:
680
+ def foreign_key_exists?(*args)
623
681
  @base.foreign_key_exists?(name, *args)
624
682
  end
625
683
  end
@@ -1,63 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/hash/compact"
4
+
1
5
  module ActiveRecord
2
6
  module ConnectionAdapters # :nodoc:
3
- # The goal of this module is to move Adapter specific column
4
- # definitions to the Adapter instead of having it in the schema
5
- # dumper itself. This code represents the normal case.
6
- # We can then redefine how certain data types may be handled in the schema dumper on the
7
- # Adapter level by over-writing this code inside the database specific adapters
8
- module ColumnDumper
9
- def column_spec(column)
10
- [schema_type_with_virtual(column), prepare_column_options(column)]
7
+ class SchemaDumper < SchemaDumper # :nodoc:
8
+ def self.create(connection, options)
9
+ new(connection, options)
11
10
  end
12
11
 
13
- def column_spec_for_primary_key(column)
14
- return {} if default_primary_key?(column)
15
- spec = { id: schema_type(column).inspect }
16
- spec.merge!(prepare_column_options(column).except!(:null))
17
- spec[:default] ||= "nil" if explicit_primary_key_default?(column)
18
- spec
19
- end
20
-
21
- # This can be overridden on an Adapter level basis to support other
22
- # extended datatypes (Example: Adding an array option in the
23
- # PostgreSQL::ColumnDumper)
24
- def prepare_column_options(column)
25
- spec = {}
26
-
27
- if limit = schema_limit(column)
28
- spec[:limit] = limit
12
+ private
13
+ def column_spec(column)
14
+ [schema_type_with_virtual(column), prepare_column_options(column)]
29
15
  end
30
16
 
31
- if precision = schema_precision(column)
32
- spec[:precision] = precision
17
+ def column_spec_for_primary_key(column)
18
+ return {} if default_primary_key?(column)
19
+ spec = { id: schema_type(column).inspect }
20
+ spec.merge!(prepare_column_options(column).except!(:null))
21
+ spec[:default] ||= "nil" if explicit_primary_key_default?(column)
22
+ spec
33
23
  end
34
24
 
35
- if scale = schema_scale(column)
36
- spec[:scale] = scale
25
+ def prepare_column_options(column)
26
+ spec = {}
27
+ spec[:limit] = schema_limit(column)
28
+ spec[:precision] = schema_precision(column)
29
+ spec[:scale] = schema_scale(column)
30
+ spec[:default] = schema_default(column)
31
+ spec[:null] = "false" unless column.null
32
+ spec[:collation] = schema_collation(column)
33
+ spec[:comment] = column.comment.inspect if column.comment.present?
34
+ spec.compact!
35
+ spec
37
36
  end
38
37
 
39
- default = schema_default(column) if column.has_default?
40
- spec[:default] = default unless default.nil?
41
-
42
- spec[:null] = "false" unless column.null
43
-
44
- if collation = schema_collation(column)
45
- spec[:collation] = collation
46
- end
47
-
48
- spec[:comment] = column.comment.inspect if column.comment.present?
49
-
50
- spec
51
- end
52
-
53
- # Lists the valid migration options
54
- def migration_keys # :nodoc:
55
- column_options_keys
56
- end
57
- deprecate :migration_keys
58
-
59
- private
60
-
61
38
  def default_primary_key?(column)
62
39
  schema_type(column) == :bigint
63
40
  end
@@ -67,7 +44,7 @@ module ActiveRecord
67
44
  end
68
45
 
69
46
  def schema_type_with_virtual(column)
70
- if supports_virtual_columns? && column.virtual?
47
+ if @connection.supports_virtual_columns? && column.virtual?
71
48
  :virtual
72
49
  else
73
50
  schema_type(column)
@@ -84,7 +61,7 @@ module ActiveRecord
84
61
 
85
62
  def schema_limit(column)
86
63
  limit = column.limit unless column.bigint?
87
- limit.inspect if limit && limit != native_database_types[column.type][:limit]
64
+ limit.inspect if limit && limit != @connection.native_database_types[column.type][:limit]
88
65
  end
89
66
 
90
67
  def schema_precision(column)
@@ -96,7 +73,8 @@ module ActiveRecord
96
73
  end
97
74
 
98
75
  def schema_default(column)
99
- type = lookup_cast_type_from_column(column)
76
+ return unless column.has_default?
77
+ type = @connection.lookup_cast_type_from_column(column)
100
78
  default = type.deserialize(column.default)
101
79
  if default.nil?
102
80
  schema_expression(column)