activerecord 5.0.7.2 → 5.1.0.beta1

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 (216) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +389 -2252
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +1 -1
  5. data/examples/performance.rb +28 -28
  6. data/examples/simple.rb +3 -3
  7. data/lib/active_record.rb +20 -20
  8. data/lib/active_record/aggregations.rb +244 -244
  9. data/lib/active_record/association_relation.rb +5 -5
  10. data/lib/active_record/associations.rb +1579 -1569
  11. data/lib/active_record/associations/alias_tracker.rb +1 -1
  12. data/lib/active_record/associations/association.rb +23 -15
  13. data/lib/active_record/associations/association_scope.rb +83 -81
  14. data/lib/active_record/associations/belongs_to_association.rb +0 -1
  15. data/lib/active_record/associations/builder/belongs_to.rb +16 -14
  16. data/lib/active_record/associations/builder/collection_association.rb +1 -2
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +27 -27
  18. data/lib/active_record/associations/collection_association.rb +74 -241
  19. data/lib/active_record/associations/collection_proxy.rb +144 -70
  20. data/lib/active_record/associations/has_many_association.rb +15 -19
  21. data/lib/active_record/associations/has_many_through_association.rb +12 -5
  22. data/lib/active_record/associations/has_one_association.rb +22 -28
  23. data/lib/active_record/associations/has_one_through_association.rb +5 -1
  24. data/lib/active_record/associations/join_dependency.rb +117 -115
  25. data/lib/active_record/associations/join_dependency/join_association.rb +16 -13
  26. data/lib/active_record/associations/join_dependency/join_base.rb +1 -1
  27. data/lib/active_record/associations/join_dependency/join_part.rb +1 -1
  28. data/lib/active_record/associations/preloader.rb +94 -94
  29. data/lib/active_record/associations/preloader/association.rb +87 -64
  30. data/lib/active_record/associations/preloader/belongs_to.rb +0 -2
  31. data/lib/active_record/associations/preloader/collection_association.rb +6 -6
  32. data/lib/active_record/associations/preloader/has_many.rb +0 -2
  33. data/lib/active_record/associations/preloader/singular_association.rb +6 -8
  34. data/lib/active_record/associations/preloader/through_association.rb +34 -41
  35. data/lib/active_record/associations/singular_association.rb +8 -25
  36. data/lib/active_record/associations/through_association.rb +3 -6
  37. data/lib/active_record/attribute.rb +98 -71
  38. data/lib/active_record/attribute/user_provided_default.rb +4 -2
  39. data/lib/active_record/attribute_assignment.rb +61 -61
  40. data/lib/active_record/attribute_decorators.rb +35 -13
  41. data/lib/active_record/attribute_methods.rb +56 -65
  42. data/lib/active_record/attribute_methods/before_type_cast.rb +7 -7
  43. data/lib/active_record/attribute_methods/dirty.rb +216 -34
  44. data/lib/active_record/attribute_methods/primary_key.rb +78 -73
  45. data/lib/active_record/attribute_methods/read.rb +39 -35
  46. data/lib/active_record/attribute_methods/serialization.rb +7 -7
  47. data/lib/active_record/attribute_methods/time_zone_conversion.rb +35 -58
  48. data/lib/active_record/attribute_methods/write.rb +36 -30
  49. data/lib/active_record/attribute_mutation_tracker.rb +53 -10
  50. data/lib/active_record/attribute_set.rb +9 -6
  51. data/lib/active_record/attribute_set/builder.rb +41 -49
  52. data/lib/active_record/attribute_set/yaml_encoder.rb +41 -0
  53. data/lib/active_record/attributes.rb +21 -21
  54. data/lib/active_record/autosave_association.rb +13 -13
  55. data/lib/active_record/base.rb +24 -22
  56. data/lib/active_record/callbacks.rb +52 -14
  57. data/lib/active_record/coders/yaml_column.rb +9 -11
  58. data/lib/active_record/collection_cache_key.rb +6 -17
  59. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +320 -278
  60. data/lib/active_record/connection_adapters/abstract/database_limits.rb +1 -3
  61. data/lib/active_record/connection_adapters/abstract/database_statements.rb +22 -34
  62. data/lib/active_record/connection_adapters/abstract/query_cache.rb +31 -27
  63. data/lib/active_record/connection_adapters/abstract/quoting.rb +44 -57
  64. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +9 -19
  65. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +78 -79
  66. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +53 -41
  67. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +99 -93
  68. data/lib/active_record/connection_adapters/abstract/transaction.rb +1 -5
  69. data/lib/active_record/connection_adapters/abstract_adapter.rb +156 -128
  70. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +424 -382
  71. data/lib/active_record/connection_adapters/column.rb +27 -5
  72. data/lib/active_record/connection_adapters/connection_specification.rb +128 -118
  73. data/lib/active_record/connection_adapters/mysql/column.rb +6 -31
  74. data/lib/active_record/connection_adapters/mysql/database_statements.rb +45 -43
  75. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +22 -22
  76. data/lib/active_record/connection_adapters/mysql/quoting.rb +6 -12
  77. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +49 -45
  78. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +16 -19
  79. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +49 -31
  80. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +5 -6
  81. data/lib/active_record/connection_adapters/mysql2_adapter.rb +24 -26
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +1 -28
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +46 -35
  84. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +3 -3
  85. data/lib/active_record/connection_adapters/postgresql/oid.rb +22 -21
  86. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +9 -9
  87. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +5 -3
  88. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +1 -1
  89. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +1 -1
  90. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -2
  91. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +3 -3
  92. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +16 -16
  93. data/lib/active_record/connection_adapters/postgresql/oid/{rails_5_1_point.rb → legacy_point.rb} +9 -16
  94. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
  95. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +13 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +28 -8
  97. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +28 -30
  98. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +2 -1
  99. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +51 -51
  100. data/lib/active_record/connection_adapters/postgresql/quoting.rb +38 -36
  101. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +15 -0
  102. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +37 -24
  103. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +19 -23
  104. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +161 -170
  105. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +4 -4
  106. data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -7
  107. data/lib/active_record/connection_adapters/postgresql_adapter.rb +179 -152
  108. data/lib/active_record/connection_adapters/schema_cache.rb +16 -7
  109. data/lib/active_record/connection_adapters/sql_type_metadata.rb +3 -3
  110. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +1 -1
  111. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +16 -20
  112. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +1 -8
  113. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +28 -0
  114. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +17 -0
  115. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +187 -130
  116. data/lib/active_record/connection_adapters/statement_pool.rb +7 -7
  117. data/lib/active_record/connection_handling.rb +14 -26
  118. data/lib/active_record/core.rb +110 -93
  119. data/lib/active_record/counter_cache.rb +62 -13
  120. data/lib/active_record/define_callbacks.rb +20 -0
  121. data/lib/active_record/dynamic_matchers.rb +80 -79
  122. data/lib/active_record/enum.rb +8 -6
  123. data/lib/active_record/errors.rb +58 -15
  124. data/lib/active_record/explain.rb +1 -2
  125. data/lib/active_record/explain_registry.rb +1 -1
  126. data/lib/active_record/explain_subscriber.rb +7 -4
  127. data/lib/active_record/fixture_set/file.rb +11 -8
  128. data/lib/active_record/fixtures.rb +66 -53
  129. data/lib/active_record/gem_version.rb +3 -3
  130. data/lib/active_record/inheritance.rb +93 -79
  131. data/lib/active_record/integration.rb +7 -7
  132. data/lib/active_record/internal_metadata.rb +3 -16
  133. data/lib/active_record/legacy_yaml_adapter.rb +1 -1
  134. data/lib/active_record/locking/optimistic.rb +64 -56
  135. data/lib/active_record/locking/pessimistic.rb +10 -1
  136. data/lib/active_record/log_subscriber.rb +29 -29
  137. data/lib/active_record/migration.rb +155 -172
  138. data/lib/active_record/migration/command_recorder.rb +94 -94
  139. data/lib/active_record/migration/compatibility.rb +76 -37
  140. data/lib/active_record/migration/join_table.rb +6 -6
  141. data/lib/active_record/model_schema.rb +85 -119
  142. data/lib/active_record/nested_attributes.rb +200 -199
  143. data/lib/active_record/null_relation.rb +10 -33
  144. data/lib/active_record/persistence.rb +45 -38
  145. data/lib/active_record/query_cache.rb +4 -8
  146. data/lib/active_record/querying.rb +2 -3
  147. data/lib/active_record/railtie.rb +16 -17
  148. data/lib/active_record/railties/controller_runtime.rb +6 -2
  149. data/lib/active_record/railties/databases.rake +125 -140
  150. data/lib/active_record/railties/jdbcmysql_error.rb +1 -1
  151. data/lib/active_record/readonly_attributes.rb +2 -2
  152. data/lib/active_record/reflection.rb +79 -96
  153. data/lib/active_record/relation.rb +72 -115
  154. data/lib/active_record/relation/batches.rb +87 -58
  155. data/lib/active_record/relation/batches/batch_enumerator.rb +1 -1
  156. data/lib/active_record/relation/calculations.rb +154 -160
  157. data/lib/active_record/relation/delegation.rb +30 -29
  158. data/lib/active_record/relation/finder_methods.rb +195 -226
  159. data/lib/active_record/relation/merger.rb +58 -62
  160. data/lib/active_record/relation/predicate_builder.rb +92 -89
  161. data/lib/active_record/relation/predicate_builder/array_handler.rb +7 -5
  162. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +23 -23
  163. data/lib/active_record/relation/predicate_builder/base_handler.rb +3 -1
  164. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +0 -8
  165. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +12 -10
  166. data/lib/active_record/relation/predicate_builder/range_handler.rb +0 -8
  167. data/lib/active_record/relation/query_attribute.rb +1 -1
  168. data/lib/active_record/relation/query_methods.rb +247 -295
  169. data/lib/active_record/relation/record_fetch_warning.rb +3 -3
  170. data/lib/active_record/relation/spawn_methods.rb +4 -5
  171. data/lib/active_record/relation/where_clause.rb +79 -65
  172. data/lib/active_record/relation/where_clause_factory.rb +47 -8
  173. data/lib/active_record/result.rb +29 -31
  174. data/lib/active_record/runtime_registry.rb +3 -3
  175. data/lib/active_record/sanitization.rb +182 -197
  176. data/lib/active_record/schema.rb +3 -3
  177. data/lib/active_record/schema_dumper.rb +14 -37
  178. data/lib/active_record/schema_migration.rb +3 -3
  179. data/lib/active_record/scoping.rb +9 -10
  180. data/lib/active_record/scoping/default.rb +87 -91
  181. data/lib/active_record/scoping/named.rb +16 -28
  182. data/lib/active_record/secure_token.rb +2 -2
  183. data/lib/active_record/statement_cache.rb +13 -15
  184. data/lib/active_record/store.rb +31 -32
  185. data/lib/active_record/suppressor.rb +2 -1
  186. data/lib/active_record/table_metadata.rb +9 -5
  187. data/lib/active_record/tasks/database_tasks.rb +72 -65
  188. data/lib/active_record/tasks/mysql_database_tasks.rb +75 -72
  189. data/lib/active_record/tasks/postgresql_database_tasks.rb +53 -48
  190. data/lib/active_record/tasks/sqlite_database_tasks.rb +18 -16
  191. data/lib/active_record/timestamp.rb +39 -25
  192. data/lib/active_record/touch_later.rb +1 -2
  193. data/lib/active_record/transactions.rb +98 -110
  194. data/lib/active_record/type.rb +17 -13
  195. data/lib/active_record/type/adapter_specific_registry.rb +46 -42
  196. data/lib/active_record/type/decimal_without_scale.rb +9 -0
  197. data/lib/active_record/type/hash_lookup_type_map.rb +3 -3
  198. data/lib/active_record/type/serialized.rb +8 -8
  199. data/lib/active_record/type/text.rb +9 -0
  200. data/lib/active_record/type/time.rb +0 -1
  201. data/lib/active_record/type/type_map.rb +11 -15
  202. data/lib/active_record/type/unsigned_integer.rb +15 -0
  203. data/lib/active_record/type_caster.rb +2 -2
  204. data/lib/active_record/type_caster/connection.rb +8 -6
  205. data/lib/active_record/type_caster/map.rb +3 -1
  206. data/lib/active_record/validations.rb +4 -4
  207. data/lib/active_record/validations/associated.rb +1 -1
  208. data/lib/active_record/validations/presence.rb +2 -2
  209. data/lib/active_record/validations/uniqueness.rb +8 -39
  210. data/lib/active_record/version.rb +1 -1
  211. data/lib/rails/generators/active_record.rb +4 -4
  212. data/lib/rails/generators/active_record/migration.rb +2 -2
  213. data/lib/rails/generators/active_record/migration/migration_generator.rb +37 -34
  214. data/lib/rails/generators/active_record/model/model_generator.rb +9 -9
  215. metadata +22 -13
  216. data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
@@ -1,7 +1,6 @@
1
1
  module ActiveRecord
2
2
  module ConnectionAdapters # :nodoc:
3
3
  module DatabaseLimits
4
-
5
4
  # Returns the maximum length of a table alias.
6
5
  def table_alias_length
7
6
  255
@@ -47,7 +46,7 @@ module ActiveRecord
47
46
  end
48
47
 
49
48
  # Returns the maximum number of elements in an IN (x,y,z) clause.
50
- # nil means no limit.
49
+ # +nil+ means no limit.
51
50
  def in_clause_length
52
51
  nil
53
52
  end
@@ -61,7 +60,6 @@ module ActiveRecord
61
60
  def joins_per_query
62
61
  256
63
62
  end
64
-
65
63
  end
66
64
  end
67
65
  end
@@ -10,19 +10,20 @@ module ActiveRecord
10
10
  def to_sql(arel, binds = [])
11
11
  if arel.respond_to?(:ast)
12
12
  collected = visitor.accept(arel.ast, collector)
13
- collected.compile(binds.dup, self)
13
+ collected.compile(binds, self).freeze
14
14
  else
15
- arel
15
+ arel.dup.freeze
16
16
  end
17
17
  end
18
18
 
19
19
  # This is used in the StatementCache object. It returns an object that
20
20
  # can be used to query the database repeatedly.
21
- def cacheable_query(arel) # :nodoc:
21
+ def cacheable_query(klass, arel) # :nodoc:
22
+ collected = visitor.accept(arel.ast, collector)
22
23
  if prepared_statements
23
- ActiveRecord::StatementCache.query visitor, arel.ast
24
+ klass.query(collected.value)
24
25
  else
25
- ActiveRecord::StatementCache.partial_query visitor, arel.ast, collector
26
+ klass.partial_query(collected.value)
26
27
  end
27
28
  end
28
29
 
@@ -50,8 +51,7 @@ module ActiveRecord
50
51
 
51
52
  # Returns a single value from a record
52
53
  def select_value(arel, name = nil, binds = [])
53
- arel, binds = binds_from_relation arel, binds
54
- if result = select_rows(to_sql(arel, binds), name, binds).first
54
+ if result = select_rows(arel, name, binds).first
55
55
  result.first
56
56
  end
57
57
  end
@@ -59,14 +59,13 @@ module ActiveRecord
59
59
  # Returns an array of the values of the first column in a select:
60
60
  # select_values("SELECT id FROM companies LIMIT 3") => [1,2,3]
61
61
  def select_values(arel, name = nil, binds = [])
62
- arel, binds = binds_from_relation arel, binds
63
- select_rows(to_sql(arel, binds), name, binds).map(&:first)
62
+ select_rows(arel, name, binds).map(&:first)
64
63
  end
65
64
 
66
65
  # Returns an array of arrays containing the field values.
67
66
  # Order is the same as that returned by +columns+.
68
- def select_rows(sql, name = nil, binds = [])
69
- exec_query(sql, name, binds).rows
67
+ def select_rows(arel, name = nil, binds = [])
68
+ select_all(arel, name, binds).rows
70
69
  end
71
70
 
72
71
  # Executes the SQL statement in the context of this connection and returns
@@ -81,21 +80,22 @@ module ActiveRecord
81
80
  # Executes +sql+ statement in the context of this connection using
82
81
  # +binds+ as the bind substitutes. +name+ is logged along with
83
82
  # the executed +sql+ statement.
84
- def exec_query(sql, name = 'SQL', binds = [], prepare: false)
83
+ def exec_query(sql, name = "SQL", binds = [], prepare: false)
85
84
  raise NotImplementedError
86
85
  end
87
86
 
88
87
  # Executes insert +sql+ statement in the context of this connection using
89
88
  # +binds+ as the bind substitutes. +name+ is logged along with
90
89
  # the executed +sql+ statement.
91
- def exec_insert(sql, name, binds, pk = nil, sequence_name = nil)
90
+ def exec_insert(sql, name = nil, binds = [], pk = nil, sequence_name = nil)
91
+ sql, binds = sql_for_insert(sql, pk, nil, sequence_name, binds)
92
92
  exec_query(sql, name, binds)
93
93
  end
94
94
 
95
95
  # Executes delete +sql+ statement in the context of this connection using
96
96
  # +binds+ as the bind substitutes. +name+ is logged along with
97
97
  # the executed +sql+ statement.
98
- def exec_delete(sql, name, binds)
98
+ def exec_delete(sql, name = nil, binds = [])
99
99
  exec_query(sql, name, binds)
100
100
  end
101
101
 
@@ -107,40 +107,33 @@ module ActiveRecord
107
107
  # Executes update +sql+ statement in the context of this connection using
108
108
  # +binds+ as the bind substitutes. +name+ is logged along with
109
109
  # the executed +sql+ statement.
110
- def exec_update(sql, name, binds)
110
+ def exec_update(sql, name = nil, binds = [])
111
111
  exec_query(sql, name, binds)
112
112
  end
113
113
 
114
114
  # Executes an INSERT query and returns the new record's ID
115
115
  #
116
- # +id_value+ will be returned unless the value is nil, in
116
+ # +id_value+ will be returned unless the value is +nil+, in
117
117
  # which case the database will attempt to calculate the last inserted
118
118
  # id and return that value.
119
119
  #
120
120
  # If the next id was calculated in advance (as in Oracle), it should be
121
121
  # passed in as +id_value+.
122
122
  def insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [])
123
- sql, binds, pk, sequence_name = sql_for_insert(to_sql(arel, binds), pk, id_value, sequence_name, binds)
124
- value = exec_insert(sql, name, binds, pk, sequence_name)
123
+ value = exec_insert(to_sql(arel, binds), name, binds, pk, sequence_name)
125
124
  id_value || last_inserted_id(value)
126
125
  end
127
126
  alias create insert
128
- alias insert_sql insert
129
- deprecate insert_sql: :insert
130
127
 
131
128
  # Executes the update statement and returns the number of rows affected.
132
129
  def update(arel, name = nil, binds = [])
133
130
  exec_update(to_sql(arel, binds), name, binds)
134
131
  end
135
- alias update_sql update
136
- deprecate update_sql: :update
137
132
 
138
133
  # Executes the delete statement and returns the number of rows affected.
139
134
  def delete(arel, name = nil, binds = [])
140
135
  exec_delete(to_sql(arel, binds), name, binds)
141
136
  end
142
- alias delete_sql delete
143
- deprecate delete_sql: :delete
144
137
 
145
138
  # Returns +true+ when the connection adapter supports prepared statement
146
139
  # caching, otherwise returns +false+
@@ -315,7 +308,7 @@ module ActiveRecord
315
308
  end
316
309
  end
317
310
  key_list = fixture.keys.map { |name| quote_column_name(name) }
318
- value_list = prepare_binds_for_database(binds).map do |value|
311
+ value_list = binds.map(&:value_for_database).map do |value|
319
312
  begin
320
313
  quote(value)
321
314
  rescue TypeError
@@ -323,7 +316,7 @@ module ActiveRecord
323
316
  end
324
317
  end
325
318
 
326
- execute "INSERT INTO #{quote_table_name(table_name)} (#{key_list.join(', ')}) VALUES (#{value_list.join(', ')})", 'Fixture Insert'
319
+ execute "INSERT INTO #{quote_table_name(table_name)} (#{key_list.join(', ')}) VALUES (#{value_list.join(', ')})", "Fixture Insert"
327
320
  end
328
321
 
329
322
  def empty_insert_statement_value
@@ -333,17 +326,12 @@ module ActiveRecord
333
326
  # Sanitizes the given LIMIT parameter in order to prevent SQL injection.
334
327
  #
335
328
  # The +limit+ may be anything that can evaluate to a string via #to_s. It
336
- # should look like an integer, or a comma-delimited list of integers, or
337
- # an Arel SQL literal.
329
+ # should look like an integer, or an Arel SQL literal.
338
330
  #
339
331
  # Returns Integer and Arel::Nodes::SqlLiteral limits as is.
340
- # Returns the sanitized limit parameter, either as an integer, or as a
341
- # string which contains a comma-delimited list of integers.
342
332
  def sanitize_limit(limit)
343
333
  if limit.is_a?(Integer) || limit.is_a?(Arel::Nodes::SqlLiteral)
344
334
  limit
345
- elsif limit.to_s.include?(',')
346
- Arel.sql limit.to_s.split(',').map{ |i| Integer(i) }.join(',')
347
335
  else
348
336
  Integer(limit)
349
337
  end
@@ -359,7 +347,7 @@ module ActiveRecord
359
347
  end
360
348
  alias join_to_delete join_to_update
361
349
 
362
- protected
350
+ private
363
351
 
364
352
  # Returns a subquery for the given key using the join information.
365
353
  def subquery_for(key, select)
@@ -378,7 +366,7 @@ module ActiveRecord
378
366
  end
379
367
 
380
368
  def sql_for_insert(sql, pk, id_value, sequence_name, binds)
381
- [sql, binds, pk, sequence_name]
369
+ [sql, binds]
382
370
  end
383
371
 
384
372
  def last_inserted_id(result)
@@ -46,7 +46,7 @@ module ActiveRecord
46
46
 
47
47
  def initialize(*)
48
48
  super
49
- @query_cache = Hash.new { |h,sql| h[sql] = {} }
49
+ @query_cache = Hash.new { |h, sql| h[sql] = {} }
50
50
  @query_cache_enabled = false
51
51
  end
52
52
 
@@ -83,14 +83,16 @@ module ActiveRecord
83
83
  # the same SQL query and repeatedly return the same result each time, silently
84
84
  # undermining the randomness you were expecting.
85
85
  def clear_query_cache
86
- @query_cache.clear
86
+ @lock.synchronize do
87
+ @query_cache.clear
88
+ end
87
89
  end
88
90
 
89
91
  def select_all(arel, name = nil, binds = [], preparable: nil)
90
92
  if @query_cache_enabled && !locked?(arel)
91
93
  arel, binds = binds_from_relation arel, binds
92
94
  sql = to_sql(arel, binds)
93
- cache_sql(sql, binds) { super(sql, name, binds, preparable: preparable) }
95
+ cache_sql(sql, name, binds) { super(sql, name, binds, preparable: preparable) }
94
96
  else
95
97
  super
96
98
  end
@@ -98,33 +100,35 @@ module ActiveRecord
98
100
 
99
101
  private
100
102
 
101
- def cache_sql(sql, binds)
102
- result =
103
- if @query_cache[sql].key?(binds)
104
- ActiveSupport::Notifications.instrument(
105
- "sql.active_record",
106
- sql: sql,
107
- binds: binds,
108
- type_casted_binds: -> { type_casted_binds(binds) },
109
- name: "CACHE",
110
- connection_id: object_id,
111
- )
112
- @query_cache[sql][binds]
113
- else
114
- @query_cache[sql][binds] = yield
103
+ def cache_sql(sql, name, binds)
104
+ @lock.synchronize do
105
+ result =
106
+ if @query_cache[sql].key?(binds)
107
+ ActiveSupport::Notifications.instrument(
108
+ "sql.active_record",
109
+ sql: sql,
110
+ binds: binds,
111
+ name: name,
112
+ connection_id: object_id,
113
+ cached: true,
114
+ )
115
+ @query_cache[sql][binds]
116
+ else
117
+ @query_cache[sql][binds] = yield
118
+ end
119
+ result.dup
115
120
  end
116
- result.dup
117
- end
121
+ end
118
122
 
119
- # If arel is locked this is a SELECT ... FOR UPDATE or somesuch. Such
120
- # queries should not be cached.
121
- def locked?(arel)
122
- arel.respond_to?(:locked) && arel.locked
123
- end
123
+ # If arel is locked this is a SELECT ... FOR UPDATE or somesuch. Such
124
+ # queries should not be cached.
125
+ def locked?(arel)
126
+ arel.respond_to?(:locked) && arel.locked
127
+ end
124
128
 
125
- def configure_query_cache!
126
- enable_query_cache! if pool.query_cache_enabled
127
- end
129
+ def configure_query_cache!
130
+ enable_query_cache! if pool.query_cache_enabled
131
+ end
128
132
  end
129
133
  end
130
134
  end
@@ -1,4 +1,4 @@
1
- require 'active_support/core_ext/big_decimal/conversions'
1
+ require "active_support/core_ext/big_decimal/conversions"
2
2
  require "active_support/multibyte/chars"
3
3
 
4
4
  module ActiveRecord
@@ -6,20 +6,10 @@ module ActiveRecord
6
6
  module Quoting
7
7
  # Quotes the column value to help prevent
8
8
  # {SQL injection attacks}[http://en.wikipedia.org/wiki/SQL_injection].
9
- def quote(value, column = nil)
9
+ def quote(value)
10
10
  # records are quoted as their primary key
11
11
  return value.quoted_id if value.respond_to?(:quoted_id)
12
12
 
13
- if column
14
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
15
- Passing a column to `quote` has been deprecated. It is only used
16
- for type casting, which should be handled elsewhere. See
17
- https://github.com/rails/arel/commit/6160bfbda1d1781c3b08a33ec4955f170e95be11
18
- for more information.
19
- MSG
20
- value = type_cast_from_column(column, value)
21
- end
22
-
23
13
  _quote(value)
24
14
  end
25
15
 
@@ -117,7 +107,7 @@ module ActiveRecord
117
107
  end
118
108
 
119
109
  def unquoted_true
120
- 't'.freeze
110
+ "t".freeze
121
111
  end
122
112
 
123
113
  def quoted_false
@@ -125,7 +115,7 @@ module ActiveRecord
125
115
  end
126
116
 
127
117
  def unquoted_false
128
- 'f'.freeze
118
+ "f".freeze
129
119
  end
130
120
 
131
121
  # Quote date/time values for use in SQL input. Includes microseconds
@@ -148,60 +138,57 @@ module ActiveRecord
148
138
  end
149
139
 
150
140
  def quoted_time(value) # :nodoc:
151
- quoted_date(value).sub(/\A\d\d\d\d-\d\d-\d\d /, '')
141
+ quoted_date(value).sub(/\A2000-01-01 /, "")
152
142
  end
153
143
 
154
- def prepare_binds_for_database(binds) # :nodoc:
155
- binds.map(&:value_for_database)
144
+ def quoted_binary(value) # :nodoc:
145
+ "'#{quote_string(value.to_s)}'"
156
146
  end
157
147
 
158
- def type_casted_binds(binds) # :nodoc:
159
- if binds.first.is_a?(Array)
160
- binds.map { |column, value| type_cast(value, column) }
161
- else
148
+ private
149
+
150
+ def type_casted_binds(binds)
162
151
  binds.map { |attr| type_cast(attr.value_for_database) }
163
152
  end
164
- end
165
153
 
166
- private
154
+ def types_which_need_no_typecasting
155
+ [nil, Numeric, String]
156
+ end
167
157
 
168
- def types_which_need_no_typecasting
169
- [nil, Numeric, String]
170
- end
171
-
172
- def _quote(value)
173
- case value
174
- when String, ActiveSupport::Multibyte::Chars, Type::Binary::Data
175
- "'#{quote_string(value.to_s)}'"
176
- when true then quoted_true
177
- when false then quoted_false
178
- when nil then "NULL"
179
- # BigDecimals need to be put in a non-normalized form and quoted.
180
- when BigDecimal then value.to_s('F')
181
- when Numeric, ActiveSupport::Duration then value.to_s
182
- when Type::Time::Value then "'#{quoted_time(value)}'"
183
- when Date, Time then "'#{quoted_date(value)}'"
184
- when Symbol then "'#{quote_string(value.to_s)}'"
185
- when Class then "'#{value}'"
186
- else raise TypeError, "can't quote #{value.class.name}"
158
+ def _quote(value)
159
+ case value
160
+ when String, ActiveSupport::Multibyte::Chars
161
+ "'#{quote_string(value.to_s)}'"
162
+ when true then quoted_true
163
+ when false then quoted_false
164
+ when nil then "NULL"
165
+ # BigDecimals need to be put in a non-normalized form and quoted.
166
+ when BigDecimal then value.to_s("F")
167
+ when Numeric, ActiveSupport::Duration then value.to_s
168
+ when Type::Binary::Data then quoted_binary(value)
169
+ when Type::Time::Value then "'#{quoted_time(value)}'"
170
+ when Date, Time then "'#{quoted_date(value)}'"
171
+ when Symbol then "'#{quote_string(value.to_s)}'"
172
+ when Class then "'#{value}'"
173
+ else raise TypeError, "can't quote #{value.class.name}"
174
+ end
187
175
  end
188
- end
189
176
 
190
- def _type_cast(value)
191
- case value
192
- when Symbol, ActiveSupport::Multibyte::Chars, Type::Binary::Data
193
- value.to_s
194
- when true then unquoted_true
195
- when false then unquoted_false
196
- # BigDecimals need to be put in a non-normalized form and quoted.
197
- when BigDecimal then value.to_s('F')
198
- when Type::Time::Value then quoted_time(value)
199
- when Date, Time then quoted_date(value)
200
- when *types_which_need_no_typecasting
201
- value
202
- else raise TypeError
177
+ def _type_cast(value)
178
+ case value
179
+ when Symbol, ActiveSupport::Multibyte::Chars, Type::Binary::Data
180
+ value.to_s
181
+ when true then unquoted_true
182
+ when false then unquoted_false
183
+ # BigDecimals need to be put in a non-normalized form and quoted.
184
+ when BigDecimal then value.to_s("F")
185
+ when Type::Time::Value then quoted_time(value)
186
+ when Date, Time then quoted_date(value)
187
+ when *types_which_need_no_typecasting
188
+ value
189
+ else raise TypeError
190
+ end
203
191
  end
204
- end
205
192
  end
206
193
  end
207
194
  end
@@ -1,4 +1,4 @@
1
- require 'active_support/core_ext/string/strip'
1
+ require "active_support/core_ext/string/strip"
2
2
 
3
3
  module ActiveRecord
4
4
  module ConnectionAdapters
@@ -15,21 +15,21 @@ module ActiveRecord
15
15
  end
16
16
 
17
17
  delegate :quote_column_name, :quote_table_name, :quote_default_expression, :type_to_sql,
18
- :options_include_default?, :supports_indexes_in_create?, :supports_foreign_keys?, :foreign_key_options, to: :@conn
18
+ :options_include_default?, :supports_indexes_in_create?, :supports_foreign_keys_in_create?, :foreign_key_options, to: :@conn
19
19
  private :quote_column_name, :quote_table_name, :quote_default_expression, :type_to_sql,
20
- :options_include_default?, :supports_indexes_in_create?, :supports_foreign_keys?, :foreign_key_options
20
+ :options_include_default?, :supports_indexes_in_create?, :supports_foreign_keys_in_create?, :foreign_key_options
21
21
 
22
22
  private
23
23
 
24
24
  def visit_AlterTable(o)
25
25
  sql = "ALTER TABLE #{quote_table_name(o.name)} "
26
- sql << o.adds.map { |col| accept col }.join(' ')
27
- sql << o.foreign_key_adds.map { |fk| visit_AddForeignKey fk }.join(' ')
28
- sql << o.foreign_key_drops.map { |fk| visit_DropForeignKey fk }.join(' ')
26
+ sql << o.adds.map { |col| accept col }.join(" ")
27
+ sql << o.foreign_key_adds.map { |fk| visit_AddForeignKey fk }.join(" ")
28
+ sql << o.foreign_key_drops.map { |fk| visit_DropForeignKey fk }.join(" ")
29
29
  end
30
30
 
31
31
  def visit_ColumnDefinition(o)
32
- o.sql_type ||= type_to_sql(o.type, o.limit, o.precision, o.scale)
32
+ o.sql_type = type_to_sql(o.type, o.options)
33
33
  column_sql = "#{quote_column_name(o.name)} #{o.sql_type}"
34
34
  add_column_options!(column_sql, column_options(o)) unless o.type == :primary_key
35
35
  column_sql
@@ -49,7 +49,7 @@ module ActiveRecord
49
49
  statements.concat(o.indexes.map { |column_name, options| index_in_create(o.name, column_name, options) })
50
50
  end
51
51
 
52
- if supports_foreign_keys?
52
+ if supports_foreign_keys_in_create?
53
53
  statements.concat(o.foreign_keys.map { |to_table, options| foreign_key_in_create(o.name, to_table, options) })
54
54
  end
55
55
 
@@ -96,17 +96,7 @@ module ActiveRecord
96
96
  end
97
97
 
98
98
  def column_options(o)
99
- column_options = {}
100
- column_options[:null] = o.null unless o.null.nil?
101
- column_options[:default] = o.default unless o.default.nil?
102
- column_options[:column] = o
103
- column_options[:first] = o.first
104
- column_options[:after] = o.after
105
- column_options[:auto_increment] = o.auto_increment
106
- column_options[:primary_key] = o.primary_key
107
- column_options[:collation] = o.collation
108
- column_options[:comment] = o.comment
109
- column_options
99
+ o.options.merge(column: o)
110
100
  end
111
101
 
112
102
  def add_column_options!(sql, options)