arel 1.0.1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE.txt +20 -0
- data/Manifest.txt +105 -0
- data/README.markdown +12 -32
- data/Rakefile +17 -0
- data/arel.gemspec +39 -0
- data/lib/arel.rb +30 -9
- data/lib/arel/attributes.rb +20 -0
- data/lib/arel/attributes/attribute.rb +190 -0
- data/lib/arel/compatibility/wheres.rb +33 -0
- data/lib/arel/crud.rb +37 -0
- data/lib/arel/delete_manager.rb +22 -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 +44 -0
- data/lib/arel/nodes/and.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 +17 -0
- data/lib/arel/nodes/does_not_match.rb +6 -0
- data/lib/arel/nodes/equality.rb +9 -0
- data/lib/arel/nodes/exists.rb +11 -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 +11 -0
- data/lib/arel/nodes/grouping.rb +11 -0
- data/lib/arel/nodes/having.rb +11 -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/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/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 +30 -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 +11 -0
- data/lib/arel/nodes/on.rb +11 -0
- data/lib/arel/nodes/or.rb +6 -0
- data/lib/arel/nodes/ordering.rb +19 -0
- data/lib/arel/nodes/outer_join.rb +6 -0
- data/lib/arel/nodes/select_core.rb +25 -0
- data/lib/arel/nodes/select_statement.rb +22 -0
- data/lib/arel/nodes/sql_literal.rb +7 -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 +21 -0
- data/lib/arel/nodes/unqualified_column.rb +19 -0
- data/lib/arel/nodes/update_statement.rb +21 -0
- data/lib/arel/nodes/values.rb +12 -0
- data/lib/arel/relation.rb +6 -0
- data/lib/arel/select_manager.rb +203 -0
- data/lib/arel/sql/engine.rb +10 -0
- data/lib/arel/sql_literal.rb +1 -10
- data/lib/arel/table.rb +126 -0
- data/lib/arel/tree_manager.rb +26 -0
- data/lib/arel/update_manager.rb +48 -0
- data/lib/arel/visitors.rb +30 -0
- data/lib/arel/visitors/dot.rb +233 -0
- data/lib/arel/visitors/join_sql.rb +38 -0
- data/lib/arel/visitors/mysql.rb +16 -0
- data/lib/arel/visitors/oracle.rb +69 -0
- data/lib/arel/visitors/order_clauses.rb +9 -0
- data/lib/arel/visitors/postgresql.rb +54 -0
- data/lib/arel/visitors/to_sql.rb +301 -0
- data/lib/arel/visitors/where_sql.rb +9 -0
- data/spec/activerecord_compat_spec.rb +18 -0
- data/spec/attributes/attribute_spec.rb +648 -0
- data/spec/attributes_spec.rb +33 -6
- data/spec/crud_spec.rb +69 -0
- data/spec/delete_manager_spec.rb +53 -0
- data/spec/insert_manager_spec.rb +141 -0
- data/spec/nodes/count_spec.rb +18 -0
- data/spec/nodes/delete_statement_spec.rb +15 -0
- data/spec/nodes/equality_spec.rb +72 -0
- data/spec/nodes/insert_statement_spec.rb +18 -0
- data/spec/nodes/or_spec.rb +20 -0
- data/spec/nodes/select_core_spec.rb +21 -0
- data/spec/nodes/select_statement_spec.rb +14 -0
- data/spec/nodes/sql_literal_spec.rb +26 -0
- data/spec/nodes/sum_spec.rb +12 -0
- data/spec/nodes/update_statement_spec.rb +18 -0
- data/spec/select_manager_spec.rb +581 -0
- data/spec/spec.opts +3 -0
- data/spec/spec_helper.rb +6 -21
- data/spec/support/fake_record.rb +89 -0
- data/spec/support/shared/tree_manager_shared.rb +9 -0
- data/spec/table_spec.rb +176 -0
- data/spec/update_manager_spec.rb +89 -0
- data/spec/visitors/join_sql_spec.rb +35 -0
- data/spec/visitors/oracle_spec.rb +111 -0
- data/spec/visitors/to_sql_spec.rb +134 -0
- metadata +160 -260
- data/lib/arel/algebra.rb +0 -10
- data/lib/arel/algebra/attributes.rb +0 -7
- data/lib/arel/algebra/attributes/attribute.rb +0 -304
- data/lib/arel/algebra/attributes/boolean.rb +0 -21
- data/lib/arel/algebra/attributes/decimal.rb +0 -9
- data/lib/arel/algebra/attributes/float.rb +0 -9
- data/lib/arel/algebra/attributes/integer.rb +0 -10
- data/lib/arel/algebra/attributes/string.rb +0 -10
- data/lib/arel/algebra/attributes/time.rb +0 -6
- data/lib/arel/algebra/core_extensions.rb +0 -3
- data/lib/arel/algebra/core_extensions/hash.rb +0 -7
- data/lib/arel/algebra/core_extensions/object.rb +0 -13
- data/lib/arel/algebra/core_extensions/symbol.rb +0 -9
- data/lib/arel/algebra/expression.rb +0 -56
- data/lib/arel/algebra/header.rb +0 -66
- data/lib/arel/algebra/ordering.rb +0 -31
- data/lib/arel/algebra/predicates.rb +0 -306
- data/lib/arel/algebra/relations.rb +0 -16
- data/lib/arel/algebra/relations/operations/from.rb +0 -14
- data/lib/arel/algebra/relations/operations/group.rb +0 -14
- data/lib/arel/algebra/relations/operations/having.rb +0 -14
- data/lib/arel/algebra/relations/operations/join.rb +0 -103
- data/lib/arel/algebra/relations/operations/lock.rb +0 -10
- data/lib/arel/algebra/relations/operations/order.rb +0 -23
- data/lib/arel/algebra/relations/operations/project.rb +0 -20
- data/lib/arel/algebra/relations/operations/skip.rb +0 -14
- data/lib/arel/algebra/relations/operations/take.rb +0 -18
- data/lib/arel/algebra/relations/operations/where.rb +0 -24
- data/lib/arel/algebra/relations/relation.rb +0 -205
- data/lib/arel/algebra/relations/row.rb +0 -29
- data/lib/arel/algebra/relations/utilities/compound.rb +0 -55
- data/lib/arel/algebra/relations/utilities/externalization.rb +0 -26
- data/lib/arel/algebra/relations/utilities/nil.rb +0 -7
- data/lib/arel/algebra/relations/writes.rb +0 -47
- data/lib/arel/algebra/value.rb +0 -53
- data/lib/arel/engines.rb +0 -2
- data/lib/arel/engines/memory.rb +0 -2
- data/lib/arel/engines/memory/engine.rb +0 -10
- data/lib/arel/engines/memory/relations.rb +0 -2
- data/lib/arel/engines/memory/relations/array.rb +0 -37
- data/lib/arel/engines/memory/relations/operations.rb +0 -9
- data/lib/arel/engines/sql.rb +0 -6
- data/lib/arel/engines/sql/attributes.rb +0 -45
- data/lib/arel/engines/sql/christener.rb +0 -20
- data/lib/arel/engines/sql/compilers/ibm_db_compiler.rb +0 -48
- data/lib/arel/engines/sql/compilers/mysql_compiler.rb +0 -11
- data/lib/arel/engines/sql/compilers/oracle_compiler.rb +0 -106
- data/lib/arel/engines/sql/compilers/postgresql_compiler.rb +0 -50
- data/lib/arel/engines/sql/compilers/sqlite_compiler.rb +0 -9
- data/lib/arel/engines/sql/core_extensions.rb +0 -4
- data/lib/arel/engines/sql/core_extensions/array.rb +0 -24
- data/lib/arel/engines/sql/core_extensions/nil_class.rb +0 -15
- data/lib/arel/engines/sql/core_extensions/object.rb +0 -19
- data/lib/arel/engines/sql/core_extensions/range.rb +0 -19
- data/lib/arel/engines/sql/engine.rb +0 -47
- data/lib/arel/engines/sql/formatters.rb +0 -138
- data/lib/arel/engines/sql/relations.rb +0 -3
- data/lib/arel/engines/sql/relations/compiler.rb +0 -153
- data/lib/arel/engines/sql/relations/table.rb +0 -100
- data/lib/arel/engines/sql/relations/utilities/nil.rb +0 -6
- data/lib/arel/recursion/base_case.rb +0 -13
- data/lib/arel/session.rb +0 -35
- data/lib/arel/version.rb +0 -3
- data/spec/algebra/unit/predicates/binary_spec.rb +0 -35
- data/spec/algebra/unit/predicates/equality_spec.rb +0 -29
- data/spec/algebra/unit/predicates/in_spec.rb +0 -12
- data/spec/algebra/unit/predicates/inequality_spec.rb +0 -32
- data/spec/algebra/unit/predicates/predicate_spec.rb +0 -22
- data/spec/algebra/unit/primitives/attribute_spec.rb +0 -175
- data/spec/algebra/unit/primitives/expression_spec.rb +0 -39
- data/spec/algebra/unit/primitives/value_spec.rb +0 -15
- data/spec/algebra/unit/relations/alias_spec.rb +0 -16
- data/spec/algebra/unit/relations/delete_spec.rb +0 -9
- data/spec/algebra/unit/relations/group_spec.rb +0 -10
- data/spec/algebra/unit/relations/insert_spec.rb +0 -9
- data/spec/algebra/unit/relations/join_spec.rb +0 -18
- data/spec/algebra/unit/relations/order_spec.rb +0 -21
- data/spec/algebra/unit/relations/project_spec.rb +0 -34
- data/spec/algebra/unit/relations/relation_spec.rb +0 -241
- data/spec/algebra/unit/relations/skip_spec.rb +0 -10
- data/spec/algebra/unit/relations/table_spec.rb +0 -38
- data/spec/algebra/unit/relations/take_spec.rb +0 -10
- data/spec/algebra/unit/relations/update_spec.rb +0 -9
- data/spec/algebra/unit/relations/where_spec.rb +0 -19
- data/spec/algebra/unit/session/session_spec.rb +0 -84
- data/spec/attributes/boolean_spec.rb +0 -57
- data/spec/attributes/float_spec.rb +0 -119
- data/spec/attributes/header_spec.rb +0 -42
- data/spec/attributes/integer_spec.rb +0 -119
- data/spec/attributes/string_spec.rb +0 -43
- data/spec/attributes/time_spec.rb +0 -24
- data/spec/engines/memory/integration/joins/cross_engine_spec.rb +0 -61
- data/spec/engines/memory/unit/relations/array_spec.rb +0 -33
- data/spec/engines/memory/unit/relations/insert_spec.rb +0 -28
- data/spec/engines/memory/unit/relations/join_spec.rb +0 -32
- data/spec/engines/memory/unit/relations/order_spec.rb +0 -28
- data/spec/engines/memory/unit/relations/project_spec.rb +0 -27
- data/spec/engines/memory/unit/relations/skip_spec.rb +0 -31
- data/spec/engines/memory/unit/relations/take_spec.rb +0 -28
- data/spec/engines/memory/unit/relations/where_spec.rb +0 -43
- data/spec/engines/sql/integration/joins/with_adjacency_spec.rb +0 -258
- data/spec/engines/sql/integration/joins/with_aggregations_spec.rb +0 -221
- data/spec/engines/sql/integration/joins/with_compounds_spec.rb +0 -137
- data/spec/engines/sql/unit/engine_spec.rb +0 -65
- data/spec/engines/sql/unit/predicates/binary_spec.rb +0 -140
- data/spec/engines/sql/unit/predicates/equality_spec.rb +0 -75
- data/spec/engines/sql/unit/predicates/in_spec.rb +0 -179
- data/spec/engines/sql/unit/predicates/noteq_spec.rb +0 -75
- data/spec/engines/sql/unit/predicates/predicates_spec.rb +0 -79
- data/spec/engines/sql/unit/primitives/attribute_spec.rb +0 -36
- data/spec/engines/sql/unit/primitives/expression_spec.rb +0 -28
- data/spec/engines/sql/unit/primitives/literal_spec.rb +0 -43
- data/spec/engines/sql/unit/primitives/value_spec.rb +0 -29
- data/spec/engines/sql/unit/relations/alias_spec.rb +0 -53
- data/spec/engines/sql/unit/relations/delete_spec.rb +0 -83
- data/spec/engines/sql/unit/relations/from_spec.rb +0 -64
- data/spec/engines/sql/unit/relations/group_spec.rb +0 -72
- data/spec/engines/sql/unit/relations/having_spec.rb +0 -78
- data/spec/engines/sql/unit/relations/insert_spec.rb +0 -143
- data/spec/engines/sql/unit/relations/join_spec.rb +0 -180
- data/spec/engines/sql/unit/relations/lock_spec.rb +0 -86
- data/spec/engines/sql/unit/relations/order_spec.rb +0 -161
- data/spec/engines/sql/unit/relations/project_spec.rb +0 -143
- data/spec/engines/sql/unit/relations/skip_spec.rb +0 -41
- data/spec/engines/sql/unit/relations/table_spec.rb +0 -122
- data/spec/engines/sql/unit/relations/take_spec.rb +0 -75
- data/spec/engines/sql/unit/relations/update_spec.rb +0 -203
- data/spec/engines/sql/unit/relations/where_spec.rb +0 -72
- data/spec/relations/join_spec.rb +0 -42
- data/spec/relations/relation_spec.rb +0 -31
- data/spec/shared/relation_spec.rb +0 -255
- data/spec/sql/christener_spec.rb +0 -70
- data/spec/support/connections/mysql_connection.rb +0 -14
- data/spec/support/connections/oracle_connection.rb +0 -17
- data/spec/support/connections/postgresql_connection.rb +0 -13
- data/spec/support/connections/sqlite3_connection.rb +0 -24
- data/spec/support/guards.rb +0 -28
- data/spec/support/matchers/disambiguate_attributes.rb +0 -28
- data/spec/support/matchers/hash_the_same_as.rb +0 -26
- data/spec/support/matchers/have_rows.rb +0 -18
- data/spec/support/model.rb +0 -67
- data/spec/support/schemas/mysql_schema.rb +0 -26
- data/spec/support/schemas/oracle_schema.rb +0 -20
- data/spec/support/schemas/postgresql_schema.rb +0 -26
- data/spec/support/schemas/sqlite3_schema.rb +0 -26
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,105 @@
|
|
1
|
+
History.txt
|
2
|
+
MIT-LICENSE.txt
|
3
|
+
Manifest.txt
|
4
|
+
README.markdown
|
5
|
+
Rakefile
|
6
|
+
arel.gemspec
|
7
|
+
lib/arel.rb
|
8
|
+
lib/arel/attributes.rb
|
9
|
+
lib/arel/attributes/attribute.rb
|
10
|
+
lib/arel/compatibility/wheres.rb
|
11
|
+
lib/arel/crud.rb
|
12
|
+
lib/arel/delete_manager.rb
|
13
|
+
lib/arel/deprecated.rb
|
14
|
+
lib/arel/expression.rb
|
15
|
+
lib/arel/expressions.rb
|
16
|
+
lib/arel/insert_manager.rb
|
17
|
+
lib/arel/nodes.rb
|
18
|
+
lib/arel/nodes/and.rb
|
19
|
+
lib/arel/nodes/assignment.rb
|
20
|
+
lib/arel/nodes/avg.rb
|
21
|
+
lib/arel/nodes/between.rb
|
22
|
+
lib/arel/nodes/binary.rb
|
23
|
+
lib/arel/nodes/count.rb
|
24
|
+
lib/arel/nodes/delete_statement.rb
|
25
|
+
lib/arel/nodes/does_not_match.rb
|
26
|
+
lib/arel/nodes/equality.rb
|
27
|
+
lib/arel/nodes/exists.rb
|
28
|
+
lib/arel/nodes/function.rb
|
29
|
+
lib/arel/nodes/greater_than.rb
|
30
|
+
lib/arel/nodes/greater_than_or_equal.rb
|
31
|
+
lib/arel/nodes/group.rb
|
32
|
+
lib/arel/nodes/grouping.rb
|
33
|
+
lib/arel/nodes/having.rb
|
34
|
+
lib/arel/nodes/in.rb
|
35
|
+
lib/arel/nodes/inner_join.rb
|
36
|
+
lib/arel/nodes/insert_statement.rb
|
37
|
+
lib/arel/nodes/join.rb
|
38
|
+
lib/arel/nodes/less_than.rb
|
39
|
+
lib/arel/nodes/less_than_or_equal.rb
|
40
|
+
lib/arel/nodes/lock.rb
|
41
|
+
lib/arel/nodes/matches.rb
|
42
|
+
lib/arel/nodes/max.rb
|
43
|
+
lib/arel/nodes/min.rb
|
44
|
+
lib/arel/nodes/node.rb
|
45
|
+
lib/arel/nodes/not_equal.rb
|
46
|
+
lib/arel/nodes/not_in.rb
|
47
|
+
lib/arel/nodes/offset.rb
|
48
|
+
lib/arel/nodes/on.rb
|
49
|
+
lib/arel/nodes/or.rb
|
50
|
+
lib/arel/nodes/ordering.rb
|
51
|
+
lib/arel/nodes/outer_join.rb
|
52
|
+
lib/arel/nodes/select_core.rb
|
53
|
+
lib/arel/nodes/select_statement.rb
|
54
|
+
lib/arel/nodes/sql_literal.rb
|
55
|
+
lib/arel/nodes/string_join.rb
|
56
|
+
lib/arel/nodes/sum.rb
|
57
|
+
lib/arel/nodes/table_alias.rb
|
58
|
+
lib/arel/nodes/unqualified_column.rb
|
59
|
+
lib/arel/nodes/update_statement.rb
|
60
|
+
lib/arel/nodes/values.rb
|
61
|
+
lib/arel/relation.rb
|
62
|
+
lib/arel/select_manager.rb
|
63
|
+
lib/arel/sql/engine.rb
|
64
|
+
lib/arel/sql_literal.rb
|
65
|
+
lib/arel/table.rb
|
66
|
+
lib/arel/tree_manager.rb
|
67
|
+
lib/arel/update_manager.rb
|
68
|
+
lib/arel/visitors.rb
|
69
|
+
lib/arel/visitors/dot.rb
|
70
|
+
lib/arel/visitors/join_sql.rb
|
71
|
+
lib/arel/visitors/mysql.rb
|
72
|
+
lib/arel/visitors/oracle.rb
|
73
|
+
lib/arel/visitors/order_clauses.rb
|
74
|
+
lib/arel/visitors/postgresql.rb
|
75
|
+
lib/arel/visitors/to_sql.rb
|
76
|
+
lib/arel/visitors/where_sql.rb
|
77
|
+
spec/activerecord_compat_spec.rb
|
78
|
+
spec/attributes/attribute_spec.rb
|
79
|
+
spec/attributes_spec.rb
|
80
|
+
spec/crud_spec.rb
|
81
|
+
spec/delete_manager_spec.rb
|
82
|
+
spec/insert_manager_spec.rb
|
83
|
+
spec/nodes/count_spec.rb
|
84
|
+
spec/nodes/delete_statement_spec.rb
|
85
|
+
spec/nodes/equality_spec.rb
|
86
|
+
spec/nodes/insert_statement_spec.rb
|
87
|
+
spec/nodes/or_spec.rb
|
88
|
+
spec/nodes/select_core_spec.rb
|
89
|
+
spec/nodes/select_statement_spec.rb
|
90
|
+
spec/nodes/sql_literal_spec.rb
|
91
|
+
spec/nodes/sum_spec.rb
|
92
|
+
spec/nodes/update_statement_spec.rb
|
93
|
+
spec/select_manager_spec.rb
|
94
|
+
spec/spec.opts
|
95
|
+
spec/spec_helper.rb
|
96
|
+
spec/support/check.rb
|
97
|
+
spec/support/fake_record.rb
|
98
|
+
spec/support/matchers.rb
|
99
|
+
spec/support/matchers/be_like.rb
|
100
|
+
spec/support/shared/tree_manager_shared.rb
|
101
|
+
spec/table_spec.rb
|
102
|
+
spec/update_manager_spec.rb
|
103
|
+
spec/visitors/join_sql_spec.rb
|
104
|
+
spec/visitors/oracle_spec.rb
|
105
|
+
spec/visitors/to_sql_spec.rb
|
data/README.markdown
CHANGED
@@ -1,14 +1,18 @@
|
|
1
|
-
|
1
|
+
# ARel
|
2
|
+
|
3
|
+
* http://github.com/rails/arel
|
4
|
+
|
5
|
+
## DESCRIPTION
|
2
6
|
|
3
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.
|
4
8
|
|
5
|
-
## Status
|
9
|
+
## Status
|
6
10
|
|
7
11
|
For the moment, Arel uses ActiveRecord's connection adapters to connect to the various engines, connection pooling, perform quoting, and do type conversion. On the horizon is the use of DataObjects instead.
|
8
12
|
|
9
13
|
The long term goal, following both LINQ and DataMapper, is to have Arel adapt to engines beyond RDBMS, including XML, IMAP, YAML, etc.
|
10
14
|
|
11
|
-
## A Gentle Introduction
|
15
|
+
## A Gentle Introduction
|
12
16
|
|
13
17
|
Generating a query with ARel is simple. For example, in order to produce
|
14
18
|
|
@@ -29,7 +33,7 @@ In other words, Arel relations implement Ruby's Enumerable interface. Let's have
|
|
29
33
|
|
30
34
|
As you can see, Arel converts the rows from the database into a hash, the values of which are sublimated to the appropriate Ruby primitive (integers, strings, and so forth).
|
31
35
|
|
32
|
-
### More Sophisticated
|
36
|
+
### More Sophisticated Queries
|
33
37
|
|
34
38
|
Here is a whirlwind tour through the most common relational operators. These will probably cover 80% of all interaction with the database.
|
35
39
|
|
@@ -56,7 +60,7 @@ What are called `LIMIT` and `OFFSET` in SQL are called `take` and `skip` in Arel
|
|
56
60
|
|
57
61
|
users.group(users[:name]) # => SELECT * FROM users GROUP BY name
|
58
62
|
|
59
|
-
The best property of the Relational Algebra is its "composability", or closure under all operations. For example, to
|
63
|
+
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:
|
60
64
|
|
61
65
|
users \
|
62
66
|
.where(users[:name].eq('amy')) \
|
@@ -85,11 +89,11 @@ Finally, most operations take a block form. For example:
|
|
85
89
|
|
86
90
|
This provides a (sometimes) convenient alternative syntax.
|
87
91
|
|
88
|
-
### The Crazy Features
|
92
|
+
### The Crazy Features
|
89
93
|
|
90
94
|
The examples above are fairly simple and other libraries match or come close to matching the expressiveness of Arel (e.g., `Sequel` in Ruby).
|
91
95
|
|
92
|
-
#### Complex Joins
|
96
|
+
#### Complex Joins
|
93
97
|
|
94
98
|
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:
|
95
99
|
|
@@ -124,7 +128,7 @@ Note that you do NOT want to do something like:
|
|
124
128
|
|
125
129
|
This does NOT have the same meaning as the previous query, since the comments[:parent_id] reference is effectively ambiguous.
|
126
130
|
|
127
|
-
#### Complex Aggregations
|
131
|
+
#### Complex Aggregations
|
128
132
|
|
129
133
|
My personal favorite feature of Arel, certainly the most difficult to implement, and possibly only of marginal value, is **closure under joining even in the presence of aggregations**. This is a feature where the Relational Algebra is fundamentally easier to use than SQL. Think of this as a preview of the kind of radical functionality that is to come, stuff no other "ORM" is doing.
|
130
134
|
|
@@ -180,27 +184,3 @@ As you can see, we're completely missing data for user with id 3. `dumpty` has n
|
|
180
184
|
FROM users
|
181
185
|
LEFT OUTER JOIN (SELECT user_id, count(*) as cnt FROM photos GROUP BY user_id) AS photos_aggregation
|
182
186
|
ON photos_aggregation.user_id = users.id
|
183
|
-
|
184
|
-
## ActiveRecord Adapter Support
|
185
|
-
|
186
|
-
Arel provides built-in support for the following ActiveRecord DB adapters:
|
187
|
-
|
188
|
-
* IBM DB
|
189
|
-
* MySQL
|
190
|
-
* Oracle
|
191
|
-
* PostgreSQL
|
192
|
-
* SQLite
|
193
|
-
|
194
|
-
You can add support for other adapters by defining a SQL compiler at the appropriate place. Here's an example: let's say
|
195
|
-
you've got a YourSQL adapter. Create a file at `yoursql/arel_compiler.rb` somewhere on the load path (presumably in
|
196
|
-
the YourSQL adapter gem). The contents of that file can be as simple as:
|
197
|
-
|
198
|
-
module Arel
|
199
|
-
module SqlCompiler
|
200
|
-
class YourSQLCompiler < GenericCompiler
|
201
|
-
end
|
202
|
-
end
|
203
|
-
end
|
204
|
-
|
205
|
-
Override any methods as necessary. See examples at
|
206
|
-
[lib/arel/engines/sql/compilers](http://github.com/rails/arel/tree/master/lib/arel/engines/sql/compilers/).
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
gem 'hoe', '>= 2.1.0'
|
3
|
+
require 'hoe'
|
4
|
+
|
5
|
+
Hoe.plugin :gemspec # `gem install hoe-gemspec`
|
6
|
+
|
7
|
+
Hoe.spec 'arel' do
|
8
|
+
developer('Aaron Patterson', 'aaron@tenderlovemaking.com')
|
9
|
+
developer('Bryan Halmkamp', 'bryan@brynary.com')
|
10
|
+
developer('Emilio Tagua', 'miloops@gmail.com')
|
11
|
+
developer('Nick Kallen', 'nick@example.org') # FIXME: need Nick's email
|
12
|
+
|
13
|
+
self.readme_file = 'README.markdown'
|
14
|
+
self.extra_rdoc_files = FileList['README.markdown']
|
15
|
+
self.extra_dev_deps << ['rspec', '~> 1.3.0']
|
16
|
+
self.testlib = :rspec
|
17
|
+
end
|
data/arel.gemspec
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{arel}
|
5
|
+
s.version = "2.0.0.dev.20100924164835"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Aaron Patterson", "Bryan Halmkamp", "Emilio Tagua", "Nick Kallen"]
|
9
|
+
s.date = %q{2010-09-24}
|
10
|
+
s.description = %q{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.}
|
11
|
+
s.email = ["aaron@tenderlovemaking.com", "bryan@brynary.com", "miloops@gmail.com", "nick@example.org"]
|
12
|
+
s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.markdown"]
|
13
|
+
s.files = ["History.txt", "Manifest.txt", "README.markdown", "Rakefile", "arel.gemspec", "lib/arel.rb", "lib/arel/attributes.rb", "lib/arel/attributes/attribute.rb", "lib/arel/compatibility/wheres.rb", "lib/arel/crud.rb", "lib/arel/delete_manager.rb", "lib/arel/deprecated.rb", "lib/arel/expression.rb", "lib/arel/expressions.rb", "lib/arel/insert_manager.rb", "lib/arel/nodes.rb", "lib/arel/nodes/and.rb", "lib/arel/nodes/assignment.rb", "lib/arel/nodes/avg.rb", "lib/arel/nodes/between.rb", "lib/arel/nodes/binary.rb", "lib/arel/nodes/count.rb", "lib/arel/nodes/delete_statement.rb", "lib/arel/nodes/equality.rb", "lib/arel/nodes/exists.rb", "lib/arel/nodes/function.rb", "lib/arel/nodes/greater_than.rb", "lib/arel/nodes/greater_than_or_equal.rb", "lib/arel/nodes/group.rb", "lib/arel/nodes/grouping.rb", "lib/arel/nodes/having.rb", "lib/arel/nodes/in.rb", "lib/arel/nodes/inner_join.rb", "lib/arel/nodes/insert_statement.rb", "lib/arel/nodes/join.rb", "lib/arel/nodes/less_than.rb", "lib/arel/nodes/less_than_or_equal.rb", "lib/arel/nodes/lock.rb", "lib/arel/nodes/max.rb", "lib/arel/nodes/min.rb", "lib/arel/nodes/node.rb", "lib/arel/nodes/not_equal.rb", "lib/arel/nodes/offset.rb", "lib/arel/nodes/on.rb", "lib/arel/nodes/or.rb", "lib/arel/nodes/outer_join.rb", "lib/arel/nodes/select_core.rb", "lib/arel/nodes/select_statement.rb", "lib/arel/nodes/sql_literal.rb", "lib/arel/nodes/string_join.rb", "lib/arel/nodes/sum.rb", "lib/arel/nodes/table_alias.rb", "lib/arel/nodes/unqualified_column.rb", "lib/arel/nodes/update_statement.rb", "lib/arel/nodes/values.rb", "lib/arel/relation.rb", "lib/arel/select_manager.rb", "lib/arel/sql/engine.rb", "lib/arel/sql_literal.rb", "lib/arel/table.rb", "lib/arel/tree_manager.rb", "lib/arel/update_manager.rb", "lib/arel/visitors.rb", "lib/arel/visitors/dot.rb", "lib/arel/visitors/join_sql.rb", "lib/arel/visitors/mysql.rb", "lib/arel/visitors/oracle.rb", "lib/arel/visitors/order_clauses.rb", "lib/arel/visitors/postgresql.rb", "lib/arel/visitors/to_sql.rb", "spec/activerecord_compat_spec.rb", "spec/attributes/attribute_spec.rb", "spec/attributes_spec.rb", "spec/crud_spec.rb", "spec/delete_manager_spec.rb", "spec/insert_manager_spec.rb", "spec/nodes/count_spec.rb", "spec/nodes/delete_statement_spec.rb", "spec/nodes/equality_spec.rb", "spec/nodes/insert_statement_spec.rb", "spec/nodes/or_spec.rb", "spec/nodes/select_core_spec.rb", "spec/nodes/select_statement_spec.rb", "spec/nodes/sql_literal_spec.rb", "spec/nodes/sum_spec.rb", "spec/nodes/update_statement_spec.rb", "spec/select_manager_spec.rb", "spec/spec.opts", "spec/spec_helper.rb", "spec/support/check.rb", "spec/support/fake_record.rb", "spec/support/matchers.rb", "spec/support/matchers/be_like.rb", "spec/support/shared/tree_manager_shared.rb", "spec/table_spec.rb", "spec/update_manager_spec.rb", "spec/visitors/join_sql_spec.rb", "spec/visitors/oracle_spec.rb", "spec/visitors/to_sql_spec.rb"]
|
14
|
+
s.homepage = %q{http://github.com/rails/arel}
|
15
|
+
s.rdoc_options = ["--main", "README.markdown"]
|
16
|
+
s.require_paths = ["lib"]
|
17
|
+
s.rubyforge_project = %q{arel}
|
18
|
+
s.rubygems_version = %q{1.3.7}
|
19
|
+
s.summary = %q{Arel is a Relational Algebra for Ruby}
|
20
|
+
|
21
|
+
if s.respond_to? :specification_version then
|
22
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
23
|
+
s.specification_version = 3
|
24
|
+
|
25
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
26
|
+
s.add_development_dependency(%q<rubyforge>, [">= 2.0.4"])
|
27
|
+
s.add_development_dependency(%q<rspec>, ["~> 1.3.0"])
|
28
|
+
s.add_development_dependency(%q<hoe>, [">= 2.6.0"])
|
29
|
+
else
|
30
|
+
s.add_dependency(%q<rubyforge>, [">= 2.0.4"])
|
31
|
+
s.add_dependency(%q<rspec>, ["~> 1.3.0"])
|
32
|
+
s.add_dependency(%q<hoe>, [">= 2.6.0"])
|
33
|
+
end
|
34
|
+
else
|
35
|
+
s.add_dependency(%q<rubyforge>, [">= 2.0.4"])
|
36
|
+
s.add_dependency(%q<rspec>, ["~> 1.3.0"])
|
37
|
+
s.add_dependency(%q<hoe>, [">= 2.6.0"])
|
38
|
+
end
|
39
|
+
end
|
data/lib/arel.rb
CHANGED
@@ -1,14 +1,35 @@
|
|
1
|
-
require '
|
2
|
-
require 'active_support/core_ext/module/delegation'
|
3
|
-
require 'active_support/core_ext/object/blank'
|
1
|
+
require 'arel/crud'
|
4
2
|
|
5
|
-
require 'arel/
|
3
|
+
require 'arel/expressions'
|
4
|
+
require 'arel/table'
|
5
|
+
require 'arel/attributes'
|
6
|
+
require 'arel/compatibility/wheres'
|
7
|
+
|
8
|
+
#### these are deprecated
|
9
|
+
# The Arel::Relation constant is referenced in Rails
|
10
|
+
require 'arel/relation'
|
11
|
+
require 'arel/expression'
|
12
|
+
####
|
13
|
+
|
14
|
+
require 'arel/visitors'
|
15
|
+
|
16
|
+
require 'arel/tree_manager'
|
17
|
+
require 'arel/insert_manager'
|
18
|
+
require 'arel/select_manager'
|
19
|
+
require 'arel/update_manager'
|
20
|
+
require 'arel/delete_manager'
|
21
|
+
require 'arel/nodes'
|
22
|
+
|
23
|
+
#### these are deprecated
|
24
|
+
require 'arel/deprecated'
|
25
|
+
require 'arel/sql/engine'
|
26
|
+
require 'arel/sql_literal'
|
27
|
+
####
|
6
28
|
|
7
29
|
module Arel
|
8
|
-
|
9
|
-
require 'arel/sql_literal'
|
10
|
-
require 'arel/engines'
|
11
|
-
require 'arel/version'
|
30
|
+
VERSION = '2.0.0'
|
12
31
|
|
13
|
-
|
32
|
+
def self.sql raw_sql
|
33
|
+
Arel::Nodes::SqlLiteral.new raw_sql
|
34
|
+
end
|
14
35
|
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
|
+
raise NotImplementedError, "Column type `#{column.type}` is not currently handled"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,190 @@
|
|
1
|
+
module Arel
|
2
|
+
module Attributes
|
3
|
+
class Attribute < Struct.new :relation, :name, :column
|
4
|
+
include Arel::Expressions
|
5
|
+
|
6
|
+
def not_eq other
|
7
|
+
Nodes::NotEqual.new self, other
|
8
|
+
end
|
9
|
+
|
10
|
+
def not_eq_any others
|
11
|
+
grouping_any :not_eq, others
|
12
|
+
end
|
13
|
+
|
14
|
+
def not_eq_all others
|
15
|
+
grouping_all :not_eq, others
|
16
|
+
end
|
17
|
+
|
18
|
+
def eq other
|
19
|
+
Nodes::Equality.new self, other
|
20
|
+
end
|
21
|
+
|
22
|
+
def eq_any others
|
23
|
+
grouping_any :eq, others
|
24
|
+
end
|
25
|
+
|
26
|
+
def eq_all others
|
27
|
+
grouping_all :eq, others
|
28
|
+
end
|
29
|
+
|
30
|
+
def in other
|
31
|
+
case other
|
32
|
+
when Arel::SelectManager
|
33
|
+
Nodes::In.new self, other.to_a.map { |x| x.id }
|
34
|
+
when Range
|
35
|
+
if other.exclude_end?
|
36
|
+
left = Nodes::GreaterThanOrEqual.new(self, other.min)
|
37
|
+
right = Nodes::LessThan.new(self, other.max + 1)
|
38
|
+
Nodes::And.new left, right
|
39
|
+
else
|
40
|
+
Nodes::Between.new(self, Nodes::And.new(other.min, other.max))
|
41
|
+
end
|
42
|
+
else
|
43
|
+
Nodes::In.new self, other
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def in_any others
|
48
|
+
grouping_any :in, others
|
49
|
+
end
|
50
|
+
|
51
|
+
def in_all others
|
52
|
+
grouping_all :in, others
|
53
|
+
end
|
54
|
+
|
55
|
+
def not_in other
|
56
|
+
case other
|
57
|
+
when Arel::SelectManager
|
58
|
+
Nodes::NotIn.new self, other.to_a.map { |x| x.id }
|
59
|
+
when Range
|
60
|
+
if other.exclude_end?
|
61
|
+
left = Nodes::LessThan.new(self, other.min)
|
62
|
+
right = Nodes::GreaterThanOrEqual.new(self, other.max)
|
63
|
+
Nodes::Or.new left, right
|
64
|
+
else
|
65
|
+
left = Nodes::LessThan.new(self, other.min)
|
66
|
+
right = Nodes::GreaterThan.new(self, other.max)
|
67
|
+
Nodes::Or.new left, right
|
68
|
+
end
|
69
|
+
else
|
70
|
+
Nodes::NotIn.new self, other
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def not_in_any others
|
75
|
+
grouping_any :not_in, others
|
76
|
+
end
|
77
|
+
|
78
|
+
def not_in_all others
|
79
|
+
grouping_all :not_in, others
|
80
|
+
end
|
81
|
+
|
82
|
+
def matches other
|
83
|
+
Nodes::Matches.new self, other
|
84
|
+
end
|
85
|
+
|
86
|
+
def matches_any others
|
87
|
+
grouping_any :matches, others
|
88
|
+
end
|
89
|
+
|
90
|
+
def matches_all others
|
91
|
+
grouping_all :matches, others
|
92
|
+
end
|
93
|
+
|
94
|
+
def does_not_match other
|
95
|
+
Nodes::DoesNotMatch.new self, other
|
96
|
+
end
|
97
|
+
|
98
|
+
def does_not_match_any others
|
99
|
+
grouping_any :does_not_match, others
|
100
|
+
end
|
101
|
+
|
102
|
+
def does_not_match_all others
|
103
|
+
grouping_all :does_not_match, others
|
104
|
+
end
|
105
|
+
|
106
|
+
def gteq right
|
107
|
+
Nodes::GreaterThanOrEqual.new self, right
|
108
|
+
end
|
109
|
+
|
110
|
+
def gteq_any others
|
111
|
+
grouping_any :gteq, others
|
112
|
+
end
|
113
|
+
|
114
|
+
def gteq_all others
|
115
|
+
grouping_all :gteq, others
|
116
|
+
end
|
117
|
+
|
118
|
+
def gt right
|
119
|
+
Nodes::GreaterThan.new self, right
|
120
|
+
end
|
121
|
+
|
122
|
+
def gt_any others
|
123
|
+
grouping_any :gt, others
|
124
|
+
end
|
125
|
+
|
126
|
+
def gt_all others
|
127
|
+
grouping_all :gt, others
|
128
|
+
end
|
129
|
+
|
130
|
+
def lt right
|
131
|
+
Nodes::LessThan.new self, right
|
132
|
+
end
|
133
|
+
|
134
|
+
def lt_any others
|
135
|
+
grouping_any :lt, others
|
136
|
+
end
|
137
|
+
|
138
|
+
def lt_all others
|
139
|
+
grouping_all :lt, others
|
140
|
+
end
|
141
|
+
|
142
|
+
def lteq right
|
143
|
+
Nodes::LessThanOrEqual.new self, right
|
144
|
+
end
|
145
|
+
|
146
|
+
def lteq_any others
|
147
|
+
grouping_any :lteq, others
|
148
|
+
end
|
149
|
+
|
150
|
+
def lteq_all others
|
151
|
+
grouping_all :lteq, others
|
152
|
+
end
|
153
|
+
|
154
|
+
def asc
|
155
|
+
Nodes::Ordering.new self, :asc
|
156
|
+
end
|
157
|
+
|
158
|
+
def desc
|
159
|
+
Nodes::Ordering.new self, :desc
|
160
|
+
end
|
161
|
+
|
162
|
+
private
|
163
|
+
|
164
|
+
def grouping_any method_id, others
|
165
|
+
first = send method_id, others.shift
|
166
|
+
|
167
|
+
Nodes::Grouping.new others.inject(first) { |memo,expr|
|
168
|
+
Nodes::Or.new(memo, send(method_id, expr))
|
169
|
+
}
|
170
|
+
end
|
171
|
+
|
172
|
+
def grouping_all method_id, others
|
173
|
+
first = send method_id, others.shift
|
174
|
+
|
175
|
+
Nodes::Grouping.new others.inject(first) { |memo,expr|
|
176
|
+
Nodes::And.new(memo, send(method_id, expr))
|
177
|
+
}
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
class String < Attribute; end
|
182
|
+
class Time < Attribute; end
|
183
|
+
class Boolean < Attribute; end
|
184
|
+
class Decimal < Attribute; end
|
185
|
+
class Float < Attribute; end
|
186
|
+
class Integer < Attribute; end
|
187
|
+
end
|
188
|
+
|
189
|
+
Attribute = Attributes::Attribute
|
190
|
+
end
|