arel 7.0.0 → 7.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d7b8575f1877fe831a05c70632e7046c6ce384c9
4
- data.tar.gz: ab4c6895e273c5ad2bd6456bdf2f0fd1b3f7e0a2
3
+ metadata.gz: 2342eabbd34e994cf145023635cfe2da0c06cdf1
4
+ data.tar.gz: 044e71730354450e808cc454d89b8c362b2c8248
5
5
  SHA512:
6
- metadata.gz: 71feebe60212b48f1bce1fe0acc756728aff663f7e84836bc5888ed237bc6315b22d95993d9b9fce655dbccbf35c75652e9fd62c185d141c0c246084e3d70e68
7
- data.tar.gz: 563e00ae3191b5d4be40b8ead9168ead202242593a9761a2a5e938454b13c3094542d83b2e3ca5706c572ca2d1551772a9bce80631e55be9aa3379435bfecb75
6
+ metadata.gz: 14fd92387019cbab3bd4a102d0bddf0de1870eb16308054c69488d5d33a7692250f8e4c833ee0b7c76079fb8ed77778e98c55dc3da5f74a9726c793312661cda
7
+ data.tar.gz: ee5a6f43ddfae8c144f300fc7cb387bb0b836cb9cbbdbd8e1b597d22ed3493ee49a60656ac9ca1420bf9404a406d7a3ccd2fc5eda8281c03cb5ffb616654fe56
@@ -1,3 +1,11 @@
1
+ === 7.1.0 / 2016-07-19
2
+
3
+ * Enhancements
4
+
5
+ * Support Ruby 2.4 unified Integer class
6
+ * Implement `CASE` conditional expression
7
+ * Support for Bitwise Operations as `InfixOperations`
8
+
1
9
  === 7.0.0 / 2015-12-17
2
10
 
3
11
  * Enhancements
@@ -1,4 +1,4 @@
1
- Copyright (c) 2007-2015 Nick Kallen, Bryan Helmkamp, Emilio Tagua, Aaron Patterson
1
+ Copyright (c) 2007-2016 Nick Kallen, Bryan Helmkamp, Emilio Tagua, Aaron Patterson
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -8,8 +8,8 @@ Arel Really Exasperates Logicians
8
8
 
9
9
  Arel is a SQL AST manager for Ruby. It
10
10
 
11
- 1. Simplifies the generation of complex SQL queries
12
- 2. Adapts to various RDBMSes
11
+ 1. simplifies the generation of complex SQL queries, and
12
+ 2. adapts to various RDBMSes.
13
13
 
14
14
  It is intended to be a framework framework; that is, you can build your own ORM
15
15
  with it, focusing on innovative object and collection modeling as opposed to
@@ -17,7 +17,7 @@ database compatibility and query generation.
17
17
 
18
18
  ## Status
19
19
 
20
- For the moment, Arel uses Active Record's connection adapters to connect to the various engines, connection pooling, perform quoting, and do type conversion.
20
+ For the moment, Arel uses Active Record's connection adapters to connect to the various engines and perform connection pooling, quoting, and type conversion.
21
21
 
22
22
  ## A Gentle Introduction
23
23
 
@@ -27,7 +27,7 @@ Generating a query with Arel is simple. For example, in order to produce
27
27
  SELECT * FROM users
28
28
  ```
29
29
 
30
- you construct a table relation and convert it to sql:
30
+ you construct a table relation and convert it to SQL:
31
31
 
32
32
  ```ruby
33
33
  users = Arel::Table.new(:users)
@@ -56,13 +56,48 @@ users.project(users[:id])
56
56
  Comparison operators `=`, `!=`, `<`, `>`, `<=`, `>=`, `IN`:
57
57
 
58
58
  ```ruby
59
- users.where(users[:age].eq(10)).project(Arel.sql('*')) # => SELECT * FROM "users" WHERE "users"."age" = 10
60
- users.where(users[:age].not_eq(10)).project(Arel.sql('*')) # => SELECT * FROM "users" WHERE "users"."age" != 10
61
- users.where(users[:age].lt(10)).project(Arel.sql('*')) # => SELECT * FROM "users" WHERE "users"."age" < 10
62
- users.where(users[:age].gt(10)).project(Arel.sql('*')) # => SELECT * FROM "users" WHERE "users"."age" > 10
63
- users.where(users[:age].lteq(10)).project(Arel.sql('*')) # => SELECT * FROM "users" WHERE "users"."age" <= 10
64
- users.where(users[:age].gteq(10)).project(Arel.sql('*')) # => SELECT * FROM "users" WHERE "users"."age" >= 10
65
- users.where(users[:age].in([20, 16, 17])).project(Arel.sql('*')) # => SELECT * FROM "users" WHERE "users"."age" IN (20, 16, 17)
59
+ users.where(users[:age].eq(10)).project(Arel.sql('*'))
60
+ # => SELECT * FROM "users" WHERE "users"."age" = 10
61
+
62
+ users.where(users[:age].not_eq(10)).project(Arel.sql('*'))
63
+ # => SELECT * FROM "users" WHERE "users"."age" != 10
64
+
65
+ users.where(users[:age].lt(10)).project(Arel.sql('*'))
66
+ # => SELECT * FROM "users" WHERE "users"."age" < 10
67
+
68
+ users.where(users[:age].gt(10)).project(Arel.sql('*'))
69
+ # => SELECT * FROM "users" WHERE "users"."age" > 10
70
+
71
+ users.where(users[:age].lteq(10)).project(Arel.sql('*'))
72
+ # => SELECT * FROM "users" WHERE "users"."age" <= 10
73
+
74
+ users.where(users[:age].gteq(10)).project(Arel.sql('*'))
75
+ # => SELECT * FROM "users" WHERE "users"."age" >= 10
76
+
77
+ users.where(users[:age].in([20, 16, 17])).project(Arel.sql('*'))
78
+ # => SELECT * FROM "users" WHERE "users"."age" IN (20, 16, 17)
79
+ ```
80
+
81
+ Bitwise operators `&`, `|`, `^`, `<<`, `>>`:
82
+
83
+ ```ruby
84
+ users.where((users[:bitmap] & 16).gt(0)).project(Arel.sql('*'))
85
+ # => SELECT * FROM "users" WHERE ("users"."bitmap" & 16) > 0
86
+
87
+ users.where((users[:bitmap] | 16).gt(0)).project(Arel.sql('*'))
88
+ # => SELECT * FROM "users" WHERE ("users"."bitmap" | 16) > 0
89
+
90
+ users.where((users[:bitmap] ^ 16).gt(0)).project(Arel.sql('*'))
91
+ # => SELECT * FROM "users" WHERE ("users"."bitmap" ^ 16) > 0
92
+
93
+ users.where((users[:bitmap] << 1).gt(0)).project(Arel.sql('*'))
94
+ # => SELECT * FROM "users" WHERE ("users"."bitmap" << 1) > 0
95
+
96
+ users.where((users[:bitmap] >> 1).gt(0)).project(Arel.sql('*'))
97
+ # => SELECT * FROM "users" WHERE ("users"."bitmap" >> 1) > 0
98
+
99
+ users.where((~ users[:bitmap]).gt(0)).project(Arel.sql('*'))
100
+ # => SELECT FROM "users" WHERE ~ "users"."bitmap" > 0
66
101
  ```
67
102
 
68
103
  Joins resemble SQL strongly:
@@ -72,7 +107,7 @@ users.join(photos).on(users[:id].eq(photos[:user_id]))
72
107
  # => SELECT * FROM users INNER JOIN photos ON users.id = photos.user_id
73
108
  ```
74
109
 
75
- Left Joins
110
+ Left joins:
76
111
 
77
112
  ```ruby
78
113
  users.join(photos, Arel::Nodes::OuterJoin).on(users[:id].eq(photos[:user_id]))
@@ -93,7 +128,7 @@ users.project(users[:name]).group(users[:name])
93
128
  # => SELECT users.name FROM users GROUP BY users.name
94
129
  ```
95
130
 
96
- The best property of arel is its "composability", or closure under all operations. For example, to restrict AND project, just "chain" the method invocations:
131
+ The best property of Arel is its "composability," or closure under all operations. For example, to restrict AND project, just "chain" the method invocations:
97
132
 
98
133
  ```ruby
99
134
  users \
@@ -119,23 +154,35 @@ The `AND` operator behaves similarly.
119
154
  Aggregate functions `AVG`, `SUM`, `COUNT`, `MIN`, `MAX`, `HAVING`:
120
155
 
121
156
  ```ruby
122
- photos.group(photos[:user_id]).having(photos[:id].count.gt(5)) # => SELECT FROM photos GROUP BY photos.user_id HAVING COUNT(photos.id) > 5
123
- users.project(users[:age].sum) # => SELECT SUM(users.age) FROM users
124
- users.project(users[:age].average) # => SELECT AVG(users.age) FROM users
125
- users.project(users[:age].maximum) # => SELECT MAX(users.age) FROM users
126
- users.project(users[:age].minimum) # => SELECT MIN(users.age) FROM users
127
- users.project(users[:age].count) # => SELECT COUNT(users.age) FROM users
157
+ photos.group(photos[:user_id]).having(photos[:id].count.gt(5))
158
+ # => SELECT FROM photos GROUP BY photos.user_id HAVING COUNT(photos.id) > 5
159
+
160
+ users.project(users[:age].sum)
161
+ # => SELECT SUM(users.age) FROM users
162
+
163
+ users.project(users[:age].average)
164
+ # => SELECT AVG(users.age) FROM users
165
+
166
+ users.project(users[:age].maximum)
167
+ # => SELECT MAX(users.age) FROM users
168
+
169
+ users.project(users[:age].minimum)
170
+ # => SELECT MIN(users.age) FROM users
171
+
172
+ users.project(users[:age].count)
173
+ # => SELECT COUNT(users.age) FROM users
128
174
  ```
129
175
 
130
176
  Aliasing Aggregate Functions:
131
177
 
132
178
  ```ruby
133
- users.project(users[:age].average.as("mean_age")) # => SELECT AVG(users.age) AS mean_age FROM users
179
+ users.project(users[:age].average.as("mean_age"))
180
+ # => SELECT AVG(users.age) AS mean_age FROM users
134
181
  ```
135
182
 
136
183
  ### The Crazy Features
137
184
 
138
- The examples above are fairly simple and other libraries match or come close to matching the expressiveness of Arel (e.g., `Sequel` in Ruby).
185
+ The examples above are fairly simple and other libraries match or come close to matching the expressiveness of Arel (e.g. `Sequel` in Ruby).
139
186
 
140
187
  #### Inline math operations
141
188
 
@@ -179,12 +226,13 @@ Joining a table to itself requires aliasing in SQL. This aliasing can be handled
179
226
  replies = comments.alias
180
227
  comments_with_replies = \
181
228
  comments.join(replies).on(replies[:parent_id].eq(comments[:id])).where(comments[:id].eq(1))
182
- # => SELECT * FROM comments INNER JOIN comments AS comments_2 WHERE comments_2.parent_id = comments.id AND comments.id = 1
229
+ # => SELECT * FROM comments INNER JOIN comments AS comments_2
230
+ # WHERE comments_2.parent_id = comments.id AND comments.id = 1
183
231
  ```
184
232
 
185
233
  This will return the reply for the first comment.
186
234
 
187
- [Common Table Expressions(CTE)](https://en.wikipedia.org/wiki/Common_table_expressions#Common_table_expression) support via:
235
+ [Common Table Expressions (CTE)](https://en.wikipedia.org/wiki/Common_table_expressions#Common_table_expression) support via:
188
236
 
189
237
  Create a `CTE`
190
238
 
@@ -201,7 +249,9 @@ users.
201
249
  project(users[:id], cte_table[:click].sum).
202
250
  with(composed_cte)
203
251
 
204
- # => WITH cte_table AS (SELECT FROM photos WHERE photos.created_at > '2014-05-02') SELECT users.id, SUM(cte_table.click) FROM users INNER JOIN cte_table ON users.id = cte_table.user_id
252
+ # => WITH cte_table AS (SELECT FROM photos WHERE photos.created_at > '2014-05-02')
253
+ # SELECT users.id, SUM(cte_table.click)
254
+ # FROM users INNER JOIN cte_table ON users.id = cte_table.user_id
205
255
  ```
206
256
 
207
257
  When your query is too complex for `Arel`, you can use `Arel::SqlLiteral`:
@@ -214,17 +264,18 @@ photo_clicks = Arel::Nodes::SqlLiteral.new(<<-SQL
214
264
  ELSE default_calculation END
215
265
  SQL
216
266
  )
267
+
217
268
  photos.project(photo_clicks.as("photo_clicks"))
218
269
  # => SELECT CASE WHEN condition1 THEN calculation1
219
- WHEN condition2 THEN calculation2
220
- WHEN condition3 THEN calculation3
221
- ELSE default_calculation END
222
- FROM "photos"
270
+ # WHEN condition2 THEN calculation2
271
+ # WHEN condition3 THEN calculation3
272
+ # ELSE default_calculation END
273
+ # FROM "photos"
223
274
  ```
224
275
 
225
276
  ## Contributing to Arel
226
277
 
227
- Arel is work of many contributors. You're encouraged to submit pull requests, propose
278
+ Arel is the work of many contributors. You're encouraged to submit pull requests, propose
228
279
  features and discuss issues.
229
280
 
230
281
  See [CONTRIBUTING](CONTRIBUTING.md).
@@ -21,7 +21,7 @@ require 'arel/delete_manager'
21
21
  require 'arel/nodes'
22
22
 
23
23
  module Arel
24
- VERSION = '7.0.0'
24
+ VERSION = '7.1.0'
25
25
 
26
26
  def self.sql raw_sql
27
27
  Arel::Nodes::SqlLiteral.new raw_sql
@@ -15,5 +15,29 @@ module Arel
15
15
  def /(other)
16
16
  Arel::Nodes::Division.new(self, other)
17
17
  end
18
+
19
+ def &(other)
20
+ Arel::Nodes::Grouping.new(Arel::Nodes::BitwiseAnd.new(self, other))
21
+ end
22
+
23
+ def |(other)
24
+ Arel::Nodes::Grouping.new(Arel::Nodes::BitwiseOr.new(self, other))
25
+ end
26
+
27
+ def ^(other)
28
+ Arel::Nodes::Grouping.new(Arel::Nodes::BitwiseXor.new(self, other))
29
+ end
30
+
31
+ def <<(other)
32
+ Arel::Nodes::Grouping.new(Arel::Nodes::BitwiseShiftLeft.new(self, other))
33
+ end
34
+
35
+ def >>(other)
36
+ Arel::Nodes::Grouping.new(Arel::Nodes::BitwiseShiftRight.new(self, other))
37
+ end
38
+
39
+ def ~@
40
+ Arel::Nodes::BitwiseNot.new(self)
41
+ end
18
42
  end
19
43
  end
@@ -28,6 +28,7 @@ require 'arel/nodes/join_source'
28
28
  require 'arel/nodes/delete_statement'
29
29
  require 'arel/nodes/table_alias'
30
30
  require 'arel/nodes/infix_operation'
31
+ require 'arel/nodes/unary_operation'
31
32
  require 'arel/nodes/over'
32
33
  require 'arel/nodes/matches'
33
34
  require 'arel/nodes/regexp'
@@ -47,6 +48,9 @@ require 'arel/nodes/named_function'
47
48
  # windows
48
49
  require 'arel/nodes/window'
49
50
 
51
+ # conditional expressions
52
+ require 'arel/nodes/case'
53
+
50
54
  # joins
51
55
  require 'arel/nodes/full_outer_join'
52
56
  require 'arel/nodes/inner_join'
@@ -0,0 +1,57 @@
1
+ module Arel
2
+ module Nodes
3
+ class Case < Arel::Nodes::Node
4
+ include Arel::OrderPredications
5
+ include Arel::Predications
6
+ include Arel::AliasPredication
7
+
8
+ attr_accessor :case, :conditions, :default
9
+
10
+ def initialize expression = nil, default = nil
11
+ @case = expression
12
+ @conditions = []
13
+ @default = default
14
+ end
15
+
16
+ def when condition, expression = nil
17
+ @conditions << When.new(Nodes.build_quoted(condition), expression)
18
+ self
19
+ end
20
+
21
+ def then expression
22
+ @conditions.last.right = Nodes.build_quoted(expression)
23
+ self
24
+ end
25
+
26
+ def else expression
27
+ @default = Else.new Nodes.build_quoted(expression)
28
+ self
29
+ end
30
+
31
+ def initialize_copy other
32
+ super
33
+ @case = @case.clone if @case
34
+ @conditions = @conditions.map { |x| x.clone }
35
+ @default = @default.clone if @default
36
+ end
37
+
38
+ def hash
39
+ [@case, @conditions, @default].hash
40
+ end
41
+
42
+ def eql? other
43
+ self.class == other.class &&
44
+ self.case == other.case &&
45
+ self.conditions == other.conditions &&
46
+ self.default == other.default
47
+ end
48
+ alias :== :eql?
49
+ end
50
+
51
+ class When < Binary # :nodoc:
52
+ end
53
+
54
+ class Else < Unary # :nodoc:
55
+ end
56
+ end
57
+ end
@@ -10,6 +10,10 @@ module Arel
10
10
 
11
11
  def nil?; @val.nil?; end
12
12
 
13
+ def hash
14
+ [@class, @val, @attribute].hash
15
+ end
16
+
13
17
  def eql? other
14
18
  self.class == other.class &&
15
19
  self.val == other.val &&
@@ -40,5 +40,40 @@ module Arel
40
40
  end
41
41
  end
42
42
 
43
+ class Concat < InfixOperation
44
+ def initialize left, right
45
+ super('||', left, right)
46
+ end
47
+ end
48
+
49
+ class BitwiseAnd < InfixOperation
50
+ def initialize left, right
51
+ super(:&, left, right)
52
+ end
53
+ end
54
+
55
+ class BitwiseOr < InfixOperation
56
+ def initialize left, right
57
+ super(:|, left, right)
58
+ end
59
+ end
60
+
61
+ class BitwiseXor < InfixOperation
62
+ def initialize left, right
63
+ super(:^, left, right)
64
+ end
65
+ end
66
+
67
+ class BitwiseShiftLeft < InfixOperation
68
+ def initialize left, right
69
+ super(:<<, left, right)
70
+ end
71
+ end
72
+
73
+ class BitwiseShiftRight < InfixOperation
74
+ def initialize left, right
75
+ super(:>>, left, right)
76
+ end
77
+ end
43
78
  end
44
- end
79
+ end
@@ -22,15 +22,19 @@ module Arel
22
22
 
23
23
  %w{
24
24
  Bin
25
+ Cube
26
+ DistinctOn
25
27
  Group
28
+ GroupingElement
29
+ GroupingSet
26
30
  Limit
31
+ Lock
27
32
  Not
28
33
  Offset
29
34
  On
30
35
  Ordering
36
+ RollUp
31
37
  Top
32
- Lock
33
- DistinctOn
34
38
  }.each do |name|
35
39
  const_set(name, Class.new(Unary))
36
40
  end
@@ -0,0 +1,25 @@
1
+ module Arel
2
+ module Nodes
3
+
4
+ class UnaryOperation < Unary
5
+ include Arel::Expressions
6
+ include Arel::Predications
7
+ include Arel::OrderPredications
8
+ include Arel::AliasPredication
9
+ include Arel::Math
10
+
11
+ attr_reader :operator
12
+
13
+ def initialize operator, operand
14
+ super(operand)
15
+ @operator = operator
16
+ end
17
+ end
18
+
19
+ class BitwiseNot < UnaryOperation
20
+ def initialize operand
21
+ super(:~, operand)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -198,6 +198,14 @@ Passing a range to `#not_in` is deprecated. Call `#not_between`, instead.
198
198
  grouping_all :lteq, others
199
199
  end
200
200
 
201
+ def when right
202
+ Nodes::Case.new(self).when quoted_node(right)
203
+ end
204
+
205
+ def concat other
206
+ Nodes::Concat.new self, other
207
+ end
208
+
201
209
  private
202
210
 
203
211
  def grouping_any method_id, others, *extras
@@ -14,28 +14,5 @@ require 'arel/visitors/informix'
14
14
 
15
15
  module Arel
16
16
  module Visitors
17
- VISITORS = {
18
- 'postgresql' => Arel::Visitors::PostgreSQL,
19
- 'mysql' => Arel::Visitors::MySQL,
20
- 'mysql2' => Arel::Visitors::MySQL,
21
- 'mssql' => Arel::Visitors::MSSQL,
22
- 'sqlserver' => Arel::Visitors::MSSQL,
23
- 'oracle_enhanced' => Arel::Visitors::Oracle,
24
- 'sqlite' => Arel::Visitors::SQLite,
25
- 'sqlite3' => Arel::Visitors::SQLite,
26
- 'ibm_db' => Arel::Visitors::IBM_DB,
27
- 'informix' => Arel::Visitors::Informix,
28
- }
29
-
30
- ENGINE_VISITORS = Hash.new do |hash, engine|
31
- pool = engine.connection_pool
32
- adapter = pool.spec.config[:adapter]
33
- hash[engine] = (VISITORS[adapter] || Visitors::ToSql).new(engine)
34
- end
35
-
36
- def self.visitor_for engine
37
- ENGINE_VISITORS[engine]
38
- end
39
- class << self; alias :for :visitor_for; end
40
17
  end
41
18
  end
@@ -16,7 +16,12 @@ module Arel
16
16
  def unary o
17
17
  visit o.expr
18
18
  end
19
+ alias :visit_Arel_Nodes_Else :unary
19
20
  alias :visit_Arel_Nodes_Group :unary
21
+ alias :visit_Arel_Nodes_Cube :unary
22
+ alias :visit_Arel_Nodes_RollUp :unary
23
+ alias :visit_Arel_Nodes_GroupingSet :unary
24
+ alias :visit_Arel_Nodes_GroupingElement :unary
20
25
  alias :visit_Arel_Nodes_Grouping :unary
21
26
  alias :visit_Arel_Nodes_Having :unary
22
27
  alias :visit_Arel_Nodes_Limit :unary
@@ -53,6 +58,12 @@ module Arel
53
58
  visit o.distinct
54
59
  end
55
60
 
61
+ def visit_Arel_Nodes_Case o
62
+ visit o.case
63
+ visit o.conditions
64
+ visit o.default
65
+ end
66
+
56
67
  def nary o
57
68
  o.children.each { |child| visit child}
58
69
  end
@@ -65,6 +76,7 @@ module Arel
65
76
  alias :visit_Arel_Nodes_As :binary
66
77
  alias :visit_Arel_Nodes_Assignment :binary
67
78
  alias :visit_Arel_Nodes_Between :binary
79
+ alias :visit_Arel_Nodes_Concat :binary
68
80
  alias :visit_Arel_Nodes_DeleteStatement :binary
69
81
  alias :visit_Arel_Nodes_DoesNotMatch :binary
70
82
  alias :visit_Arel_Nodes_Equality :binary
@@ -86,8 +98,9 @@ module Arel
86
98
  alias :visit_Arel_Nodes_Regexp :binary
87
99
  alias :visit_Arel_Nodes_RightOuterJoin :binary
88
100
  alias :visit_Arel_Nodes_TableAlias :binary
89
- alias :visit_Arel_Nodes_Values :binary
90
101
  alias :visit_Arel_Nodes_Union :binary
102
+ alias :visit_Arel_Nodes_Values :binary
103
+ alias :visit_Arel_Nodes_When :binary
91
104
 
92
105
  def visit_Arel_Nodes_StringJoin o
93
106
  visit o.left
@@ -128,6 +141,7 @@ module Arel
128
141
  alias :visit_FalseClass :terminal
129
142
  alias :visit_Fixnum :terminal
130
143
  alias :visit_Float :terminal
144
+ alias :visit_Integer :terminal
131
145
  alias :visit_NilClass :terminal
132
146
  alias :visit_String :terminal
133
147
  alias :visit_Symbol :terminal
@@ -69,6 +69,10 @@ module Arel
69
69
  visit_edge o, "expr"
70
70
  end
71
71
  alias :visit_Arel_Nodes_Group :unary
72
+ alias :visit_Arel_Nodes_Cube :unary
73
+ alias :visit_Arel_Nodes_RollUp :unary
74
+ alias :visit_Arel_Nodes_GroupingSet :unary
75
+ alias :visit_Arel_Nodes_GroupingElement :unary
72
76
  alias :visit_Arel_Nodes_Grouping :unary
73
77
  alias :visit_Arel_Nodes_Having :unary
74
78
  alias :visit_Arel_Nodes_Limit :unary
@@ -176,6 +180,7 @@ module Arel
176
180
  alias :visit_Arel_Nodes_As :binary
177
181
  alias :visit_Arel_Nodes_Assignment :binary
178
182
  alias :visit_Arel_Nodes_Between :binary
183
+ alias :visit_Arel_Nodes_Concat :binary
179
184
  alias :visit_Arel_Nodes_DoesNotMatch :binary
180
185
  alias :visit_Arel_Nodes_Equality :binary
181
186
  alias :visit_Arel_Nodes_GreaterThan :binary
@@ -200,6 +205,7 @@ module Arel
200
205
  alias :visit_TrueClass :visit_String
201
206
  alias :visit_FalseClass :visit_String
202
207
  alias :visit_Arel_Nodes_BindParam :visit_String
208
+ alias :visit_Integer :visit_String
203
209
  alias :visit_Fixnum :visit_String
204
210
  alias :visit_BigDecimal :visit_String
205
211
  alias :visit_Float :visit_String
@@ -72,6 +72,14 @@ module Arel
72
72
  maybe_visit o.limit, collector
73
73
  end
74
74
 
75
+ def visit_Arel_Nodes_Concat o, collector
76
+ collector << " CONCAT("
77
+ visit o.left, collector
78
+ collector << ", "
79
+ visit o.right, collector
80
+ collector << ") "
81
+ collector
82
+ end
75
83
  end
76
84
  end
77
85
  end
@@ -6,10 +6,12 @@ module Arel
6
6
  def visit_Arel_Nodes_SelectStatement o, collector
7
7
  # Oracle does not allow LIMIT clause with select for update
8
8
  if o.limit && o.lock
9
- o = o.dup
10
- o.limit = []
9
+ raise ArgumentError, <<-MSG
10
+ 'Combination of limit and lock is not supported.
11
+ because generated SQL statements
12
+ `SELECT FOR UPDATE and FETCH FIRST n ROWS` generates ORA-02014.`
13
+ MSG
11
14
  end
12
-
13
15
  super
14
16
  end
15
17
 
@@ -48,6 +50,10 @@ module Arel
48
50
 
49
51
  super
50
52
  end
53
+
54
+ def visit_Arel_Nodes_BindParam o, collector
55
+ collector.add_bind(o) { |i| ":a#{i}" }
56
+ end
51
57
  end
52
58
  end
53
59
  end
@@ -1,6 +1,10 @@
1
1
  module Arel
2
2
  module Visitors
3
3
  class PostgreSQL < Arel::Visitors::ToSql
4
+ CUBE = 'CUBE'
5
+ ROLLUP = 'ROLLUP'
6
+ GROUPING_SET = 'GROUPING SET'
7
+
4
8
  private
5
9
 
6
10
  def visit_Arel_Nodes_Matches o, collector
@@ -43,6 +47,38 @@ module Arel
43
47
  def visit_Arel_Nodes_BindParam o, collector
44
48
  collector.add_bind(o) { |i| "$#{i}" }
45
49
  end
50
+
51
+ def visit_Arel_Nodes_GroupingElement o, collector
52
+ collector << "( "
53
+ visit(o.expr, collector) << " )"
54
+ end
55
+
56
+ def visit_Arel_Nodes_Cube o, collector
57
+ collector << CUBE
58
+ grouping_array_or_grouping_element o, collector
59
+ end
60
+
61
+ def visit_Arel_Nodes_RollUp o, collector
62
+ collector << ROLLUP
63
+ grouping_array_or_grouping_element o, collector
64
+ end
65
+
66
+ def visit_Arel_Nodes_GroupingSet o, collector
67
+ collector << GROUPING_SET
68
+ grouping_array_or_grouping_element o, collector
69
+ end
70
+
71
+ # Utilized by GroupingSet, Cube & RollUp visitors to
72
+ # handle grouping aggregation semantics
73
+ def grouping_array_or_grouping_element o, collector
74
+ if o.expr.is_a? Array
75
+ collector << "( "
76
+ visit o.expr, collector
77
+ collector << " )"
78
+ else
79
+ visit o.expr, collector
80
+ end
81
+ end
46
82
  end
47
83
  end
48
84
  end
@@ -12,6 +12,15 @@ module Arel
12
12
  o.limit = Arel::Nodes::Limit.new(-1) if o.offset && !o.limit
13
13
  super
14
14
  end
15
+
16
+ def visit_Arel_Nodes_True o, collector
17
+ collector << "1"
18
+ end
19
+
20
+ def visit_Arel_Nodes_False o, collector
21
+ collector << "0"
22
+ end
23
+
15
24
  end
16
25
  end
17
26
  end
@@ -199,7 +199,7 @@ module Arel
199
199
  collector << quote(value, attr && column_for(attr)).to_s
200
200
  end
201
201
  unless i == len
202
- collector << ', '
202
+ collector << COMMA
203
203
  end
204
204
  }
205
205
 
@@ -243,53 +243,33 @@ module Arel
243
243
 
244
244
  collector = maybe_visit o.set_quantifier, collector
245
245
 
246
- unless o.projections.empty?
247
- collector << SPACE
248
- len = o.projections.length - 1
249
- o.projections.each_with_index do |x, i|
250
- collector = visit(x, collector)
251
- collector << COMMA unless len == i
252
- end
253
- end
246
+ collect_nodes_for o.projections, collector, SPACE
254
247
 
255
248
  if o.source && !o.source.empty?
256
249
  collector << " FROM "
257
250
  collector = visit o.source, collector
258
251
  end
259
252
 
260
- unless o.wheres.empty?
261
- collector << WHERE
262
- len = o.wheres.length - 1
263
- o.wheres.each_with_index do |x, i|
264
- collector = visit(x, collector)
265
- collector << AND unless len == i
266
- end
267
- end
268
-
269
- unless o.groups.empty?
270
- collector << GROUP_BY
271
- len = o.groups.length - 1
272
- o.groups.each_with_index do |x, i|
273
- collector = visit(x, collector)
274
- collector << COMMA unless len == i
275
- end
276
- end
277
-
253
+ collect_nodes_for o.wheres, collector, WHERE, AND
254
+ collect_nodes_for o.groups, collector, GROUP_BY
278
255
  unless o.havings.empty?
279
256
  collector << " HAVING "
280
257
  inject_join o.havings, collector, AND
281
258
  end
259
+ collect_nodes_for o.windows, collector, WINDOW
282
260
 
283
- unless o.windows.empty?
284
- collector << WINDOW
285
- len = o.windows.length - 1
286
- o.windows.each_with_index do |x, i|
261
+ collector
262
+ end
263
+
264
+ def collect_nodes_for nodes, collector, spacer, connector = COMMA
265
+ unless nodes.empty?
266
+ collector << spacer
267
+ len = nodes.length - 1
268
+ nodes.each_with_index do |x, i|
287
269
  collector = visit(x, collector)
288
- collector << COMMA unless len == i
270
+ collector << connector unless len == i
289
271
  end
290
272
  end
291
-
292
- collector
293
273
  end
294
274
 
295
275
  def visit_Arel_Nodes_Bin o, collector
@@ -349,13 +329,13 @@ module Arel
349
329
  end
350
330
 
351
331
  if o.orders.any?
352
- collector << ' ' if o.partitions.any?
332
+ collector << SPACE if o.partitions.any?
353
333
  collector << "ORDER BY "
354
334
  collector = inject_join o.orders, collector, ", "
355
335
  end
356
336
 
357
337
  if o.framing
358
- collector << ' ' if o.partitions.any? or o.orders.any?
338
+ collector << SPACE if o.partitions.any? or o.orders.any?
359
339
  collector = visit o.framing, collector
360
340
  end
361
341
 
@@ -564,7 +544,7 @@ module Arel
564
544
  collector = visit o.left, collector
565
545
  end
566
546
  if o.right.any?
567
- collector << " " if o.left
547
+ collector << SPACE if o.left
568
548
  collector = inject_join o.right, collector, ' '
569
549
  end
570
550
  collector
@@ -708,6 +688,35 @@ module Arel
708
688
  visit o.right, collector
709
689
  end
710
690
 
691
+ def visit_Arel_Nodes_Case o, collector
692
+ collector << "CASE "
693
+ if o.case
694
+ visit o.case, collector
695
+ collector << " "
696
+ end
697
+ o.conditions.each do |condition|
698
+ visit condition, collector
699
+ collector << " "
700
+ end
701
+ if o.default
702
+ visit o.default, collector
703
+ collector << " "
704
+ end
705
+ collector << "END"
706
+ end
707
+
708
+ def visit_Arel_Nodes_When o, collector
709
+ collector << "WHEN "
710
+ visit o.left, collector
711
+ collector << " THEN "
712
+ visit o.right, collector
713
+ end
714
+
715
+ def visit_Arel_Nodes_Else o, collector
716
+ collector << "ELSE "
717
+ visit o.expr, collector
718
+ end
719
+
711
720
  def visit_Arel_Nodes_UnqualifiedColumn o, collector
712
721
  collector << "#{quote_column_name o.name}"
713
722
  collector
@@ -733,6 +742,7 @@ module Arel
733
742
  alias :visit_Arel_Nodes_SqlLiteral :literal
734
743
  alias :visit_Bignum :literal
735
744
  alias :visit_Fixnum :literal
745
+ alias :visit_Integer :literal
736
746
 
737
747
  def quoted o, a
738
748
  if a && a.able_to_type_cast?
@@ -772,6 +782,11 @@ module Arel
772
782
  alias :visit_Arel_Nodes_Multiplication :visit_Arel_Nodes_InfixOperation
773
783
  alias :visit_Arel_Nodes_Division :visit_Arel_Nodes_InfixOperation
774
784
 
785
+ def visit_Arel_Nodes_UnaryOperation o, collector
786
+ collector << " #{o.operator} "
787
+ visit o.expr, collector
788
+ end
789
+
775
790
  def visit_Array o, collector
776
791
  inject_join o, collector, ", "
777
792
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: arel
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.0.0
4
+ version: 7.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Patterson
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2015-12-17 00:00:00.000000000 Z
14
+ date: 2016-07-20 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: minitest
@@ -75,11 +75,11 @@ extensions: []
75
75
  extra_rdoc_files:
76
76
  - History.txt
77
77
  - MIT-LICENSE.txt
78
- - README.markdown
78
+ - README.md
79
79
  files:
80
80
  - History.txt
81
81
  - MIT-LICENSE.txt
82
- - README.markdown
82
+ - README.md
83
83
  - lib/arel.rb
84
84
  - lib/arel/alias_predication.rb
85
85
  - lib/arel/attributes.rb
@@ -99,6 +99,7 @@ files:
99
99
  - lib/arel/nodes/ascending.rb
100
100
  - lib/arel/nodes/binary.rb
101
101
  - lib/arel/nodes/bind_param.rb
102
+ - lib/arel/nodes/case.rb
102
103
  - lib/arel/nodes/casted.rb
103
104
  - lib/arel/nodes/count.rb
104
105
  - lib/arel/nodes/delete_statement.rb
@@ -129,6 +130,7 @@ files:
129
130
  - lib/arel/nodes/terminal.rb
130
131
  - lib/arel/nodes/true.rb
131
132
  - lib/arel/nodes/unary.rb
133
+ - lib/arel/nodes/unary_operation.rb
132
134
  - lib/arel/nodes/unqualified_column.rb
133
135
  - lib/arel/nodes/update_statement.rb
134
136
  - lib/arel/nodes/values.rb
@@ -165,7 +167,7 @@ metadata: {}
165
167
  post_install_message:
166
168
  rdoc_options:
167
169
  - "--main"
168
- - README.markdown
170
+ - README.md
169
171
  require_paths:
170
172
  - lib
171
173
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -180,7 +182,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
180
182
  version: '0'
181
183
  requirements: []
182
184
  rubyforge_project:
183
- rubygems_version: 2.4.5.1
185
+ rubygems_version: 2.6.6
184
186
  signing_key:
185
187
  specification_version: 4
186
188
  summary: Arel Really Exasperates Logicians Arel is a SQL AST manager for Ruby