arel 2.0.1 → 2.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. data/.autotest +26 -0
  2. data/History.txt +18 -0
  3. data/Manifest.txt +31 -30
  4. data/README.markdown +7 -99
  5. data/Rakefile +3 -2
  6. data/arel.gemspec +18 -11
  7. data/lib/arel.rb +2 -1
  8. data/lib/arel/attributes/attribute.rb +1 -174
  9. data/lib/arel/crud.rb +2 -2
  10. data/lib/arel/delete_manager.rb +4 -4
  11. data/lib/arel/insert_manager.rb +8 -8
  12. data/lib/arel/nodes/exists.rb +2 -6
  13. data/lib/arel/nodes/sql_literal.rb +1 -0
  14. data/lib/arel/predications.rb +177 -0
  15. data/lib/arel/select_manager.rb +17 -11
  16. data/lib/arel/table.rb +4 -0
  17. data/lib/arel/tree_manager.rb +4 -3
  18. data/lib/arel/update_manager.rb +8 -8
  19. data/lib/arel/visitors.rb +4 -0
  20. data/lib/arel/visitors/dot.rb +3 -3
  21. data/lib/arel/visitors/join_sql.rb +2 -0
  22. data/lib/arel/visitors/mysql.rb +14 -0
  23. data/lib/arel/visitors/oracle.rb +31 -1
  24. data/lib/arel/visitors/order_clauses.rb +2 -0
  25. data/lib/arel/visitors/sqlite.rb +11 -0
  26. data/lib/arel/visitors/to_sql.rb +8 -11
  27. data/lib/arel/visitors/visitor.rb +19 -0
  28. data/{spec/attributes/attribute_spec.rb → test/attributes/test_attribute.rb} +84 -84
  29. data/test/helper.rb +13 -0
  30. data/{spec/nodes/count_spec.rb → test/nodes/test_count.rb} +3 -3
  31. data/{spec/nodes/delete_statement_spec.rb → test/nodes/test_delete_statement.rb} +3 -4
  32. data/{spec/nodes/equality_spec.rb → test/nodes/test_equality.rb} +10 -8
  33. data/{spec/nodes/insert_statement_spec.rb → test/nodes/test_insert_statement.rb} +6 -6
  34. data/{spec/nodes/or_spec.rb → test/nodes/test_or.rb} +6 -4
  35. data/test/nodes/test_select_core.rb +22 -0
  36. data/{spec/nodes/select_statement_spec.rb → test/nodes/test_select_statement.rb} +3 -4
  37. data/test/nodes/test_sql_literal.rb +52 -0
  38. data/{spec/nodes/sum_spec.rb → test/nodes/test_sum.rb} +2 -2
  39. data/{spec/nodes/update_statement_spec.rb → test/nodes/test_update_statement.rb} +6 -6
  40. data/{spec → test}/support/fake_record.rb +4 -2
  41. data/{spec/activerecord_compat_spec.rb → test/test_activerecord_compat.rb} +3 -3
  42. data/{spec/attributes_spec.rb → test/test_attributes.rb} +7 -7
  43. data/{spec/crud_spec.rb → test/test_crud.rb} +4 -4
  44. data/{spec/delete_manager_spec.rb → test/test_delete_manager.rb} +5 -16
  45. data/{spec/insert_manager_spec.rb → test/test_insert_manager.rb} +15 -31
  46. data/{spec/select_manager_spec.rb → test/test_select_manager.rb} +95 -77
  47. data/{spec/table_spec.rb → test/test_table.rb} +38 -32
  48. data/{spec/update_manager_spec.rb → test/test_update_manager.rb} +9 -21
  49. data/{spec/visitors/join_sql_spec.rb → test/visitors/test_join_sql.rb} +3 -3
  50. data/test/visitors/test_mysql.rb +27 -0
  51. data/{spec/visitors/oracle_spec.rb → test/visitors/test_oracle.rb} +26 -10
  52. data/{spec/visitors/postgres_spec.rb → test/visitors/test_postgres.rb} +2 -2
  53. data/test/visitors/test_sqlite.rb +18 -0
  54. data/{spec/visitors/to_sql_spec.rb → test/visitors/test_to_sql.rb} +25 -18
  55. metadata +101 -43
  56. data/spec/nodes/select_core_spec.rb +0 -21
  57. data/spec/nodes/sql_literal_spec.rb +0 -26
  58. data/spec/spec.opts +0 -3
  59. data/spec/spec_helper.rb +0 -18
  60. data/spec/support/check.rb +0 -6
  61. data/spec/support/matchers.rb +0 -4
  62. data/spec/support/matchers/be_like.rb +0 -24
  63. data/spec/support/shared/tree_manager_shared.rb +0 -9
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 CHANGED
@@ -1,3 +1,21 @@
1
+ == 2.0.2
2
+
3
+ * Bug fixes
4
+
5
+ * MySQL selects from DUAL on empty FROM
6
+ * Visitor translates nil to NULL
7
+ * Visitor translates Bignum properly
8
+
9
+ == 2.0.1
10
+
11
+ * Bug fixes
12
+
13
+ == 2.0.0 / 2010-08-01
14
+ * Enhancements
15
+
16
+ * Recreate library using the Visitor pattern.
17
+ http://en.wikipedia.org/wiki/Visitor_pattern
18
+
1
19
  == 0.3.0 / 2010-03-10
2
20
 
3
21
  * Enhancements
data/Manifest.txt CHANGED
@@ -1,3 +1,4 @@
1
+ .autotest
1
2
  History.txt
2
3
  MIT-LICENSE.txt
3
4
  Manifest.txt
@@ -58,6 +59,7 @@ lib/arel/nodes/table_alias.rb
58
59
  lib/arel/nodes/unqualified_column.rb
59
60
  lib/arel/nodes/update_statement.rb
60
61
  lib/arel/nodes/values.rb
62
+ lib/arel/predications.rb
61
63
  lib/arel/relation.rb
62
64
  lib/arel/select_manager.rb
63
65
  lib/arel/sql/engine.rb
@@ -72,35 +74,34 @@ lib/arel/visitors/mysql.rb
72
74
  lib/arel/visitors/oracle.rb
73
75
  lib/arel/visitors/order_clauses.rb
74
76
  lib/arel/visitors/postgresql.rb
77
+ lib/arel/visitors/sqlite.rb
75
78
  lib/arel/visitors/to_sql.rb
79
+ lib/arel/visitors/visitor.rb
76
80
  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/postgres_spec.rb
106
- spec/visitors/to_sql_spec.rb
81
+ test/attributes/test_attribute.rb
82
+ test/helper.rb
83
+ test/nodes/test_count.rb
84
+ test/nodes/test_delete_statement.rb
85
+ test/nodes/test_equality.rb
86
+ test/nodes/test_insert_statement.rb
87
+ test/nodes/test_or.rb
88
+ test/nodes/test_select_core.rb
89
+ test/nodes/test_select_statement.rb
90
+ test/nodes/test_sql_literal.rb
91
+ test/nodes/test_sum.rb
92
+ test/nodes/test_update_statement.rb
93
+ test/support/fake_record.rb
94
+ test/test_activerecord_compat.rb
95
+ test/test_attributes.rb
96
+ test/test_crud.rb
97
+ test/test_delete_manager.rb
98
+ test/test_insert_manager.rb
99
+ test/test_select_manager.rb
100
+ test/test_table.rb
101
+ test/test_update_manager.rb
102
+ test/visitors/test_join_sql.rb
103
+ test/visitors/test_mysql.rb
104
+ test/visitors/test_oracle.rb
105
+ test/visitors/test_postgres.rb
106
+ test/visitors/test_sqlite.rb
107
+ test/visitors/test_to_sql.rb
data/README.markdown CHANGED
@@ -8,9 +8,7 @@ Arel is a Relational Algebra for Ruby. It 1) simplifies the generation complex o
8
8
 
9
9
  ## Status
10
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. On the horizon is the use of DataObjects instead.
12
-
13
- The long term goal, following both LINQ and DataMapper, is to have Arel adapt to engines beyond RDBMS, including XML, IMAP, YAML, etc.
11
+ For the moment, Arel uses ActiveRecord's connection adapters to connect to the various engines, connection pooling, perform quoting, and do type conversion.
14
12
 
15
13
  ## A Gentle Introduction
16
14
 
@@ -20,19 +18,10 @@ Generating a query with ARel is simple. For example, in order to produce
20
18
 
21
19
  you construct a table relation and convert it to sql:
22
20
 
23
- users = Table(:users)
21
+ users = Arel::Table.new(:users)
22
+ users.project(Arel.sql('*'))
24
23
  users.to_sql
25
24
 
26
- In fact, you will probably never call `#to_sql`. Rather, you'll work with data from the table directly. You can iterate through all rows in the `users` table like this:
27
-
28
- users.each { |user| ... }
29
-
30
- In other words, Arel relations implement Ruby's Enumerable interface. Let's have a look at a concrete example:
31
-
32
- users.first # => { users[:id] => 1, users[:name] => 'bob' }
33
-
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).
35
-
36
25
  ### More Sophisticated Queries
37
26
 
38
27
  Here is a whirlwind tour through the most common relational operators. These will probably cover 80% of all interaction with the database.
@@ -75,19 +64,11 @@ Of course, many of the operators take multiple arguments, so the last example ca
75
64
 
76
65
  users.where(users[:name].eq('bob'), users[:age].lt(25))
77
66
 
78
- The `OR` operator is not yet supported. It will work like this:
67
+ The `OR` operator works like this:
79
68
 
80
69
  users.where(users[:name].eq('bob').or(users[:age].lt(25)))
81
70
 
82
- The `AND` operator will behave similarly.
83
-
84
- Finally, most operations take a block form. For example:
85
-
86
- Table(:users) \
87
- .where { |u| u[:id].eq(1) } \
88
- .project { |u| u[:id] }
89
-
90
- This provides a (sometimes) convenient alternative syntax.
71
+ The `AND` operator behaves similarly.
91
72
 
92
73
  ### The Crazy Features
93
74
 
@@ -97,11 +78,11 @@ The examples above are fairly simple and other libraries match or come close to
97
78
 
98
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:
99
80
 
100
- comments = Table(:comments)
81
+ comments = Arel::Table.new(:comments)
101
82
 
102
83
  And this table has the following attributes:
103
84
 
104
- comments.attributes # => [comments[:id], comments[:body], comments[:parent_id]]
85
+ comments.columns # => [comments[:id], comments[:body], comments[:parent_id]]
105
86
 
106
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:
107
88
 
@@ -110,77 +91,4 @@ The `parent_id` column is a foreign key from the `comments` table to itself. Now
110
91
  comments.join(replies).on(replies[:parent_id].eq(comments[:id]))
111
92
  # => SELECT * FROM comments INNER JOIN comments AS comments_2 WHERE comments_2.parent_id = comments.id
112
93
 
113
- The call to `#alias` is actually optional: Arel will always produce a unique name for every table joined in the relation, and it will always do so deterministically to exploit query caching. Explicit aliasing is more common, however. When you want to extract specific slices of data, aliased tables are a necessity. For example to get just certain columns from the row, treat a row like a hash:
114
-
115
- comments_with_replies.first[replies[:body]]
116
-
117
94
  This will return the first comment's reply's body.
118
-
119
- If you don't need to extract the data later (for example, you're simply doing a join to find comments that have replies, you don't care what the content of the replies are), the block form may be preferable:
120
-
121
- comments.join(comments) { |comments, replies| replies[:parent_id].eq(comments[:id]) }
122
- # => SELECT * FROM comments INNER JOIN comments AS comments_2 WHERE comments_2.parent_id = comments.id
123
-
124
- Note that you do NOT want to do something like:
125
-
126
- comments.join(comments, comments[:parent_id].eq(comments[:id]))
127
- # => SELECT * FROM comments INNER JOIN comments AS comments_2 WHERE comments.parent_id = comments.id
128
-
129
- This does NOT have the same meaning as the previous query, since the comments[:parent_id] reference is effectively ambiguous.
130
-
131
- #### Complex Aggregations
132
-
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.
134
-
135
- The easiest way to introduce this is in SQL. Your task is to get all users and the **count** of their associated photos. Let's start from the inside out:
136
-
137
- SELECT count(*)
138
- FROM photos
139
- GROUP BY user_id
140
-
141
- Now, we'd like to join this with the user table. Naively, you might try to do this:
142
-
143
- SELECT users.*, count(photos.id)
144
- FROM users
145
- LEFT OUTER JOIN photos
146
- ON users.id = photos.user_id
147
- GROUP BY photos.user_id
148
-
149
- Of course, this has a slightly different meaning than our intended query. This is actually a fairly advanced topic in SQL so let's see why this doesn't work *step by step*. Suppose we have these records in our `users` table:
150
-
151
- mysql> select * from users;
152
- +------+--------+
153
- | id | name |
154
- +------+--------+
155
- | 1 | hai |
156
- | 2 | bai |
157
- | 3 | dumpty |
158
- +------+--------+
159
-
160
- And these in the photos table:
161
-
162
- mysql> select * from photos;
163
- +------+---------+-----------+
164
- | id | user_id | camera_id |
165
- +------+---------+-----------+
166
- | 1 | 1 | 1 |
167
- | 2 | 1 | 1 |
168
- | 3 | 1 | 1 |
169
- +------+---------+-----------+
170
-
171
- If we perform the above, incorrect query, we get the following:
172
-
173
- mysql> select users.*, count(photos.id) from users left outer join photos on users.id = photos.user_id limit 3 group by user_id;
174
- +------+------+------------------+
175
- | id | name | count(photos.id) |
176
- +------+------+------------------+
177
- | 2 | bai | 0 |
178
- | 1 | hai | 3 |
179
- +------+------+------------------+
180
-
181
- As you can see, we're completely missing data for user with id 3. `dumpty` has no photos, neither does `bai`. But strangely `bai` appeared and `dumpty` didn't! The reason is that the `GROUP BY` clause is aggregating on both tables, not just the `photos` table. All users without photos have a `photos.id` of `null` (thanks to the left outer join). These are rolled up together and an arbitrary user wins. In this case, `bai` not `dumpty`.
182
-
183
- SELECT users.*, photos_aggregation.cnt
184
- FROM users
185
- LEFT OUTER JOIN (SELECT user_id, count(*) as cnt FROM photos GROUP BY user_id) AS photos_aggregation
186
- ON photos_aggregation.user_id = users.id
data/Rakefile CHANGED
@@ -2,6 +2,7 @@ require "rubygems"
2
2
  gem 'hoe', '>= 2.1.0'
3
3
  require 'hoe'
4
4
 
5
+ Hoe.plugin :minitest
5
6
  Hoe.plugin :gemspec # `gem install hoe-gemspec`
6
7
 
7
8
  Hoe.spec 'arel' do
@@ -12,6 +13,6 @@ Hoe.spec 'arel' do
12
13
 
13
14
  self.readme_file = 'README.markdown'
14
15
  self.extra_rdoc_files = FileList['README.markdown']
15
- self.extra_dev_deps << ['rspec', '~> 1.3.0']
16
- self.testlib = :rspec
16
+ self.extra_dev_deps << [ 'hoe', '>= 2.1.0' ]
17
+ self.extra_dev_deps << [ 'minitest', '>= 1.6.0' ]
17
18
  end
data/arel.gemspec CHANGED
@@ -2,21 +2,22 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{arel}
5
- s.version = "2.0.0.dev.20100924164835"
5
+ s.version = "2.0.1.20101111105523"
6
6
 
7
- s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Aaron Patterson", "Bryan Halmkamp", "Emilio Tagua", "Nick Kallen"]
9
- s.date = %q{2010-09-24}
9
+ s.date = %q{2010-11-11}
10
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
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"]
12
+ s.extra_rdoc_files = ["History.txt", "MIT-LICENSE.txt", "Manifest.txt", "README.markdown"]
13
+ s.files = [".autotest", "History.txt", "MIT-LICENSE.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/does_not_match.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/matches.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/not_in.rb", "lib/arel/nodes/offset.rb", "lib/arel/nodes/on.rb", "lib/arel/nodes/or.rb", "lib/arel/nodes/ordering.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/predications.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/sqlite.rb", "lib/arel/visitors/to_sql.rb", "lib/arel/visitors/visitor.rb", "lib/arel/visitors/where_sql.rb", "test/attributes/test_attribute.rb", "test/helper.rb", "test/nodes/test_count.rb", "test/nodes/test_delete_statement.rb", "test/nodes/test_equality.rb", "test/nodes/test_insert_statement.rb", "test/nodes/test_or.rb", "test/nodes/test_select_core.rb", "test/nodes/test_select_statement.rb", "test/nodes/test_sql_literal.rb", "test/nodes/test_sum.rb", "test/nodes/test_update_statement.rb", "test/support/fake_record.rb", "test/test_activerecord_compat.rb", "test/test_attributes.rb", "test/test_crud.rb", "test/test_delete_manager.rb", "test/test_insert_manager.rb", "test/test_select_manager.rb", "test/test_table.rb", "test/test_update_manager.rb", "test/visitors/test_join_sql.rb", "test/visitors/test_mysql.rb", "test/visitors/test_oracle.rb", "test/visitors/test_postgres.rb", "test/visitors/test_sqlite.rb", "test/visitors/test_to_sql.rb"]
14
14
  s.homepage = %q{http://github.com/rails/arel}
15
15
  s.rdoc_options = ["--main", "README.markdown"]
16
16
  s.require_paths = ["lib"]
17
17
  s.rubyforge_project = %q{arel}
18
18
  s.rubygems_version = %q{1.3.7}
19
19
  s.summary = %q{Arel is a Relational Algebra for Ruby}
20
+ s.test_files = ["test/attributes/test_attribute.rb", "test/nodes/test_count.rb", "test/nodes/test_delete_statement.rb", "test/nodes/test_equality.rb", "test/nodes/test_insert_statement.rb", "test/nodes/test_or.rb", "test/nodes/test_select_core.rb", "test/nodes/test_select_statement.rb", "test/nodes/test_sql_literal.rb", "test/nodes/test_sum.rb", "test/nodes/test_update_statement.rb", "test/test_activerecord_compat.rb", "test/test_attributes.rb", "test/test_crud.rb", "test/test_delete_manager.rb", "test/test_insert_manager.rb", "test/test_select_manager.rb", "test/test_table.rb", "test/test_update_manager.rb", "test/visitors/test_join_sql.rb", "test/visitors/test_mysql.rb", "test/visitors/test_oracle.rb", "test/visitors/test_postgres.rb", "test/visitors/test_sqlite.rb", "test/visitors/test_to_sql.rb"]
20
21
 
21
22
  if s.respond_to? :specification_version then
22
23
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
@@ -24,16 +25,22 @@ Gem::Specification.new do |s|
24
25
 
25
26
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
26
27
  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"])
28
+ s.add_development_dependency(%q<minitest>, [">= 2.0.0.beta"])
29
+ s.add_development_dependency(%q<hoe>, [">= 2.1.0"])
30
+ s.add_development_dependency(%q<minitest>, [">= 1.6.0"])
31
+ s.add_development_dependency(%q<hoe>, [">= 2.6.2"])
29
32
  else
30
33
  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"])
34
+ s.add_dependency(%q<minitest>, [">= 2.0.0.beta"])
35
+ s.add_dependency(%q<hoe>, [">= 2.1.0"])
36
+ s.add_dependency(%q<minitest>, [">= 1.6.0"])
37
+ s.add_dependency(%q<hoe>, [">= 2.6.2"])
33
38
  end
34
39
  else
35
40
  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"])
41
+ s.add_dependency(%q<minitest>, [">= 2.0.0.beta"])
42
+ s.add_dependency(%q<hoe>, [">= 2.1.0"])
43
+ s.add_dependency(%q<minitest>, [">= 1.6.0"])
44
+ s.add_dependency(%q<hoe>, [">= 2.6.2"])
38
45
  end
39
46
  end
data/lib/arel.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require 'arel/crud'
2
2
 
3
3
  require 'arel/expressions'
4
+ require 'arel/predications'
4
5
  require 'arel/table'
5
6
  require 'arel/attributes'
6
7
  require 'arel/compatibility/wheres'
@@ -27,7 +28,7 @@ require 'arel/sql_literal'
27
28
  ####
28
29
 
29
30
  module Arel
30
- VERSION = '2.0.1'
31
+ VERSION = '2.0.2'
31
32
 
32
33
  def self.sql raw_sql
33
34
  Arel::Nodes::SqlLiteral.new raw_sql
@@ -2,180 +2,7 @@ module Arel
2
2
  module Attributes
3
3
  class Attribute < Struct.new :relation, :name, :column
4
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
5
+ include Arel::Predications
179
6
  end
180
7
 
181
8
  class String < Attribute; end