arel 6.0.4 → 7.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/History.txt +31 -12
  3. data/MIT-LICENSE.txt +2 -1
  4. data/{README.markdown → README.md} +88 -31
  5. data/lib/arel.rb +1 -1
  6. data/lib/arel/attributes/attribute.rb +8 -0
  7. data/lib/arel/crud.rb +4 -3
  8. data/lib/arel/delete_manager.rb +6 -1
  9. data/lib/arel/insert_manager.rb +1 -1
  10. data/lib/arel/math.rb +24 -0
  11. data/lib/arel/nodes.rb +6 -38
  12. data/lib/arel/nodes/binary.rb +0 -2
  13. data/lib/arel/nodes/bind_param.rb +3 -0
  14. data/lib/arel/nodes/case.rb +57 -0
  15. data/lib/arel/nodes/casted.rb +44 -0
  16. data/lib/arel/nodes/delete_statement.rb +2 -0
  17. data/lib/arel/nodes/infix_operation.rb +36 -1
  18. data/lib/arel/nodes/matches.rb +3 -1
  19. data/lib/arel/nodes/regexp.rb +14 -0
  20. data/lib/arel/nodes/select_core.rb +5 -5
  21. data/lib/arel/nodes/table_alias.rb +6 -2
  22. data/lib/arel/nodes/unary.rb +6 -3
  23. data/lib/arel/nodes/unary_operation.rb +25 -0
  24. data/lib/arel/predications.rb +38 -14
  25. data/lib/arel/select_manager.rb +6 -6
  26. data/lib/arel/table.rb +34 -59
  27. data/lib/arel/tree_manager.rb +3 -8
  28. data/lib/arel/update_manager.rb +1 -1
  29. data/lib/arel/visitors.rb +1 -23
  30. data/lib/arel/visitors/depth_first.rb +14 -2
  31. data/lib/arel/visitors/dot.rb +12 -1
  32. data/lib/arel/visitors/informix.rb +6 -1
  33. data/lib/arel/visitors/mssql.rb +35 -3
  34. data/lib/arel/visitors/mysql.rb +8 -0
  35. data/lib/arel/visitors/oracle.rb +13 -2
  36. data/lib/arel/visitors/oracle12.rb +59 -0
  37. data/lib/arel/visitors/postgresql.rb +56 -4
  38. data/lib/arel/visitors/sqlite.rb +9 -0
  39. data/lib/arel/visitors/to_sql.rb +94 -52
  40. data/lib/arel/visitors/where_sql.rb +10 -1
  41. metadata +11 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 59ae3c77b74453a1663328ba61bfc418c079991c
4
- data.tar.gz: 7b834bf894712eb6aacfc8ba7daee9e74267cc26
3
+ metadata.gz: d1986f950d2ecce6990d5a420c7963c874bcf22b
4
+ data.tar.gz: e21fbc532cdf9feceed6883a9ed1a151c0c1ebb3
5
5
  SHA512:
6
- metadata.gz: 750cf5971ff972d2c4db50ba08d36bbedc180bc5ad468668259f1d56d66ca6af377a92f2991370654b97e92130e6ea3d9ff7e826930cab74da8a73e118e878b2
7
- data.tar.gz: 803c188ee28bd29a6df184200d15dce08c6f7166b0f762cd698193692f8616873894f2be87b924848d5ec26cb0b57061346a8dfe98b71bab0072b8b9b5bd4612
6
+ metadata.gz: c0c67c17600ee4a7ce861bc688abf8d409d8b8c1c65969f26a9cfe8d7263eacd3c50f3e9548b80f1e071cd14e176e765addba6ec84de579c4797a123c960e2b1
7
+ data.tar.gz: a9f11f32f1868a9df3b27c88828513bf4106fcce946defc2d383488ab9fe9cb814408c51071ce6bbfe5aa8777d1a1fba7afd4fea89d4931282a2d7447343588e
data/History.txt CHANGED
@@ -1,26 +1,45 @@
1
- === 6.0.4 / 2016-12-27
1
+ === 7.1.4 / 2016-10-10
2
2
 
3
- * Enhancements
3
+ * bug fixes
4
4
 
5
- * Ruby 2.4 compatibility
5
+ * Remove deprecated usage inside arel.
6
6
 
7
- === 6.0.3 / 2015-08-04
7
+ === 7.1.3 / 2016-10-07
8
8
 
9
- * Bug fixes
9
+ * bug fixes
10
10
 
11
- * Fix quoting LIMIT values on Oracle visitor.
11
+ * Remove union mapping as :binary node when performing DepthFirst enumeration
12
+ * Fix invalid BindParam output in Dot visitor
13
+ * Add Arel::Nodes::Casted to dot visitor
14
+ * Use Arel::Nodes::BindParam in Oracle visitor for queries using both LIMIT and OFFSET
12
15
 
13
- === 6.0.2 / 2015-07-11
16
+ === 7.1.2 / 2016-09-13
14
17
 
15
- * Bug fixes
18
+ * bug fixes
16
19
 
17
- * Fix file permission problem on the gem package
20
+ * Don't store all aliases to a table
18
21
 
19
- === 6.0.1 / 2015-07-10
22
+ === 7.1.1 / 2016-07-27
20
23
 
21
- * Bug fixes
24
+ * bug fixes
25
+
26
+ * fix warning in `casted#hash`
27
+
28
+ === 7.1.0 / 2016-07-19
29
+
30
+ * Enhancements
31
+
32
+ * Support Ruby 2.4 unified Integer class
33
+ * Implement `CASE` conditional expression
34
+ * Support for Bitwise Operations as `InfixOperations`
35
+
36
+ === 7.0.0 / 2015-12-17
37
+
38
+ * Enhancements
22
39
 
23
- * Stop quoting LIMIT values.
40
+ * Remove deprecated method `Table#primary_key`
41
+ * Remove engine from the constructor arguments `Arel::Table`
42
+ * Deprecate automatic type casting within Arel
24
43
 
25
44
  === 6.0.0 / 2014-11-25
26
45
 
data/MIT-LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2007-2010 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
@@ -18,3 +18,4 @@ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
18
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
19
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
20
  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
@@ -1,4 +1,4 @@
1
- # Arel [![Build Status](https://secure.travis-ci.org/rails/arel.svg?branch=master)](http://travis-ci.org/rails/arel) [![Dependency Status](https://gemnasium.com/rails/arel.svg)](https://gemnasium.com/rails/arel)
1
+ # Arel
2
2
 
3
3
  * http://github.com/rails/arel
4
4
 
@@ -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,14 +264,21 @@ 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
- ### License
276
+ ## Contributing to Arel
277
+
278
+ Arel is the work of many contributors. You're encouraged to submit pull requests, propose
279
+ features and discuss issues.
280
+
281
+ See [CONTRIBUTING](CONTRIBUTING.md).
226
282
 
227
- Arel is released under the [MIT License](http://opensource.org/licenses/MIT).
283
+ ## License
284
+ Arel is released under the [MIT License](http://www.opensource.org/licenses/MIT).
data/lib/arel.rb CHANGED
@@ -21,7 +21,7 @@ require 'arel/delete_manager'
21
21
  require 'arel/nodes'
22
22
 
23
23
  module Arel
24
- VERSION = '6.0.4'
24
+ VERSION = '7.1.4'
25
25
 
26
26
  def self.sql raw_sql
27
27
  Arel::Nodes::SqlLiteral.new raw_sql
@@ -12,6 +12,14 @@ module Arel
12
12
  def lower
13
13
  relation.lower self
14
14
  end
15
+
16
+ def type_cast_for_database(value)
17
+ relation.type_cast_for_database(name, value)
18
+ end
19
+
20
+ def able_to_type_cast?
21
+ relation.able_to_type_cast?
22
+ end
15
23
  end
16
24
 
17
25
  class String < Attribute; end
data/lib/arel/crud.rb CHANGED
@@ -3,7 +3,7 @@ module Arel
3
3
  # FIXME hopefully we can remove this
4
4
  module Crud
5
5
  def compile_update values, pk
6
- um = UpdateManager.new @engine
6
+ um = UpdateManager.new
7
7
 
8
8
  if Nodes::SqlLiteral === values
9
9
  relation = @ctx.from
@@ -26,11 +26,12 @@ module Arel
26
26
  end
27
27
 
28
28
  def create_insert
29
- InsertManager.new @engine
29
+ InsertManager.new
30
30
  end
31
31
 
32
32
  def compile_delete
33
- dm = DeleteManager.new @engine
33
+ dm = DeleteManager.new
34
+ dm.take @ast.limit.expr if @ast.limit
34
35
  dm.wheres = @ctx.wheres
35
36
  dm.from @ctx.froms
36
37
  dm
@@ -1,6 +1,6 @@
1
1
  module Arel
2
2
  class DeleteManager < Arel::TreeManager
3
- def initialize engine
3
+ def initialize
4
4
  super
5
5
  @ast = Nodes::DeleteStatement.new
6
6
  @ctx = @ast
@@ -11,6 +11,11 @@ module Arel
11
11
  self
12
12
  end
13
13
 
14
+ def take limit
15
+ @ast.limit = Nodes::Limit.new(Nodes.build_quoted(limit)) if limit
16
+ self
17
+ end
18
+
14
19
  def wheres= list
15
20
  @ast.wheres = list
16
21
  end
@@ -1,6 +1,6 @@
1
1
  module Arel
2
2
  class InsertManager < Arel::TreeManager
3
- def initialize engine
3
+ def initialize
4
4
  super
5
5
  @ast = Nodes::InsertStatement.new
6
6
  end
data/lib/arel/math.rb CHANGED
@@ -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
data/lib/arel/nodes.rb CHANGED
@@ -28,8 +28,10 @@ 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'
34
+ require 'arel/nodes/regexp'
33
35
 
34
36
  # nary
35
37
  require 'arel/nodes/and'
@@ -46,6 +48,9 @@ require 'arel/nodes/named_function'
46
48
  # windows
47
49
  require 'arel/nodes/window'
48
50
 
51
+ # conditional expressions
52
+ require 'arel/nodes/case'
53
+
49
54
  # joins
50
55
  require 'arel/nodes/full_outer_join'
51
56
  require 'arel/nodes/inner_join'
@@ -55,41 +60,4 @@ require 'arel/nodes/string_join'
55
60
 
56
61
  require 'arel/nodes/sql_literal'
57
62
 
58
- module Arel
59
- module Nodes
60
- class Casted < Arel::Nodes::Node # :nodoc:
61
- attr_reader :val, :attribute
62
- def initialize val, attribute
63
- @val = val
64
- @attribute = attribute
65
- super()
66
- end
67
-
68
- def nil?; @val.nil?; end
69
-
70
- def eql? other
71
- self.class == other.class &&
72
- self.val == other.val &&
73
- self.attribute == other.attribute
74
- end
75
- alias :== :eql?
76
- end
77
-
78
- class Quoted < Arel::Nodes::Unary # :nodoc:
79
- end
80
-
81
- def self.build_quoted other, attribute = nil
82
- case other
83
- when Arel::Nodes::Node, Arel::Attributes::Attribute, Arel::Table, Arel::Nodes::BindParam, Arel::SelectManager
84
- other
85
- else
86
- case attribute
87
- when Arel::Attributes::Attribute
88
- Casted.new other, attribute
89
- else
90
- Quoted.new other
91
- end
92
- end
93
- end
94
- end
95
- end
63
+ require 'arel/nodes/casted'