square-arel 2.0.9.20110222133018
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.
- data/.autotest +26 -0
- data/History.txt +105 -0
- data/MIT-LICENSE.txt +20 -0
- data/Manifest.txt +124 -0
- data/README.markdown +94 -0
- data/Rakefile +20 -0
- data/lib/arel.rb +39 -0
- data/lib/arel/attributes.rb +20 -0
- data/lib/arel/attributes/attribute.rb +18 -0
- data/lib/arel/compatibility/wheres.rb +33 -0
- data/lib/arel/crud.rb +37 -0
- data/lib/arel/delete_manager.rb +18 -0
- data/lib/arel/deprecated.rb +4 -0
- data/lib/arel/expression.rb +4 -0
- data/lib/arel/expressions.rb +23 -0
- data/lib/arel/insert_manager.rb +34 -0
- data/lib/arel/nodes.rb +53 -0
- data/lib/arel/nodes/and.rb +6 -0
- data/lib/arel/nodes/as.rb +6 -0
- data/lib/arel/nodes/assignment.rb +6 -0
- data/lib/arel/nodes/avg.rb +6 -0
- data/lib/arel/nodes/between.rb +6 -0
- data/lib/arel/nodes/binary.rb +12 -0
- data/lib/arel/nodes/count.rb +13 -0
- data/lib/arel/nodes/delete_statement.rb +19 -0
- data/lib/arel/nodes/does_not_match.rb +6 -0
- data/lib/arel/nodes/equality.rb +9 -0
- data/lib/arel/nodes/except.rb +7 -0
- data/lib/arel/nodes/exists.rb +7 -0
- data/lib/arel/nodes/function.rb +18 -0
- data/lib/arel/nodes/greater_than.rb +6 -0
- data/lib/arel/nodes/greater_than_or_equal.rb +6 -0
- data/lib/arel/nodes/group.rb +6 -0
- data/lib/arel/nodes/grouping.rb +6 -0
- data/lib/arel/nodes/having.rb +6 -0
- data/lib/arel/nodes/in.rb +6 -0
- data/lib/arel/nodes/inner_join.rb +6 -0
- data/lib/arel/nodes/insert_statement.rb +19 -0
- data/lib/arel/nodes/intersect.rb +7 -0
- data/lib/arel/nodes/join.rb +13 -0
- data/lib/arel/nodes/less_than.rb +6 -0
- data/lib/arel/nodes/less_than_or_equal.rb +6 -0
- data/lib/arel/nodes/limit.rb +7 -0
- data/lib/arel/nodes/lock.rb +6 -0
- data/lib/arel/nodes/matches.rb +6 -0
- data/lib/arel/nodes/max.rb +6 -0
- data/lib/arel/nodes/min.rb +6 -0
- data/lib/arel/nodes/node.rb +44 -0
- data/lib/arel/nodes/not.rb +6 -0
- data/lib/arel/nodes/not_equal.rb +6 -0
- data/lib/arel/nodes/not_in.rb +6 -0
- data/lib/arel/nodes/offset.rb +7 -0
- data/lib/arel/nodes/on.rb +6 -0
- data/lib/arel/nodes/or.rb +6 -0
- data/lib/arel/nodes/ordering.rb +20 -0
- data/lib/arel/nodes/outer_join.rb +6 -0
- data/lib/arel/nodes/select_core.rb +26 -0
- data/lib/arel/nodes/select_statement.rb +22 -0
- data/lib/arel/nodes/sql_literal.rb +8 -0
- data/lib/arel/nodes/string_join.rb +11 -0
- data/lib/arel/nodes/sum.rb +6 -0
- data/lib/arel/nodes/table_alias.rb +13 -0
- data/lib/arel/nodes/top.rb +6 -0
- data/lib/arel/nodes/unary.rb +11 -0
- data/lib/arel/nodes/union.rb +7 -0
- data/lib/arel/nodes/union_all.rb +7 -0
- data/lib/arel/nodes/unqualified_column.rb +16 -0
- data/lib/arel/nodes/update_statement.rb +21 -0
- data/lib/arel/nodes/values.rb +14 -0
- data/lib/arel/predications.rb +183 -0
- data/lib/arel/relation.rb +6 -0
- data/lib/arel/select_manager.rb +237 -0
- data/lib/arel/sql/engine.rb +10 -0
- data/lib/arel/sql_literal.rb +4 -0
- data/lib/arel/table.rb +134 -0
- data/lib/arel/tree_manager.rb +36 -0
- data/lib/arel/update_manager.rb +49 -0
- data/lib/arel/visitors.rb +38 -0
- data/lib/arel/visitors/depth_first.rb +154 -0
- data/lib/arel/visitors/dot.rb +230 -0
- data/lib/arel/visitors/join_sql.rb +40 -0
- data/lib/arel/visitors/mssql.rb +16 -0
- data/lib/arel/visitors/mysql.rb +34 -0
- data/lib/arel/visitors/oracle.rb +116 -0
- data/lib/arel/visitors/order_clauses.rb +11 -0
- data/lib/arel/visitors/postgresql.rb +58 -0
- data/lib/arel/visitors/sqlite.rb +11 -0
- data/lib/arel/visitors/to_sql.rb +331 -0
- data/lib/arel/visitors/visitor.rb +27 -0
- data/lib/arel/visitors/where_sql.rb +9 -0
- data/square-arel.gemspec +36 -0
- data/test/attributes/test_attribute.rb +664 -0
- data/test/helper.rb +13 -0
- data/test/nodes/test_as.rb +16 -0
- data/test/nodes/test_count.rb +18 -0
- data/test/nodes/test_delete_statement.rb +14 -0
- data/test/nodes/test_equality.rb +74 -0
- data/test/nodes/test_insert_statement.rb +18 -0
- data/test/nodes/test_node.rb +33 -0
- data/test/nodes/test_not.rb +20 -0
- data/test/nodes/test_or.rb +22 -0
- data/test/nodes/test_select_core.rb +22 -0
- data/test/nodes/test_select_statement.rb +13 -0
- data/test/nodes/test_sql_literal.rb +52 -0
- data/test/nodes/test_sum.rb +12 -0
- data/test/nodes/test_update_statement.rb +18 -0
- data/test/support/fake_record.rb +91 -0
- data/test/test_activerecord_compat.rb +18 -0
- data/test/test_attributes.rb +46 -0
- data/test/test_crud.rb +69 -0
- data/test/test_delete_manager.rb +42 -0
- data/test/test_insert_manager.rb +125 -0
- data/test/test_select_manager.rb +659 -0
- data/test/test_table.rb +193 -0
- data/test/test_update_manager.rb +86 -0
- data/test/visitors/test_depth_first.rb +212 -0
- data/test/visitors/test_dot.rb +29 -0
- data/test/visitors/test_join_sql.rb +35 -0
- data/test/visitors/test_mssql.rb +18 -0
- data/test/visitors/test_mysql.rb +45 -0
- data/test/visitors/test_oracle.rb +147 -0
- data/test/visitors/test_postgres.rb +36 -0
- data/test/visitors/test_sqlite.rb +18 -0
- data/test/visitors/test_to_sql.rb +255 -0
- metadata +261 -0
data/.autotest
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
# require 'autotest/restart'
|
4
|
+
|
5
|
+
ENV['GEM_PATH'] = "tmp/isolate/ruby-1.8"
|
6
|
+
|
7
|
+
module Autotest::Restart
|
8
|
+
Autotest.add_hook :updated do |at, *args|
|
9
|
+
if args.flatten.include? ".autotest" then
|
10
|
+
warn "Detected change to .autotest, restarting"
|
11
|
+
cmd = %w(autotest)
|
12
|
+
cmd << " -v" if $v
|
13
|
+
cmd += ARGV
|
14
|
+
|
15
|
+
exec(*cmd)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
Autotest.add_hook :initialize do |at|
|
21
|
+
at.add_exception 'tmp'
|
22
|
+
at.testlib = "minitest/autorun"
|
23
|
+
|
24
|
+
at.find_directories = ARGV unless ARGV.empty?
|
25
|
+
end
|
26
|
+
|
data/History.txt
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
== 2.0.9 / 2010/02/25
|
2
|
+
|
3
|
+
* Bug Fixes
|
4
|
+
|
5
|
+
* Custom LOCK strings are allowed. Fixes LH # 6399
|
6
|
+
https://rails.lighthouseapp.com/projects/8994/tickets/6399-allow-database-specific-locking-clauses-to-be-used
|
7
|
+
|
8
|
+
* Strings passed to StringManager#on will be automatically tagged as SQL
|
9
|
+
literals. Fixes Rails LH #6384
|
10
|
+
https://rails.lighthouseapp.com/projects/8994/tickets/6384-activerecord-303-and-3-0-stable-generate-invalid-sql-for-has_many-through-association-with-conditions
|
11
|
+
|
12
|
+
== 2.0.8 / 2010/02/08
|
13
|
+
|
14
|
+
* Bug Fixes
|
15
|
+
|
16
|
+
* Added set operation support
|
17
|
+
* Fixed problems with *_any / *_all methods.
|
18
|
+
|
19
|
+
== 2.0.7
|
20
|
+
|
21
|
+
* Bug Fixes
|
22
|
+
|
23
|
+
* Limit members are visited
|
24
|
+
* Fixing MSSQL TOP support
|
25
|
+
|
26
|
+
== 2.0.6 12/01/2010
|
27
|
+
|
28
|
+
* Bug Fixes
|
29
|
+
|
30
|
+
* Rails 3.0.x does not like that Node is Enumerable, so removing for now.
|
31
|
+
|
32
|
+
== 2.0.5 11/30/2010
|
33
|
+
|
34
|
+
* Enhancements
|
35
|
+
|
36
|
+
* Arel::Visitors::DepthFirst can walk your AST depth first
|
37
|
+
* Arel::Nodes::Node is enumerable, depth first
|
38
|
+
|
39
|
+
* Bug fixes
|
40
|
+
|
41
|
+
* #lock will lock SELECT statements "FOR UPDATE" on mysql
|
42
|
+
* Nodes::Node#not factory method added for creating Nodes::Not nodes
|
43
|
+
* Added an As node
|
44
|
+
|
45
|
+
* Deprecations
|
46
|
+
|
47
|
+
* Support for Subclasses of core classes will be removed in ARel version
|
48
|
+
2.2.0
|
49
|
+
|
50
|
+
== 2.0.4
|
51
|
+
|
52
|
+
* Bug fixes
|
53
|
+
|
54
|
+
* Speed improvements for Range queries. Thanks Rolf Timmermans!
|
55
|
+
|
56
|
+
== 2.0.3
|
57
|
+
|
58
|
+
* Bug fixes
|
59
|
+
|
60
|
+
* Fixing Oracle support
|
61
|
+
* Added a visitor for "Class" objects
|
62
|
+
|
63
|
+
== 2.0.2
|
64
|
+
|
65
|
+
* Bug fixes
|
66
|
+
|
67
|
+
* MySQL selects from DUAL on empty FROM
|
68
|
+
* Visitor translates nil to NULL
|
69
|
+
* Visitor translates Bignum properly
|
70
|
+
|
71
|
+
== 2.0.1
|
72
|
+
|
73
|
+
* Bug fixes
|
74
|
+
|
75
|
+
== 2.0.0 / 2010-08-01
|
76
|
+
* Enhancements
|
77
|
+
|
78
|
+
* Recreate library using the Visitor pattern.
|
79
|
+
http://en.wikipedia.org/wiki/Visitor_pattern
|
80
|
+
|
81
|
+
== 0.3.0 / 2010-03-10
|
82
|
+
|
83
|
+
* Enhancements
|
84
|
+
|
85
|
+
* Introduced "SQL compilers" for query generation.
|
86
|
+
* Added support for Oracle (Raimonds Simanovskis) and IBM/DB (Praveen Devarao).
|
87
|
+
* Improvements to give better support to ActiveRecord.
|
88
|
+
|
89
|
+
== 0.2.1 / 2010-02-05
|
90
|
+
|
91
|
+
* Enhancements
|
92
|
+
|
93
|
+
* Bump dependency version of activesupport to 3.0.0.beta
|
94
|
+
|
95
|
+
== 0.2.0 / 2010-01-31
|
96
|
+
|
97
|
+
* Ruby 1.9 compatibility
|
98
|
+
* Many improvements to support the Arel integration into ActiveRecord (see `git log v0.1.0..v0.2.0`)
|
99
|
+
* Thanks to Emilio Tagua and Pratik Naik for many significant contributions!
|
100
|
+
|
101
|
+
== 0.1.0 / 2009-08-06
|
102
|
+
|
103
|
+
* 1 major enhancement
|
104
|
+
|
105
|
+
* Birthday!
|
data/MIT-LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2007-2010 Nick Kallen, Bryan Helmkamp, Emilio Tagua, Aaron Patterson
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Manifest.txt
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
.autotest
|
2
|
+
History.txt
|
3
|
+
MIT-LICENSE.txt
|
4
|
+
Manifest.txt
|
5
|
+
README.markdown
|
6
|
+
Rakefile
|
7
|
+
arel.gemspec
|
8
|
+
lib/arel.rb
|
9
|
+
lib/arel/attributes.rb
|
10
|
+
lib/arel/attributes/attribute.rb
|
11
|
+
lib/arel/compatibility/wheres.rb
|
12
|
+
lib/arel/crud.rb
|
13
|
+
lib/arel/delete_manager.rb
|
14
|
+
lib/arel/deprecated.rb
|
15
|
+
lib/arel/expression.rb
|
16
|
+
lib/arel/expressions.rb
|
17
|
+
lib/arel/insert_manager.rb
|
18
|
+
lib/arel/nodes.rb
|
19
|
+
lib/arel/nodes/and.rb
|
20
|
+
lib/arel/nodes/as.rb
|
21
|
+
lib/arel/nodes/assignment.rb
|
22
|
+
lib/arel/nodes/avg.rb
|
23
|
+
lib/arel/nodes/between.rb
|
24
|
+
lib/arel/nodes/binary.rb
|
25
|
+
lib/arel/nodes/count.rb
|
26
|
+
lib/arel/nodes/delete_statement.rb
|
27
|
+
lib/arel/nodes/does_not_match.rb
|
28
|
+
lib/arel/nodes/equality.rb
|
29
|
+
lib/arel/nodes/except.rb
|
30
|
+
lib/arel/nodes/exists.rb
|
31
|
+
lib/arel/nodes/function.rb
|
32
|
+
lib/arel/nodes/greater_than.rb
|
33
|
+
lib/arel/nodes/greater_than_or_equal.rb
|
34
|
+
lib/arel/nodes/group.rb
|
35
|
+
lib/arel/nodes/grouping.rb
|
36
|
+
lib/arel/nodes/having.rb
|
37
|
+
lib/arel/nodes/in.rb
|
38
|
+
lib/arel/nodes/inner_join.rb
|
39
|
+
lib/arel/nodes/insert_statement.rb
|
40
|
+
lib/arel/nodes/intersect.rb
|
41
|
+
lib/arel/nodes/join.rb
|
42
|
+
lib/arel/nodes/less_than.rb
|
43
|
+
lib/arel/nodes/less_than_or_equal.rb
|
44
|
+
lib/arel/nodes/limit.rb
|
45
|
+
lib/arel/nodes/lock.rb
|
46
|
+
lib/arel/nodes/matches.rb
|
47
|
+
lib/arel/nodes/max.rb
|
48
|
+
lib/arel/nodes/min.rb
|
49
|
+
lib/arel/nodes/node.rb
|
50
|
+
lib/arel/nodes/not.rb
|
51
|
+
lib/arel/nodes/not_equal.rb
|
52
|
+
lib/arel/nodes/not_in.rb
|
53
|
+
lib/arel/nodes/offset.rb
|
54
|
+
lib/arel/nodes/on.rb
|
55
|
+
lib/arel/nodes/or.rb
|
56
|
+
lib/arel/nodes/ordering.rb
|
57
|
+
lib/arel/nodes/outer_join.rb
|
58
|
+
lib/arel/nodes/select_core.rb
|
59
|
+
lib/arel/nodes/select_statement.rb
|
60
|
+
lib/arel/nodes/sql_literal.rb
|
61
|
+
lib/arel/nodes/string_join.rb
|
62
|
+
lib/arel/nodes/sum.rb
|
63
|
+
lib/arel/nodes/table_alias.rb
|
64
|
+
lib/arel/nodes/top.rb
|
65
|
+
lib/arel/nodes/unary.rb
|
66
|
+
lib/arel/nodes/union.rb
|
67
|
+
lib/arel/nodes/union_all.rb
|
68
|
+
lib/arel/nodes/unqualified_column.rb
|
69
|
+
lib/arel/nodes/update_statement.rb
|
70
|
+
lib/arel/nodes/values.rb
|
71
|
+
lib/arel/predications.rb
|
72
|
+
lib/arel/relation.rb
|
73
|
+
lib/arel/select_manager.rb
|
74
|
+
lib/arel/sql/engine.rb
|
75
|
+
lib/arel/sql_literal.rb
|
76
|
+
lib/arel/table.rb
|
77
|
+
lib/arel/tree_manager.rb
|
78
|
+
lib/arel/update_manager.rb
|
79
|
+
lib/arel/visitors.rb
|
80
|
+
lib/arel/visitors/depth_first.rb
|
81
|
+
lib/arel/visitors/dot.rb
|
82
|
+
lib/arel/visitors/join_sql.rb
|
83
|
+
lib/arel/visitors/mssql.rb
|
84
|
+
lib/arel/visitors/mysql.rb
|
85
|
+
lib/arel/visitors/oracle.rb
|
86
|
+
lib/arel/visitors/order_clauses.rb
|
87
|
+
lib/arel/visitors/postgresql.rb
|
88
|
+
lib/arel/visitors/sqlite.rb
|
89
|
+
lib/arel/visitors/to_sql.rb
|
90
|
+
lib/arel/visitors/visitor.rb
|
91
|
+
lib/arel/visitors/where_sql.rb
|
92
|
+
test/attributes/test_attribute.rb
|
93
|
+
test/helper.rb
|
94
|
+
test/nodes/test_as.rb
|
95
|
+
test/nodes/test_count.rb
|
96
|
+
test/nodes/test_delete_statement.rb
|
97
|
+
test/nodes/test_equality.rb
|
98
|
+
test/nodes/test_insert_statement.rb
|
99
|
+
test/nodes/test_node.rb
|
100
|
+
test/nodes/test_not.rb
|
101
|
+
test/nodes/test_or.rb
|
102
|
+
test/nodes/test_select_core.rb
|
103
|
+
test/nodes/test_select_statement.rb
|
104
|
+
test/nodes/test_sql_literal.rb
|
105
|
+
test/nodes/test_sum.rb
|
106
|
+
test/nodes/test_update_statement.rb
|
107
|
+
test/support/fake_record.rb
|
108
|
+
test/test_activerecord_compat.rb
|
109
|
+
test/test_attributes.rb
|
110
|
+
test/test_crud.rb
|
111
|
+
test/test_delete_manager.rb
|
112
|
+
test/test_insert_manager.rb
|
113
|
+
test/test_select_manager.rb
|
114
|
+
test/test_table.rb
|
115
|
+
test/test_update_manager.rb
|
116
|
+
test/visitors/test_depth_first.rb
|
117
|
+
test/visitors/test_dot.rb
|
118
|
+
test/visitors/test_join_sql.rb
|
119
|
+
test/visitors/test_mssql.rb
|
120
|
+
test/visitors/test_mysql.rb
|
121
|
+
test/visitors/test_oracle.rb
|
122
|
+
test/visitors/test_postgres.rb
|
123
|
+
test/visitors/test_sqlite.rb
|
124
|
+
test/visitors/test_to_sql.rb
|
data/README.markdown
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
# ARel
|
2
|
+
|
3
|
+
* http://github.com/rails/arel
|
4
|
+
|
5
|
+
## DESCRIPTION
|
6
|
+
|
7
|
+
Arel is a Relational Algebra for Ruby. It 1) simplifies the generation complex of SQL queries and it 2) adapts to various RDBMS systems. It is intended to be a framework framework; that is, you can build your own ORM with it, focusing on innovative object and collection modeling as opposed to database compatibility and query generation.
|
8
|
+
|
9
|
+
## Status
|
10
|
+
|
11
|
+
For the moment, Arel uses ActiveRecord's connection adapters to connect to the various engines, connection pooling, perform quoting, and do type conversion.
|
12
|
+
|
13
|
+
## A Gentle Introduction
|
14
|
+
|
15
|
+
Generating a query with ARel is simple. For example, in order to produce
|
16
|
+
|
17
|
+
SELECT * FROM users
|
18
|
+
|
19
|
+
you construct a table relation and convert it to sql:
|
20
|
+
|
21
|
+
users = Arel::Table.new(:users)
|
22
|
+
users.project(Arel.sql('*'))
|
23
|
+
users.to_sql
|
24
|
+
|
25
|
+
### More Sophisticated Queries
|
26
|
+
|
27
|
+
Here is a whirlwind tour through the most common relational operators. These will probably cover 80% of all interaction with the database.
|
28
|
+
|
29
|
+
First is the 'restriction' operator, `where`:
|
30
|
+
|
31
|
+
users.where(users[:name].eq('amy'))
|
32
|
+
# => SELECT * FROM users WHERE users.name = 'amy'
|
33
|
+
|
34
|
+
What would, in SQL, be part of the `SELECT` clause is called in Arel a `projection`:
|
35
|
+
|
36
|
+
users.project(users[:id]) # => SELECT users.id FROM users
|
37
|
+
|
38
|
+
Joins resemble SQL strongly:
|
39
|
+
|
40
|
+
users.join(photos).on(users[:id].eq(photos[:user_id]))
|
41
|
+
# => SELECT * FROM users INNER JOIN photos ON users.id = photos.user_id
|
42
|
+
|
43
|
+
What are called `LIMIT` and `OFFSET` in SQL are called `take` and `skip` in Arel:
|
44
|
+
|
45
|
+
users.take(5) # => SELECT * FROM users LIMIT 5
|
46
|
+
users.skip(4) # => SELECT * FROM users OFFSET 4
|
47
|
+
|
48
|
+
`GROUP BY` is called `group`:
|
49
|
+
|
50
|
+
users.group(users[:name]) # => SELECT * FROM users GROUP BY name
|
51
|
+
|
52
|
+
The best property of the Relational Algebra is its "composability", or closure under all operations. For example, to restrict AND project, just "chain" the method invocations:
|
53
|
+
|
54
|
+
users \
|
55
|
+
.where(users[:name].eq('amy')) \
|
56
|
+
.project(users[:id]) \
|
57
|
+
# => SELECT users.id FROM users WHERE users.name = 'amy'
|
58
|
+
|
59
|
+
All operators are chainable in this way, and they are chainable any number of times, in any order.
|
60
|
+
|
61
|
+
users.where(users[:name].eq('bob')).where(users[:age].lt(25))
|
62
|
+
|
63
|
+
Of course, many of the operators take multiple arguments, so the last example can be written more tersely:
|
64
|
+
|
65
|
+
users.where(users[:name].eq('bob'), users[:age].lt(25))
|
66
|
+
|
67
|
+
The `OR` operator works like this:
|
68
|
+
|
69
|
+
users.where(users[:name].eq('bob').or(users[:age].lt(25)))
|
70
|
+
|
71
|
+
The `AND` operator behaves similarly.
|
72
|
+
|
73
|
+
### The Crazy Features
|
74
|
+
|
75
|
+
The examples above are fairly simple and other libraries match or come close to matching the expressiveness of Arel (e.g., `Sequel` in Ruby).
|
76
|
+
|
77
|
+
#### Complex Joins
|
78
|
+
|
79
|
+
Where Arel really shines in its ability to handle complex joins and aggregations. As a first example, let's consider an "adjacency list", a tree represented in a table. Suppose we have a table `comments`, representing a threaded discussion:
|
80
|
+
|
81
|
+
comments = Arel::Table.new(:comments)
|
82
|
+
|
83
|
+
And this table has the following attributes:
|
84
|
+
|
85
|
+
comments.columns # => [comments[:id], comments[:body], comments[:parent_id]]
|
86
|
+
|
87
|
+
The `parent_id` column is a foreign key from the `comments` table to itself. Now, joining a table to itself requires aliasing in SQL. In fact, you may alias in Arel as well:
|
88
|
+
|
89
|
+
replies = comments.alias
|
90
|
+
comments_with_replies = \
|
91
|
+
comments.join(replies).on(replies[:parent_id].eq(comments[:id]))
|
92
|
+
# => SELECT * FROM comments INNER JOIN comments AS comments_2 WHERE comments_2.parent_id = comments.id
|
93
|
+
|
94
|
+
This will return the first comment's reply's body.
|
data/Rakefile
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
gem 'hoe', '>= 2.1.0'
|
3
|
+
require 'hoe'
|
4
|
+
|
5
|
+
Hoe.plugins.delete :rubyforge
|
6
|
+
Hoe.plugin :minitest
|
7
|
+
Hoe.plugin :gemspec # `gem install hoe-gemspec`
|
8
|
+
Hoe.plugin :git # `gem install hoe-git`
|
9
|
+
|
10
|
+
Hoe.spec 'arel' do
|
11
|
+
developer('Aaron Patterson', 'aaron@tenderlovemaking.com')
|
12
|
+
developer('Bryan Halmkamp', 'bryan@brynary.com')
|
13
|
+
developer('Emilio Tagua', 'miloops@gmail.com')
|
14
|
+
developer('Nick Kallen', 'nick@example.org') # FIXME: need Nick's email
|
15
|
+
|
16
|
+
self.readme_file = 'README.markdown'
|
17
|
+
self.extra_rdoc_files = FileList['README.markdown']
|
18
|
+
self.extra_dev_deps << [ 'hoe', '>= 2.1.0' ]
|
19
|
+
self.extra_dev_deps << [ 'minitest', '>= 1.6.0' ]
|
20
|
+
end
|
data/lib/arel.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'arel/crud'
|
2
|
+
|
3
|
+
require 'arel/expressions'
|
4
|
+
require 'arel/predications'
|
5
|
+
require 'arel/table'
|
6
|
+
require 'arel/attributes'
|
7
|
+
require 'arel/compatibility/wheres'
|
8
|
+
|
9
|
+
#### these are deprecated
|
10
|
+
# The Arel::Relation constant is referenced in Rails
|
11
|
+
require 'arel/relation'
|
12
|
+
require 'arel/expression'
|
13
|
+
####
|
14
|
+
|
15
|
+
require 'arel/visitors'
|
16
|
+
|
17
|
+
require 'arel/tree_manager'
|
18
|
+
require 'arel/insert_manager'
|
19
|
+
require 'arel/select_manager'
|
20
|
+
require 'arel/update_manager'
|
21
|
+
require 'arel/delete_manager'
|
22
|
+
require 'arel/nodes'
|
23
|
+
|
24
|
+
|
25
|
+
#### these are deprecated
|
26
|
+
require 'arel/deprecated'
|
27
|
+
require 'arel/sql/engine'
|
28
|
+
require 'arel/sql_literal'
|
29
|
+
####
|
30
|
+
|
31
|
+
module Arel
|
32
|
+
VERSION = '2.0.9'
|
33
|
+
|
34
|
+
def self.sql raw_sql
|
35
|
+
Arel::Nodes::SqlLiteral.new raw_sql
|
36
|
+
end
|
37
|
+
## Convenience Alias
|
38
|
+
Node = Arel::Nodes::Node
|
39
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'arel/attributes/attribute'
|
2
|
+
|
3
|
+
module Arel
|
4
|
+
module Attributes
|
5
|
+
###
|
6
|
+
# Factory method to wrap a raw database +column+ to an Arel Attribute.
|
7
|
+
def self.for column
|
8
|
+
case column.type
|
9
|
+
when :string, :text, :binary then String
|
10
|
+
when :integer then Integer
|
11
|
+
when :float then Float
|
12
|
+
when :decimal then Decimal
|
13
|
+
when :date, :datetime, :timestamp, :time then Time
|
14
|
+
when :boolean then Boolean
|
15
|
+
else
|
16
|
+
Undefined
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|