arel 7.0.0 → 7.1.0

Sign up to get free protection for your applications and to get access to all the features.
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