activerecord 5.2.3 → 6.0.0

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

Potentially problematic release.


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

Files changed (268) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +624 -548
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +4 -2
  5. data/examples/performance.rb +1 -1
  6. data/lib/active_record.rb +9 -2
  7. data/lib/active_record/aggregations.rb +4 -2
  8. data/lib/active_record/associations.rb +19 -14
  9. data/lib/active_record/associations/association.rb +52 -19
  10. data/lib/active_record/associations/association_scope.rb +4 -6
  11. data/lib/active_record/associations/belongs_to_association.rb +36 -42
  12. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +0 -4
  13. data/lib/active_record/associations/builder/association.rb +14 -18
  14. data/lib/active_record/associations/builder/belongs_to.rb +19 -52
  15. data/lib/active_record/associations/builder/collection_association.rb +5 -15
  16. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +17 -38
  17. data/lib/active_record/associations/builder/has_many.rb +2 -0
  18. data/lib/active_record/associations/builder/has_one.rb +35 -1
  19. data/lib/active_record/associations/builder/singular_association.rb +2 -0
  20. data/lib/active_record/associations/collection_association.rb +6 -21
  21. data/lib/active_record/associations/collection_proxy.rb +12 -15
  22. data/lib/active_record/associations/foreign_association.rb +7 -0
  23. data/lib/active_record/associations/has_many_association.rb +2 -10
  24. data/lib/active_record/associations/has_many_through_association.rb +18 -25
  25. data/lib/active_record/associations/has_one_association.rb +28 -30
  26. data/lib/active_record/associations/has_one_through_association.rb +5 -5
  27. data/lib/active_record/associations/join_dependency.rb +24 -28
  28. data/lib/active_record/associations/join_dependency/join_association.rb +27 -7
  29. data/lib/active_record/associations/join_dependency/join_part.rb +2 -2
  30. data/lib/active_record/associations/preloader.rb +39 -31
  31. data/lib/active_record/associations/preloader/association.rb +38 -36
  32. data/lib/active_record/associations/preloader/through_association.rb +48 -39
  33. data/lib/active_record/associations/singular_association.rb +2 -16
  34. data/lib/active_record/attribute_assignment.rb +7 -10
  35. data/lib/active_record/attribute_methods.rb +28 -100
  36. data/lib/active_record/attribute_methods/before_type_cast.rb +4 -1
  37. data/lib/active_record/attribute_methods/dirty.rb +111 -40
  38. data/lib/active_record/attribute_methods/primary_key.rb +15 -22
  39. data/lib/active_record/attribute_methods/query.rb +2 -3
  40. data/lib/active_record/attribute_methods/read.rb +15 -53
  41. data/lib/active_record/attribute_methods/serialization.rb +1 -1
  42. data/lib/active_record/attribute_methods/time_zone_conversion.rb +1 -1
  43. data/lib/active_record/attribute_methods/write.rb +17 -24
  44. data/lib/active_record/attributes.rb +13 -0
  45. data/lib/active_record/autosave_association.rb +16 -6
  46. data/lib/active_record/base.rb +2 -3
  47. data/lib/active_record/callbacks.rb +5 -19
  48. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +116 -19
  49. data/lib/active_record/connection_adapters/abstract/database_limits.rb +17 -4
  50. data/lib/active_record/connection_adapters/abstract/database_statements.rb +95 -123
  51. data/lib/active_record/connection_adapters/abstract/query_cache.rb +20 -11
  52. data/lib/active_record/connection_adapters/abstract/quoting.rb +68 -17
  53. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +19 -12
  54. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +76 -48
  55. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +1 -3
  56. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +133 -54
  57. data/lib/active_record/connection_adapters/abstract/transaction.rb +96 -56
  58. data/lib/active_record/connection_adapters/abstract_adapter.rb +180 -47
  59. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +128 -194
  60. data/lib/active_record/connection_adapters/column.rb +17 -13
  61. data/lib/active_record/connection_adapters/connection_specification.rb +52 -42
  62. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +6 -10
  63. data/lib/active_record/connection_adapters/mysql/database_statements.rb +73 -13
  64. data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -7
  65. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +3 -4
  66. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +40 -32
  67. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +14 -6
  68. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +129 -13
  69. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +6 -10
  70. data/lib/active_record/connection_adapters/mysql2_adapter.rb +26 -9
  71. data/lib/active_record/connection_adapters/postgresql/column.rb +17 -31
  72. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +20 -1
  73. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
  74. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
  75. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +1 -1
  76. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +1 -1
  77. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
  78. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +1 -1
  79. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +1 -1
  80. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +9 -7
  81. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +6 -3
  82. data/lib/active_record/connection_adapters/postgresql/quoting.rb +44 -7
  83. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +12 -1
  84. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -91
  85. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +55 -53
  86. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +24 -27
  87. data/lib/active_record/connection_adapters/postgresql_adapter.rb +160 -74
  88. data/lib/active_record/connection_adapters/schema_cache.rb +37 -14
  89. data/lib/active_record/connection_adapters/sql_type_metadata.rb +11 -8
  90. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +118 -0
  91. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +42 -6
  92. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +42 -11
  93. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +127 -143
  94. data/lib/active_record/connection_handling.rb +149 -27
  95. data/lib/active_record/core.rb +100 -60
  96. data/lib/active_record/counter_cache.rb +4 -29
  97. data/lib/active_record/database_configurations.rb +233 -0
  98. data/lib/active_record/database_configurations/database_config.rb +37 -0
  99. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  100. data/lib/active_record/database_configurations/url_config.rb +79 -0
  101. data/lib/active_record/dynamic_matchers.rb +1 -1
  102. data/lib/active_record/enum.rb +37 -7
  103. data/lib/active_record/errors.rb +15 -7
  104. data/lib/active_record/explain.rb +1 -1
  105. data/lib/active_record/fixture_set/model_metadata.rb +33 -0
  106. data/lib/active_record/fixture_set/render_context.rb +17 -0
  107. data/lib/active_record/fixture_set/table_row.rb +153 -0
  108. data/lib/active_record/fixture_set/table_rows.rb +47 -0
  109. data/lib/active_record/fixtures.rb +145 -472
  110. data/lib/active_record/gem_version.rb +3 -3
  111. data/lib/active_record/inheritance.rb +13 -3
  112. data/lib/active_record/insert_all.rb +179 -0
  113. data/lib/active_record/integration.rb +68 -16
  114. data/lib/active_record/internal_metadata.rb +10 -2
  115. data/lib/active_record/locking/optimistic.rb +5 -6
  116. data/lib/active_record/locking/pessimistic.rb +3 -3
  117. data/lib/active_record/log_subscriber.rb +7 -26
  118. data/lib/active_record/middleware/database_selector.rb +75 -0
  119. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  120. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  121. data/lib/active_record/migration.rb +100 -81
  122. data/lib/active_record/migration/command_recorder.rb +50 -6
  123. data/lib/active_record/migration/compatibility.rb +76 -49
  124. data/lib/active_record/model_schema.rb +30 -9
  125. data/lib/active_record/nested_attributes.rb +2 -2
  126. data/lib/active_record/no_touching.rb +7 -0
  127. data/lib/active_record/persistence.rb +228 -24
  128. data/lib/active_record/query_cache.rb +11 -4
  129. data/lib/active_record/querying.rb +32 -20
  130. data/lib/active_record/railtie.rb +80 -43
  131. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  132. data/lib/active_record/railties/controller_runtime.rb +30 -35
  133. data/lib/active_record/railties/databases.rake +196 -46
  134. data/lib/active_record/reflection.rb +42 -44
  135. data/lib/active_record/relation.rb +310 -80
  136. data/lib/active_record/relation/batches.rb +13 -10
  137. data/lib/active_record/relation/calculations.rb +58 -51
  138. data/lib/active_record/relation/delegation.rb +26 -43
  139. data/lib/active_record/relation/finder_methods.rb +14 -27
  140. data/lib/active_record/relation/merger.rb +11 -20
  141. data/lib/active_record/relation/predicate_builder.rb +4 -6
  142. data/lib/active_record/relation/predicate_builder/array_handler.rb +5 -4
  143. data/lib/active_record/relation/predicate_builder/association_query_value.rb +1 -4
  144. data/lib/active_record/relation/predicate_builder/base_handler.rb +1 -2
  145. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
  146. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +1 -4
  147. data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
  148. data/lib/active_record/relation/query_attribute.rb +13 -8
  149. data/lib/active_record/relation/query_methods.rb +206 -78
  150. data/lib/active_record/relation/spawn_methods.rb +1 -1
  151. data/lib/active_record/relation/where_clause.rb +14 -10
  152. data/lib/active_record/relation/where_clause_factory.rb +1 -2
  153. data/lib/active_record/result.rb +30 -11
  154. data/lib/active_record/sanitization.rb +32 -40
  155. data/lib/active_record/schema.rb +2 -11
  156. data/lib/active_record/schema_dumper.rb +22 -7
  157. data/lib/active_record/schema_migration.rb +5 -1
  158. data/lib/active_record/scoping.rb +8 -8
  159. data/lib/active_record/scoping/default.rb +6 -7
  160. data/lib/active_record/scoping/named.rb +19 -15
  161. data/lib/active_record/statement_cache.rb +32 -5
  162. data/lib/active_record/store.rb +87 -8
  163. data/lib/active_record/table_metadata.rb +10 -17
  164. data/lib/active_record/tasks/database_tasks.rb +194 -25
  165. data/lib/active_record/tasks/mysql_database_tasks.rb +5 -5
  166. data/lib/active_record/tasks/postgresql_database_tasks.rb +5 -7
  167. data/lib/active_record/tasks/sqlite_database_tasks.rb +2 -8
  168. data/lib/active_record/test_databases.rb +23 -0
  169. data/lib/active_record/test_fixtures.rb +224 -0
  170. data/lib/active_record/timestamp.rb +39 -25
  171. data/lib/active_record/touch_later.rb +4 -2
  172. data/lib/active_record/transactions.rb +56 -65
  173. data/lib/active_record/translation.rb +1 -1
  174. data/lib/active_record/type.rb +3 -4
  175. data/lib/active_record/type/adapter_specific_registry.rb +1 -8
  176. data/lib/active_record/type_caster/connection.rb +15 -14
  177. data/lib/active_record/type_caster/map.rb +1 -4
  178. data/lib/active_record/validations.rb +1 -0
  179. data/lib/active_record/validations/uniqueness.rb +15 -27
  180. data/lib/arel.rb +51 -0
  181. data/lib/arel/alias_predication.rb +9 -0
  182. data/lib/arel/attributes.rb +22 -0
  183. data/lib/arel/attributes/attribute.rb +37 -0
  184. data/lib/arel/collectors/bind.rb +24 -0
  185. data/lib/arel/collectors/composite.rb +31 -0
  186. data/lib/arel/collectors/plain_string.rb +20 -0
  187. data/lib/arel/collectors/sql_string.rb +20 -0
  188. data/lib/arel/collectors/substitute_binds.rb +28 -0
  189. data/lib/arel/crud.rb +42 -0
  190. data/lib/arel/delete_manager.rb +18 -0
  191. data/lib/arel/errors.rb +9 -0
  192. data/lib/arel/expressions.rb +29 -0
  193. data/lib/arel/factory_methods.rb +49 -0
  194. data/lib/arel/insert_manager.rb +49 -0
  195. data/lib/arel/math.rb +45 -0
  196. data/lib/arel/nodes.rb +68 -0
  197. data/lib/arel/nodes/and.rb +32 -0
  198. data/lib/arel/nodes/ascending.rb +23 -0
  199. data/lib/arel/nodes/binary.rb +52 -0
  200. data/lib/arel/nodes/bind_param.rb +36 -0
  201. data/lib/arel/nodes/case.rb +55 -0
  202. data/lib/arel/nodes/casted.rb +50 -0
  203. data/lib/arel/nodes/comment.rb +29 -0
  204. data/lib/arel/nodes/count.rb +12 -0
  205. data/lib/arel/nodes/delete_statement.rb +45 -0
  206. data/lib/arel/nodes/descending.rb +23 -0
  207. data/lib/arel/nodes/equality.rb +18 -0
  208. data/lib/arel/nodes/extract.rb +24 -0
  209. data/lib/arel/nodes/false.rb +16 -0
  210. data/lib/arel/nodes/full_outer_join.rb +8 -0
  211. data/lib/arel/nodes/function.rb +44 -0
  212. data/lib/arel/nodes/grouping.rb +8 -0
  213. data/lib/arel/nodes/in.rb +8 -0
  214. data/lib/arel/nodes/infix_operation.rb +80 -0
  215. data/lib/arel/nodes/inner_join.rb +8 -0
  216. data/lib/arel/nodes/insert_statement.rb +37 -0
  217. data/lib/arel/nodes/join_source.rb +20 -0
  218. data/lib/arel/nodes/matches.rb +18 -0
  219. data/lib/arel/nodes/named_function.rb +23 -0
  220. data/lib/arel/nodes/node.rb +50 -0
  221. data/lib/arel/nodes/node_expression.rb +13 -0
  222. data/lib/arel/nodes/outer_join.rb +8 -0
  223. data/lib/arel/nodes/over.rb +15 -0
  224. data/lib/arel/nodes/regexp.rb +16 -0
  225. data/lib/arel/nodes/right_outer_join.rb +8 -0
  226. data/lib/arel/nodes/select_core.rb +67 -0
  227. data/lib/arel/nodes/select_statement.rb +41 -0
  228. data/lib/arel/nodes/sql_literal.rb +16 -0
  229. data/lib/arel/nodes/string_join.rb +11 -0
  230. data/lib/arel/nodes/table_alias.rb +27 -0
  231. data/lib/arel/nodes/terminal.rb +16 -0
  232. data/lib/arel/nodes/true.rb +16 -0
  233. data/lib/arel/nodes/unary.rb +45 -0
  234. data/lib/arel/nodes/unary_operation.rb +20 -0
  235. data/lib/arel/nodes/unqualified_column.rb +22 -0
  236. data/lib/arel/nodes/update_statement.rb +41 -0
  237. data/lib/arel/nodes/values_list.rb +9 -0
  238. data/lib/arel/nodes/window.rb +126 -0
  239. data/lib/arel/nodes/with.rb +11 -0
  240. data/lib/arel/order_predications.rb +13 -0
  241. data/lib/arel/predications.rb +257 -0
  242. data/lib/arel/select_manager.rb +271 -0
  243. data/lib/arel/table.rb +110 -0
  244. data/lib/arel/tree_manager.rb +72 -0
  245. data/lib/arel/update_manager.rb +34 -0
  246. data/lib/arel/visitors.rb +20 -0
  247. data/lib/arel/visitors/depth_first.rb +204 -0
  248. data/lib/arel/visitors/dot.rb +297 -0
  249. data/lib/arel/visitors/ibm_db.rb +34 -0
  250. data/lib/arel/visitors/informix.rb +62 -0
  251. data/lib/arel/visitors/mssql.rb +157 -0
  252. data/lib/arel/visitors/mysql.rb +83 -0
  253. data/lib/arel/visitors/oracle.rb +159 -0
  254. data/lib/arel/visitors/oracle12.rb +66 -0
  255. data/lib/arel/visitors/postgresql.rb +110 -0
  256. data/lib/arel/visitors/sqlite.rb +39 -0
  257. data/lib/arel/visitors/to_sql.rb +889 -0
  258. data/lib/arel/visitors/visitor.rb +46 -0
  259. data/lib/arel/visitors/where_sql.rb +23 -0
  260. data/lib/arel/window_predications.rb +9 -0
  261. data/lib/rails/generators/active_record/migration.rb +14 -1
  262. data/lib/rails/generators/active_record/migration/migration_generator.rb +2 -5
  263. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +1 -1
  264. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +4 -2
  265. data/lib/rails/generators/active_record/model/model_generator.rb +1 -0
  266. data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
  267. metadata +107 -25
  268. data/lib/active_record/collection_cache_key.rb +0 -53
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arel # :nodoc: all
4
+ module Nodes
5
+ class SelectStatement < Arel::Nodes::NodeExpression
6
+ attr_reader :cores
7
+ attr_accessor :limit, :orders, :lock, :offset, :with
8
+
9
+ def initialize(cores = [SelectCore.new])
10
+ super()
11
+ @cores = cores
12
+ @orders = []
13
+ @limit = nil
14
+ @lock = nil
15
+ @offset = nil
16
+ @with = nil
17
+ end
18
+
19
+ def initialize_copy(other)
20
+ super
21
+ @cores = @cores.map { |x| x.clone }
22
+ @orders = @orders.map { |x| x.clone }
23
+ end
24
+
25
+ def hash
26
+ [@cores, @orders, @limit, @lock, @offset, @with].hash
27
+ end
28
+
29
+ def eql?(other)
30
+ self.class == other.class &&
31
+ self.cores == other.cores &&
32
+ self.orders == other.orders &&
33
+ self.limit == other.limit &&
34
+ self.lock == other.lock &&
35
+ self.offset == other.offset &&
36
+ self.with == other.with
37
+ end
38
+ alias :== :eql?
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arel # :nodoc: all
4
+ module Nodes
5
+ class SqlLiteral < String
6
+ include Arel::Expressions
7
+ include Arel::Predications
8
+ include Arel::AliasPredication
9
+ include Arel::OrderPredications
10
+
11
+ def encode_with(coder)
12
+ coder.scalar = self.to_s
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arel # :nodoc: all
4
+ module Nodes
5
+ class StringJoin < Arel::Nodes::Join
6
+ def initialize(left, right = nil)
7
+ super
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arel # :nodoc: all
4
+ module Nodes
5
+ class TableAlias < Arel::Nodes::Binary
6
+ alias :name :right
7
+ alias :relation :left
8
+ alias :table_alias :name
9
+
10
+ def [](name)
11
+ Attribute.new(self, name)
12
+ end
13
+
14
+ def table_name
15
+ relation.respond_to?(:name) ? relation.name : name
16
+ end
17
+
18
+ def type_cast_for_database(*args)
19
+ relation.type_cast_for_database(*args)
20
+ end
21
+
22
+ def able_to_type_cast?
23
+ relation.respond_to?(:able_to_type_cast?) && relation.able_to_type_cast?
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arel # :nodoc: all
4
+ module Nodes
5
+ class Distinct < Arel::Nodes::NodeExpression
6
+ def hash
7
+ self.class.hash
8
+ end
9
+
10
+ def eql?(other)
11
+ self.class == other.class
12
+ end
13
+ alias :== :eql?
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arel # :nodoc: all
4
+ module Nodes
5
+ class True < Arel::Nodes::NodeExpression
6
+ def hash
7
+ self.class.hash
8
+ end
9
+
10
+ def eql?(other)
11
+ self.class == other.class
12
+ end
13
+ alias :== :eql?
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arel # :nodoc: all
4
+ module Nodes
5
+ class Unary < Arel::Nodes::NodeExpression
6
+ attr_accessor :expr
7
+ alias :value :expr
8
+
9
+ def initialize(expr)
10
+ super()
11
+ @expr = expr
12
+ end
13
+
14
+ def hash
15
+ @expr.hash
16
+ end
17
+
18
+ def eql?(other)
19
+ self.class == other.class &&
20
+ self.expr == other.expr
21
+ end
22
+ alias :== :eql?
23
+ end
24
+
25
+ %w{
26
+ Bin
27
+ Cube
28
+ DistinctOn
29
+ Group
30
+ GroupingElement
31
+ GroupingSet
32
+ Lateral
33
+ Limit
34
+ Lock
35
+ Not
36
+ Offset
37
+ On
38
+ OptimizerHints
39
+ Ordering
40
+ RollUp
41
+ }.each do |name|
42
+ const_set(name, Class.new(Unary))
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arel # :nodoc: all
4
+ module Nodes
5
+ class UnaryOperation < Unary
6
+ attr_reader :operator
7
+
8
+ def initialize(operator, operand)
9
+ super(operand)
10
+ @operator = operator
11
+ end
12
+ end
13
+
14
+ class BitwiseNot < UnaryOperation
15
+ def initialize(operand)
16
+ super(:~, operand)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arel # :nodoc: all
4
+ module Nodes
5
+ class UnqualifiedColumn < Arel::Nodes::Unary
6
+ alias :attribute :expr
7
+ alias :attribute= :expr=
8
+
9
+ def relation
10
+ @expr.relation
11
+ end
12
+
13
+ def column
14
+ @expr.column
15
+ end
16
+
17
+ def name
18
+ @expr.name
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arel # :nodoc: all
4
+ module Nodes
5
+ class UpdateStatement < Arel::Nodes::Node
6
+ attr_accessor :relation, :wheres, :values, :orders, :limit, :offset, :key
7
+
8
+ def initialize
9
+ @relation = nil
10
+ @wheres = []
11
+ @values = []
12
+ @orders = []
13
+ @limit = nil
14
+ @offset = nil
15
+ @key = nil
16
+ end
17
+
18
+ def initialize_copy(other)
19
+ super
20
+ @wheres = @wheres.clone
21
+ @values = @values.clone
22
+ end
23
+
24
+ def hash
25
+ [@relation, @wheres, @values, @orders, @limit, @offset, @key].hash
26
+ end
27
+
28
+ def eql?(other)
29
+ self.class == other.class &&
30
+ self.relation == other.relation &&
31
+ self.wheres == other.wheres &&
32
+ self.values == other.values &&
33
+ self.orders == other.orders &&
34
+ self.limit == other.limit &&
35
+ self.offset == other.offset &&
36
+ self.key == other.key
37
+ end
38
+ alias :== :eql?
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arel # :nodoc: all
4
+ module Nodes
5
+ class ValuesList < Unary
6
+ alias :rows :expr
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,126 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arel # :nodoc: all
4
+ module Nodes
5
+ class Window < Arel::Nodes::Node
6
+ attr_accessor :orders, :framing, :partitions
7
+
8
+ def initialize
9
+ @orders = []
10
+ @partitions = []
11
+ @framing = nil
12
+ end
13
+
14
+ def order(*expr)
15
+ # FIXME: We SHOULD NOT be converting these to SqlLiteral automatically
16
+ @orders.concat expr.map { |x|
17
+ String === x || Symbol === x ? Nodes::SqlLiteral.new(x.to_s) : x
18
+ }
19
+ self
20
+ end
21
+
22
+ def partition(*expr)
23
+ # FIXME: We SHOULD NOT be converting these to SqlLiteral automatically
24
+ @partitions.concat expr.map { |x|
25
+ String === x || Symbol === x ? Nodes::SqlLiteral.new(x.to_s) : x
26
+ }
27
+ self
28
+ end
29
+
30
+ def frame(expr)
31
+ @framing = expr
32
+ end
33
+
34
+ def rows(expr = nil)
35
+ if @framing
36
+ Rows.new(expr)
37
+ else
38
+ frame(Rows.new(expr))
39
+ end
40
+ end
41
+
42
+ def range(expr = nil)
43
+ if @framing
44
+ Range.new(expr)
45
+ else
46
+ frame(Range.new(expr))
47
+ end
48
+ end
49
+
50
+ def initialize_copy(other)
51
+ super
52
+ @orders = @orders.map { |x| x.clone }
53
+ end
54
+
55
+ def hash
56
+ [@orders, @framing].hash
57
+ end
58
+
59
+ def eql?(other)
60
+ self.class == other.class &&
61
+ self.orders == other.orders &&
62
+ self.framing == other.framing &&
63
+ self.partitions == other.partitions
64
+ end
65
+ alias :== :eql?
66
+ end
67
+
68
+ class NamedWindow < Window
69
+ attr_accessor :name
70
+
71
+ def initialize(name)
72
+ super()
73
+ @name = name
74
+ end
75
+
76
+ def initialize_copy(other)
77
+ super
78
+ @name = other.name.clone
79
+ end
80
+
81
+ def hash
82
+ super ^ @name.hash
83
+ end
84
+
85
+ def eql?(other)
86
+ super && self.name == other.name
87
+ end
88
+ alias :== :eql?
89
+ end
90
+
91
+ class Rows < Unary
92
+ def initialize(expr = nil)
93
+ super(expr)
94
+ end
95
+ end
96
+
97
+ class Range < Unary
98
+ def initialize(expr = nil)
99
+ super(expr)
100
+ end
101
+ end
102
+
103
+ class CurrentRow < Node
104
+ def hash
105
+ self.class.hash
106
+ end
107
+
108
+ def eql?(other)
109
+ self.class == other.class
110
+ end
111
+ alias :== :eql?
112
+ end
113
+
114
+ class Preceding < Unary
115
+ def initialize(expr = nil)
116
+ super(expr)
117
+ end
118
+ end
119
+
120
+ class Following < Unary
121
+ def initialize(expr = nil)
122
+ super(expr)
123
+ end
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arel # :nodoc: all
4
+ module Nodes
5
+ class With < Arel::Nodes::Unary
6
+ alias children expr
7
+ end
8
+
9
+ class WithRecursive < With; end
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arel # :nodoc: all
4
+ module OrderPredications
5
+ def asc
6
+ Nodes::Ascending.new self
7
+ end
8
+
9
+ def desc
10
+ Nodes::Descending.new self
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,257 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arel # :nodoc: all
4
+ module Predications
5
+ def not_eq(other)
6
+ Nodes::NotEqual.new self, quoted_node(other)
7
+ end
8
+
9
+ def not_eq_any(others)
10
+ grouping_any :not_eq, others
11
+ end
12
+
13
+ def not_eq_all(others)
14
+ grouping_all :not_eq, others
15
+ end
16
+
17
+ def eq(other)
18
+ Nodes::Equality.new self, quoted_node(other)
19
+ end
20
+
21
+ def is_not_distinct_from(other)
22
+ Nodes::IsNotDistinctFrom.new self, quoted_node(other)
23
+ end
24
+
25
+ def is_distinct_from(other)
26
+ Nodes::IsDistinctFrom.new self, quoted_node(other)
27
+ end
28
+
29
+ def eq_any(others)
30
+ grouping_any :eq, others
31
+ end
32
+
33
+ def eq_all(others)
34
+ grouping_all :eq, quoted_array(others)
35
+ end
36
+
37
+ def between(other)
38
+ if unboundable?(other.begin) == 1 || unboundable?(other.end) == -1
39
+ self.in([])
40
+ elsif open_ended?(other.begin)
41
+ if other.end.nil? || open_ended?(other.end)
42
+ not_in([])
43
+ elsif other.exclude_end?
44
+ lt(other.end)
45
+ else
46
+ lteq(other.end)
47
+ end
48
+ elsif other.end.nil? || open_ended?(other.end)
49
+ gteq(other.begin)
50
+ elsif other.exclude_end?
51
+ gteq(other.begin).and(lt(other.end))
52
+ else
53
+ left = quoted_node(other.begin)
54
+ right = quoted_node(other.end)
55
+ Nodes::Between.new(self, left.and(right))
56
+ end
57
+ end
58
+
59
+ def in(other)
60
+ case other
61
+ when Arel::SelectManager
62
+ Arel::Nodes::In.new(self, other.ast)
63
+ when Range
64
+ if $VERBOSE
65
+ warn <<-eowarn
66
+ Passing a range to `#in` is deprecated. Call `#between`, instead.
67
+ eowarn
68
+ end
69
+ between(other)
70
+ when Enumerable
71
+ Nodes::In.new self, quoted_array(other)
72
+ else
73
+ Nodes::In.new self, quoted_node(other)
74
+ end
75
+ end
76
+
77
+ def in_any(others)
78
+ grouping_any :in, others
79
+ end
80
+
81
+ def in_all(others)
82
+ grouping_all :in, others
83
+ end
84
+
85
+ def not_between(other)
86
+ if unboundable?(other.begin) == 1 || unboundable?(other.end) == -1
87
+ not_in([])
88
+ elsif open_ended?(other.begin)
89
+ if other.end.nil? || open_ended?(other.end)
90
+ self.in([])
91
+ elsif other.exclude_end?
92
+ gteq(other.end)
93
+ else
94
+ gt(other.end)
95
+ end
96
+ elsif other.end.nil? || open_ended?(other.end)
97
+ lt(other.begin)
98
+ else
99
+ left = lt(other.begin)
100
+ right = if other.exclude_end?
101
+ gteq(other.end)
102
+ else
103
+ gt(other.end)
104
+ end
105
+ left.or(right)
106
+ end
107
+ end
108
+
109
+ def not_in(other)
110
+ case other
111
+ when Arel::SelectManager
112
+ Arel::Nodes::NotIn.new(self, other.ast)
113
+ when Range
114
+ if $VERBOSE
115
+ warn <<-eowarn
116
+ Passing a range to `#not_in` is deprecated. Call `#not_between`, instead.
117
+ eowarn
118
+ end
119
+ not_between(other)
120
+ when Enumerable
121
+ Nodes::NotIn.new self, quoted_array(other)
122
+ else
123
+ Nodes::NotIn.new self, quoted_node(other)
124
+ end
125
+ end
126
+
127
+ def not_in_any(others)
128
+ grouping_any :not_in, others
129
+ end
130
+
131
+ def not_in_all(others)
132
+ grouping_all :not_in, others
133
+ end
134
+
135
+ def matches(other, escape = nil, case_sensitive = false)
136
+ Nodes::Matches.new self, quoted_node(other), escape, case_sensitive
137
+ end
138
+
139
+ def matches_regexp(other, case_sensitive = true)
140
+ Nodes::Regexp.new self, quoted_node(other), case_sensitive
141
+ end
142
+
143
+ def matches_any(others, escape = nil, case_sensitive = false)
144
+ grouping_any :matches, others, escape, case_sensitive
145
+ end
146
+
147
+ def matches_all(others, escape = nil, case_sensitive = false)
148
+ grouping_all :matches, others, escape, case_sensitive
149
+ end
150
+
151
+ def does_not_match(other, escape = nil, case_sensitive = false)
152
+ Nodes::DoesNotMatch.new self, quoted_node(other), escape, case_sensitive
153
+ end
154
+
155
+ def does_not_match_regexp(other, case_sensitive = true)
156
+ Nodes::NotRegexp.new self, quoted_node(other), case_sensitive
157
+ end
158
+
159
+ def does_not_match_any(others, escape = nil)
160
+ grouping_any :does_not_match, others, escape
161
+ end
162
+
163
+ def does_not_match_all(others, escape = nil)
164
+ grouping_all :does_not_match, others, escape
165
+ end
166
+
167
+ def gteq(right)
168
+ Nodes::GreaterThanOrEqual.new self, quoted_node(right)
169
+ end
170
+
171
+ def gteq_any(others)
172
+ grouping_any :gteq, others
173
+ end
174
+
175
+ def gteq_all(others)
176
+ grouping_all :gteq, others
177
+ end
178
+
179
+ def gt(right)
180
+ Nodes::GreaterThan.new self, quoted_node(right)
181
+ end
182
+
183
+ def gt_any(others)
184
+ grouping_any :gt, others
185
+ end
186
+
187
+ def gt_all(others)
188
+ grouping_all :gt, others
189
+ end
190
+
191
+ def lt(right)
192
+ Nodes::LessThan.new self, quoted_node(right)
193
+ end
194
+
195
+ def lt_any(others)
196
+ grouping_any :lt, others
197
+ end
198
+
199
+ def lt_all(others)
200
+ grouping_all :lt, others
201
+ end
202
+
203
+ def lteq(right)
204
+ Nodes::LessThanOrEqual.new self, quoted_node(right)
205
+ end
206
+
207
+ def lteq_any(others)
208
+ grouping_any :lteq, others
209
+ end
210
+
211
+ def lteq_all(others)
212
+ grouping_all :lteq, others
213
+ end
214
+
215
+ def when(right)
216
+ Nodes::Case.new(self).when quoted_node(right)
217
+ end
218
+
219
+ def concat(other)
220
+ Nodes::Concat.new self, other
221
+ end
222
+
223
+ private
224
+
225
+ def grouping_any(method_id, others, *extras)
226
+ nodes = others.map { |expr| send(method_id, expr, *extras) }
227
+ Nodes::Grouping.new nodes.inject { |memo, node|
228
+ Nodes::Or.new(memo, node)
229
+ }
230
+ end
231
+
232
+ def grouping_all(method_id, others, *extras)
233
+ nodes = others.map { |expr| send(method_id, expr, *extras) }
234
+ Nodes::Grouping.new Nodes::And.new(nodes)
235
+ end
236
+
237
+ def quoted_node(other)
238
+ Nodes.build_quoted(other, self)
239
+ end
240
+
241
+ def quoted_array(others)
242
+ others.map { |v| quoted_node(v) }
243
+ end
244
+
245
+ def infinity?(value)
246
+ value.respond_to?(:infinite?) && value.infinite?
247
+ end
248
+
249
+ def unboundable?(value)
250
+ value.respond_to?(:unboundable?) && value.unboundable?
251
+ end
252
+
253
+ def open_ended?(value)
254
+ infinity?(value) || unboundable?(value)
255
+ end
256
+ end
257
+ end