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.
Files changed (125) hide show
  1. data/.autotest +26 -0
  2. data/History.txt +105 -0
  3. data/MIT-LICENSE.txt +20 -0
  4. data/Manifest.txt +124 -0
  5. data/README.markdown +94 -0
  6. data/Rakefile +20 -0
  7. data/lib/arel.rb +39 -0
  8. data/lib/arel/attributes.rb +20 -0
  9. data/lib/arel/attributes/attribute.rb +18 -0
  10. data/lib/arel/compatibility/wheres.rb +33 -0
  11. data/lib/arel/crud.rb +37 -0
  12. data/lib/arel/delete_manager.rb +18 -0
  13. data/lib/arel/deprecated.rb +4 -0
  14. data/lib/arel/expression.rb +4 -0
  15. data/lib/arel/expressions.rb +23 -0
  16. data/lib/arel/insert_manager.rb +34 -0
  17. data/lib/arel/nodes.rb +53 -0
  18. data/lib/arel/nodes/and.rb +6 -0
  19. data/lib/arel/nodes/as.rb +6 -0
  20. data/lib/arel/nodes/assignment.rb +6 -0
  21. data/lib/arel/nodes/avg.rb +6 -0
  22. data/lib/arel/nodes/between.rb +6 -0
  23. data/lib/arel/nodes/binary.rb +12 -0
  24. data/lib/arel/nodes/count.rb +13 -0
  25. data/lib/arel/nodes/delete_statement.rb +19 -0
  26. data/lib/arel/nodes/does_not_match.rb +6 -0
  27. data/lib/arel/nodes/equality.rb +9 -0
  28. data/lib/arel/nodes/except.rb +7 -0
  29. data/lib/arel/nodes/exists.rb +7 -0
  30. data/lib/arel/nodes/function.rb +18 -0
  31. data/lib/arel/nodes/greater_than.rb +6 -0
  32. data/lib/arel/nodes/greater_than_or_equal.rb +6 -0
  33. data/lib/arel/nodes/group.rb +6 -0
  34. data/lib/arel/nodes/grouping.rb +6 -0
  35. data/lib/arel/nodes/having.rb +6 -0
  36. data/lib/arel/nodes/in.rb +6 -0
  37. data/lib/arel/nodes/inner_join.rb +6 -0
  38. data/lib/arel/nodes/insert_statement.rb +19 -0
  39. data/lib/arel/nodes/intersect.rb +7 -0
  40. data/lib/arel/nodes/join.rb +13 -0
  41. data/lib/arel/nodes/less_than.rb +6 -0
  42. data/lib/arel/nodes/less_than_or_equal.rb +6 -0
  43. data/lib/arel/nodes/limit.rb +7 -0
  44. data/lib/arel/nodes/lock.rb +6 -0
  45. data/lib/arel/nodes/matches.rb +6 -0
  46. data/lib/arel/nodes/max.rb +6 -0
  47. data/lib/arel/nodes/min.rb +6 -0
  48. data/lib/arel/nodes/node.rb +44 -0
  49. data/lib/arel/nodes/not.rb +6 -0
  50. data/lib/arel/nodes/not_equal.rb +6 -0
  51. data/lib/arel/nodes/not_in.rb +6 -0
  52. data/lib/arel/nodes/offset.rb +7 -0
  53. data/lib/arel/nodes/on.rb +6 -0
  54. data/lib/arel/nodes/or.rb +6 -0
  55. data/lib/arel/nodes/ordering.rb +20 -0
  56. data/lib/arel/nodes/outer_join.rb +6 -0
  57. data/lib/arel/nodes/select_core.rb +26 -0
  58. data/lib/arel/nodes/select_statement.rb +22 -0
  59. data/lib/arel/nodes/sql_literal.rb +8 -0
  60. data/lib/arel/nodes/string_join.rb +11 -0
  61. data/lib/arel/nodes/sum.rb +6 -0
  62. data/lib/arel/nodes/table_alias.rb +13 -0
  63. data/lib/arel/nodes/top.rb +6 -0
  64. data/lib/arel/nodes/unary.rb +11 -0
  65. data/lib/arel/nodes/union.rb +7 -0
  66. data/lib/arel/nodes/union_all.rb +7 -0
  67. data/lib/arel/nodes/unqualified_column.rb +16 -0
  68. data/lib/arel/nodes/update_statement.rb +21 -0
  69. data/lib/arel/nodes/values.rb +14 -0
  70. data/lib/arel/predications.rb +183 -0
  71. data/lib/arel/relation.rb +6 -0
  72. data/lib/arel/select_manager.rb +237 -0
  73. data/lib/arel/sql/engine.rb +10 -0
  74. data/lib/arel/sql_literal.rb +4 -0
  75. data/lib/arel/table.rb +134 -0
  76. data/lib/arel/tree_manager.rb +36 -0
  77. data/lib/arel/update_manager.rb +49 -0
  78. data/lib/arel/visitors.rb +38 -0
  79. data/lib/arel/visitors/depth_first.rb +154 -0
  80. data/lib/arel/visitors/dot.rb +230 -0
  81. data/lib/arel/visitors/join_sql.rb +40 -0
  82. data/lib/arel/visitors/mssql.rb +16 -0
  83. data/lib/arel/visitors/mysql.rb +34 -0
  84. data/lib/arel/visitors/oracle.rb +116 -0
  85. data/lib/arel/visitors/order_clauses.rb +11 -0
  86. data/lib/arel/visitors/postgresql.rb +58 -0
  87. data/lib/arel/visitors/sqlite.rb +11 -0
  88. data/lib/arel/visitors/to_sql.rb +331 -0
  89. data/lib/arel/visitors/visitor.rb +27 -0
  90. data/lib/arel/visitors/where_sql.rb +9 -0
  91. data/square-arel.gemspec +36 -0
  92. data/test/attributes/test_attribute.rb +664 -0
  93. data/test/helper.rb +13 -0
  94. data/test/nodes/test_as.rb +16 -0
  95. data/test/nodes/test_count.rb +18 -0
  96. data/test/nodes/test_delete_statement.rb +14 -0
  97. data/test/nodes/test_equality.rb +74 -0
  98. data/test/nodes/test_insert_statement.rb +18 -0
  99. data/test/nodes/test_node.rb +33 -0
  100. data/test/nodes/test_not.rb +20 -0
  101. data/test/nodes/test_or.rb +22 -0
  102. data/test/nodes/test_select_core.rb +22 -0
  103. data/test/nodes/test_select_statement.rb +13 -0
  104. data/test/nodes/test_sql_literal.rb +52 -0
  105. data/test/nodes/test_sum.rb +12 -0
  106. data/test/nodes/test_update_statement.rb +18 -0
  107. data/test/support/fake_record.rb +91 -0
  108. data/test/test_activerecord_compat.rb +18 -0
  109. data/test/test_attributes.rb +46 -0
  110. data/test/test_crud.rb +69 -0
  111. data/test/test_delete_manager.rb +42 -0
  112. data/test/test_insert_manager.rb +125 -0
  113. data/test/test_select_manager.rb +659 -0
  114. data/test/test_table.rb +193 -0
  115. data/test/test_update_manager.rb +86 -0
  116. data/test/visitors/test_depth_first.rb +212 -0
  117. data/test/visitors/test_dot.rb +29 -0
  118. data/test/visitors/test_join_sql.rb +35 -0
  119. data/test/visitors/test_mssql.rb +18 -0
  120. data/test/visitors/test_mysql.rb +45 -0
  121. data/test/visitors/test_oracle.rb +147 -0
  122. data/test/visitors/test_postgres.rb +36 -0
  123. data/test/visitors/test_sqlite.rb +18 -0
  124. data/test/visitors/test_to_sql.rb +255 -0
  125. metadata +261 -0
@@ -0,0 +1,27 @@
1
+ module Arel
2
+ module Visitors
3
+ class Visitor
4
+ def accept object
5
+ visit object
6
+ end
7
+
8
+ private
9
+
10
+ DISPATCH = Hash.new do |hash, klass|
11
+ hash[klass] = "visit_#{(klass.name || '').gsub('::', '_')}"
12
+ end
13
+
14
+ def visit object
15
+ send DISPATCH[object.class], object
16
+ rescue NoMethodError => e
17
+ raise e if respond_to?(DISPATCH[object.class], true)
18
+ superklass = object.class.ancestors.find { |klass|
19
+ respond_to?(DISPATCH[klass], true)
20
+ }
21
+ raise(TypeError, "Cannot visit #{object.class}") unless superklass
22
+ DISPATCH[object.class] = DISPATCH[superklass]
23
+ retry
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,9 @@
1
+ module Arel
2
+ module Visitors
3
+ class WhereSql < Arel::Visitors::ToSql
4
+ def visit_Arel_Nodes_SelectCore o
5
+ "WHERE #{o.wheres.map { |x| visit x }.join ' AND ' }"
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,36 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{square-arel}
5
+ s.version = "2.0.9.20110222133018"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Aaron Patterson", "Bryan Halmkamp", "Emilio Tagua", "Nick Kallen"]
9
+ s.date = %q{2011-02-22}
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", "MIT-LICENSE.txt", "Manifest.txt", "README.markdown"]
13
+ s.files = [".autotest", "History.txt", "MIT-LICENSE.txt", "Manifest.txt", "README.markdown", "Rakefile", "square-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/as.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/except.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/intersect.rb", "lib/arel/nodes/join.rb", "lib/arel/nodes/less_than.rb", "lib/arel/nodes/less_than_or_equal.rb", "lib/arel/nodes/limit.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.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/top.rb", "lib/arel/nodes/unary.rb", "lib/arel/nodes/union.rb", "lib/arel/nodes/union_all.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/depth_first.rb", "lib/arel/visitors/dot.rb", "lib/arel/visitors/join_sql.rb", "lib/arel/visitors/mssql.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_as.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_node.rb", "test/nodes/test_not.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_depth_first.rb", "test/visitors/test_dot.rb", "test/visitors/test_join_sql.rb", "test/visitors/test_mssql.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
+ 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.5.0}
19
+ s.summary = %q{Arel is a Relational Algebra for Ruby}
20
+ s.test_files = ["test/attributes/test_attribute.rb", "test/nodes/test_as.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_node.rb", "test/nodes/test_not.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_depth_first.rb", "test/visitors/test_dot.rb", "test/visitors/test_join_sql.rb", "test/visitors/test_mssql.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"]
21
+
22
+ if s.respond_to? :specification_version then
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<minitest>, [">= 2.0.0"])
27
+ s.add_development_dependency(%q<hoe>, [">= 2.8.0"])
28
+ else
29
+ s.add_dependency(%q<minitest>, [">= 2.0.0"])
30
+ s.add_dependency(%q<hoe>, [">= 2.8.0"])
31
+ end
32
+ else
33
+ s.add_dependency(%q<minitest>, [">= 2.0.0"])
34
+ s.add_dependency(%q<hoe>, [">= 2.8.0"])
35
+ end
36
+ end
@@ -0,0 +1,664 @@
1
+ require 'helper'
2
+
3
+ module Arel
4
+ module Attributes
5
+ describe 'attribute' do
6
+ describe '#not_eq' do
7
+ it 'should create a NotEqual node' do
8
+ relation = Table.new(:users)
9
+ relation[:id].not_eq(10).must_be_kind_of Nodes::NotEqual
10
+ end
11
+
12
+ it 'should generate != in sql' do
13
+ relation = Table.new(:users)
14
+ mgr = relation.project relation[:id]
15
+ mgr.where relation[:id].not_eq(10)
16
+ mgr.to_sql.must_be_like %{
17
+ SELECT "users"."id" FROM "users" WHERE "users"."id" != 10
18
+ }
19
+ end
20
+
21
+ it 'should handle nil' do
22
+ relation = Table.new(:users)
23
+ mgr = relation.project relation[:id]
24
+ mgr.where relation[:id].not_eq(nil)
25
+ mgr.to_sql.must_be_like %{
26
+ SELECT "users"."id" FROM "users" WHERE "users"."id" IS NOT NULL
27
+ }
28
+ end
29
+ end
30
+
31
+ describe '#not_eq_any' do
32
+ it 'should create a Grouping node' do
33
+ relation = Table.new(:users)
34
+ relation[:id].not_eq_any([1,2]).must_be_kind_of Nodes::Grouping
35
+ end
36
+
37
+ it 'should generate ORs in sql' do
38
+ relation = Table.new(:users)
39
+ mgr = relation.project relation[:id]
40
+ mgr.where relation[:id].not_eq_any([1,2])
41
+ mgr.to_sql.must_be_like %{
42
+ SELECT "users"."id" FROM "users" WHERE ("users"."id" != 1 OR "users"."id" != 2)
43
+ }
44
+ end
45
+ end
46
+
47
+ describe '#not_eq_all' do
48
+ it 'should create a Grouping node' do
49
+ relation = Table.new(:users)
50
+ relation[:id].not_eq_all([1,2]).must_be_kind_of Nodes::Grouping
51
+ end
52
+
53
+ it 'should generate ANDs in sql' do
54
+ relation = Table.new(:users)
55
+ mgr = relation.project relation[:id]
56
+ mgr.where relation[:id].not_eq_all([1,2])
57
+ mgr.to_sql.must_be_like %{
58
+ SELECT "users"."id" FROM "users" WHERE ("users"."id" != 1 AND "users"."id" != 2)
59
+ }
60
+ end
61
+ end
62
+
63
+ describe '#gt' do
64
+ it 'should create a GreaterThan node' do
65
+ relation = Table.new(:users)
66
+ relation[:id].gt(10).must_be_kind_of Nodes::GreaterThan
67
+ end
68
+
69
+ it 'should generate >= in sql' do
70
+ relation = Table.new(:users)
71
+ mgr = relation.project relation[:id]
72
+ mgr.where relation[:id].gt(10)
73
+ mgr.to_sql.must_be_like %{
74
+ SELECT "users"."id" FROM "users" WHERE "users"."id" > 10
75
+ }
76
+ end
77
+ end
78
+
79
+ describe '#gt_any' do
80
+ it 'should create a Grouping node' do
81
+ relation = Table.new(:users)
82
+ relation[:id].gt_any([1,2]).must_be_kind_of Nodes::Grouping
83
+ end
84
+
85
+ it 'should generate ORs in sql' do
86
+ relation = Table.new(:users)
87
+ mgr = relation.project relation[:id]
88
+ mgr.where relation[:id].gt_any([1,2])
89
+ mgr.to_sql.must_be_like %{
90
+ SELECT "users"."id" FROM "users" WHERE ("users"."id" > 1 OR "users"."id" > 2)
91
+ }
92
+ end
93
+ end
94
+
95
+ describe '#gt_all' do
96
+ it 'should create a Grouping node' do
97
+ relation = Table.new(:users)
98
+ relation[:id].gt_all([1,2]).must_be_kind_of Nodes::Grouping
99
+ end
100
+
101
+ it 'should generate ANDs in sql' do
102
+ relation = Table.new(:users)
103
+ mgr = relation.project relation[:id]
104
+ mgr.where relation[:id].gt_all([1,2])
105
+ mgr.to_sql.must_be_like %{
106
+ SELECT "users"."id" FROM "users" WHERE ("users"."id" > 1 AND "users"."id" > 2)
107
+ }
108
+ end
109
+ end
110
+
111
+ describe '#gteq' do
112
+ it 'should create a GreaterThanOrEqual node' do
113
+ relation = Table.new(:users)
114
+ relation[:id].gteq(10).must_be_kind_of Nodes::GreaterThanOrEqual
115
+ end
116
+
117
+ it 'should generate >= in sql' do
118
+ relation = Table.new(:users)
119
+ mgr = relation.project relation[:id]
120
+ mgr.where relation[:id].gteq(10)
121
+ mgr.to_sql.must_be_like %{
122
+ SELECT "users"."id" FROM "users" WHERE "users"."id" >= 10
123
+ }
124
+ end
125
+ end
126
+
127
+ describe '#gteq_any' do
128
+ it 'should create a Grouping node' do
129
+ relation = Table.new(:users)
130
+ relation[:id].gteq_any([1,2]).must_be_kind_of Nodes::Grouping
131
+ end
132
+
133
+ it 'should generate ORs in sql' do
134
+ relation = Table.new(:users)
135
+ mgr = relation.project relation[:id]
136
+ mgr.where relation[:id].gteq_any([1,2])
137
+ mgr.to_sql.must_be_like %{
138
+ SELECT "users"."id" FROM "users" WHERE ("users"."id" >= 1 OR "users"."id" >= 2)
139
+ }
140
+ end
141
+ end
142
+
143
+ describe '#gteq_all' do
144
+ it 'should create a Grouping node' do
145
+ relation = Table.new(:users)
146
+ relation[:id].gteq_all([1,2]).must_be_kind_of Nodes::Grouping
147
+ end
148
+
149
+ it 'should generate ANDs in sql' do
150
+ relation = Table.new(:users)
151
+ mgr = relation.project relation[:id]
152
+ mgr.where relation[:id].gteq_all([1,2])
153
+ mgr.to_sql.must_be_like %{
154
+ SELECT "users"."id" FROM "users" WHERE ("users"."id" >= 1 AND "users"."id" >= 2)
155
+ }
156
+ end
157
+ end
158
+
159
+ describe '#lt' do
160
+ it 'should create a LessThan node' do
161
+ relation = Table.new(:users)
162
+ relation[:id].lt(10).must_be_kind_of Nodes::LessThan
163
+ end
164
+
165
+ it 'should generate < in sql' do
166
+ relation = Table.new(:users)
167
+ mgr = relation.project relation[:id]
168
+ mgr.where relation[:id].lt(10)
169
+ mgr.to_sql.must_be_like %{
170
+ SELECT "users"."id" FROM "users" WHERE "users"."id" < 10
171
+ }
172
+ end
173
+ end
174
+
175
+ describe '#lt_any' do
176
+ it 'should create a Grouping node' do
177
+ relation = Table.new(:users)
178
+ relation[:id].lt_any([1,2]).must_be_kind_of Nodes::Grouping
179
+ end
180
+
181
+ it 'should generate ORs in sql' do
182
+ relation = Table.new(:users)
183
+ mgr = relation.project relation[:id]
184
+ mgr.where relation[:id].lt_any([1,2])
185
+ mgr.to_sql.must_be_like %{
186
+ SELECT "users"."id" FROM "users" WHERE ("users"."id" < 1 OR "users"."id" < 2)
187
+ }
188
+ end
189
+ end
190
+
191
+ describe '#lt_all' do
192
+ it 'should create a Grouping node' do
193
+ relation = Table.new(:users)
194
+ relation[:id].lt_all([1,2]).must_be_kind_of Nodes::Grouping
195
+ end
196
+
197
+ it 'should generate ANDs in sql' do
198
+ relation = Table.new(:users)
199
+ mgr = relation.project relation[:id]
200
+ mgr.where relation[:id].lt_all([1,2])
201
+ mgr.to_sql.must_be_like %{
202
+ SELECT "users"."id" FROM "users" WHERE ("users"."id" < 1 AND "users"."id" < 2)
203
+ }
204
+ end
205
+ end
206
+
207
+ describe '#lteq' do
208
+ it 'should create a LessThanOrEqual node' do
209
+ relation = Table.new(:users)
210
+ relation[:id].lteq(10).must_be_kind_of Nodes::LessThanOrEqual
211
+ end
212
+
213
+ it 'should generate <= in sql' do
214
+ relation = Table.new(:users)
215
+ mgr = relation.project relation[:id]
216
+ mgr.where relation[:id].lteq(10)
217
+ mgr.to_sql.must_be_like %{
218
+ SELECT "users"."id" FROM "users" WHERE "users"."id" <= 10
219
+ }
220
+ end
221
+ end
222
+
223
+ describe '#lteq_any' do
224
+ it 'should create a Grouping node' do
225
+ relation = Table.new(:users)
226
+ relation[:id].lteq_any([1,2]).must_be_kind_of Nodes::Grouping
227
+ end
228
+
229
+ it 'should generate ORs in sql' do
230
+ relation = Table.new(:users)
231
+ mgr = relation.project relation[:id]
232
+ mgr.where relation[:id].lteq_any([1,2])
233
+ mgr.to_sql.must_be_like %{
234
+ SELECT "users"."id" FROM "users" WHERE ("users"."id" <= 1 OR "users"."id" <= 2)
235
+ }
236
+ end
237
+ end
238
+
239
+ describe '#lteq_all' do
240
+ it 'should create a Grouping node' do
241
+ relation = Table.new(:users)
242
+ relation[:id].lteq_all([1,2]).must_be_kind_of Nodes::Grouping
243
+ end
244
+
245
+ it 'should generate ANDs in sql' do
246
+ relation = Table.new(:users)
247
+ mgr = relation.project relation[:id]
248
+ mgr.where relation[:id].lteq_all([1,2])
249
+ mgr.to_sql.must_be_like %{
250
+ SELECT "users"."id" FROM "users" WHERE ("users"."id" <= 1 AND "users"."id" <= 2)
251
+ }
252
+ end
253
+ end
254
+
255
+ describe '#average' do
256
+ it 'should create a AVG node' do
257
+ relation = Table.new(:users)
258
+ relation[:id].average.must_be_kind_of Nodes::Avg
259
+ end
260
+
261
+ # FIXME: backwards compat. Is this really necessary?
262
+ it 'should set the alias to "avg_id"' do
263
+ relation = Table.new(:users)
264
+ mgr = relation.project relation[:id].average
265
+ mgr.to_sql.must_be_like %{
266
+ SELECT AVG("users"."id") AS avg_id
267
+ FROM "users"
268
+ }
269
+ end
270
+ end
271
+
272
+ describe '#maximum' do
273
+ it 'should create a MAX node' do
274
+ relation = Table.new(:users)
275
+ relation[:id].maximum.must_be_kind_of Nodes::Max
276
+ end
277
+
278
+ # FIXME: backwards compat. Is this really necessary?
279
+ it 'should set the alias to "max_id"' do
280
+ relation = Table.new(:users)
281
+ mgr = relation.project relation[:id].maximum
282
+ mgr.to_sql.must_be_like %{
283
+ SELECT MAX("users"."id") AS max_id
284
+ FROM "users"
285
+ }
286
+ end
287
+ end
288
+
289
+ describe '#minimum' do
290
+ it 'should create a Min node' do
291
+ relation = Table.new(:users)
292
+ relation[:id].minimum.must_be_kind_of Nodes::Min
293
+ end
294
+ end
295
+
296
+ describe '#sum' do
297
+ it 'should create a SUM node' do
298
+ relation = Table.new(:users)
299
+ relation[:id].sum.must_be_kind_of Nodes::Sum
300
+ end
301
+
302
+ # FIXME: backwards compat. Is this really necessary?
303
+ it 'should set the alias to "sum_id"' do
304
+ relation = Table.new(:users)
305
+ mgr = relation.project relation[:id].sum
306
+ mgr.to_sql.must_be_like %{
307
+ SELECT SUM("users"."id") AS sum_id
308
+ FROM "users"
309
+ }
310
+ end
311
+ end
312
+
313
+ describe '#count' do
314
+ it 'should return a count node' do
315
+ relation = Table.new(:users)
316
+ relation[:id].count.must_be_kind_of Nodes::Count
317
+ end
318
+
319
+ it 'should take a distinct param' do
320
+ relation = Table.new(:users)
321
+ count = relation[:id].count(nil)
322
+ count.must_be_kind_of Nodes::Count
323
+ count.distinct.must_be_nil
324
+ end
325
+ end
326
+
327
+ describe '#eq' do
328
+ it 'should return an equality node' do
329
+ attribute = Attribute.new nil, nil, nil
330
+ equality = attribute.eq 1
331
+ equality.left.must_equal attribute
332
+ equality.right.must_equal 1
333
+ equality.must_be_kind_of Nodes::Equality
334
+ end
335
+
336
+ it 'should generate = in sql' do
337
+ relation = Table.new(:users)
338
+ mgr = relation.project relation[:id]
339
+ mgr.where relation[:id].eq(10)
340
+ mgr.to_sql.must_be_like %{
341
+ SELECT "users"."id" FROM "users" WHERE "users"."id" = 10
342
+ }
343
+ end
344
+
345
+ it 'should handle nil' do
346
+ relation = Table.new(:users)
347
+ mgr = relation.project relation[:id]
348
+ mgr.where relation[:id].eq(nil)
349
+ mgr.to_sql.must_be_like %{
350
+ SELECT "users"."id" FROM "users" WHERE "users"."id" IS NULL
351
+ }
352
+ end
353
+ end
354
+
355
+ describe '#eq_any' do
356
+ it 'should create a Grouping node' do
357
+ relation = Table.new(:users)
358
+ relation[:id].eq_any([1,2]).must_be_kind_of Nodes::Grouping
359
+ end
360
+
361
+ it 'should generate ORs in sql' do
362
+ relation = Table.new(:users)
363
+ mgr = relation.project relation[:id]
364
+ mgr.where relation[:id].eq_any([1,2])
365
+ mgr.to_sql.must_be_like %{
366
+ SELECT "users"."id" FROM "users" WHERE ("users"."id" = 1 OR "users"."id" = 2)
367
+ }
368
+ end
369
+
370
+ it 'should not eat input' do
371
+ relation = Table.new(:users)
372
+ mgr = relation.project relation[:id]
373
+ values = [1,2]
374
+ mgr.where relation[:id].eq_any(values)
375
+ values.must_equal [1,2]
376
+ end
377
+ end
378
+
379
+ describe '#eq_all' do
380
+ it 'should create a Grouping node' do
381
+ relation = Table.new(:users)
382
+ relation[:id].eq_all([1,2]).must_be_kind_of Nodes::Grouping
383
+ end
384
+
385
+ it 'should generate ANDs in sql' do
386
+ relation = Table.new(:users)
387
+ mgr = relation.project relation[:id]
388
+ mgr.where relation[:id].eq_all([1,2])
389
+ mgr.to_sql.must_be_like %{
390
+ SELECT "users"."id" FROM "users" WHERE ("users"."id" = 1 AND "users"."id" = 2)
391
+ }
392
+ end
393
+
394
+ it 'should not eat input' do
395
+ relation = Table.new(:users)
396
+ mgr = relation.project relation[:id]
397
+ values = [1,2]
398
+ mgr.where relation[:id].eq_all(values)
399
+ values.must_equal [1,2]
400
+ end
401
+ end
402
+
403
+ describe '#matches' do
404
+ it 'should create a Matches node' do
405
+ relation = Table.new(:users)
406
+ relation[:name].matches('%bacon%').must_be_kind_of Nodes::Matches
407
+ end
408
+
409
+ it 'should generate LIKE in sql' do
410
+ relation = Table.new(:users)
411
+ mgr = relation.project relation[:id]
412
+ mgr.where relation[:name].matches('%bacon%')
413
+ mgr.to_sql.must_be_like %{
414
+ SELECT "users"."id" FROM "users" WHERE "users"."name" LIKE '%bacon%'
415
+ }
416
+ end
417
+ end
418
+
419
+ describe '#matches_any' do
420
+ it 'should create a Grouping node' do
421
+ relation = Table.new(:users)
422
+ relation[:name].matches_any(['%chunky%','%bacon%']).must_be_kind_of Nodes::Grouping
423
+ end
424
+
425
+ it 'should generate ORs in sql' do
426
+ relation = Table.new(:users)
427
+ mgr = relation.project relation[:id]
428
+ mgr.where relation[:name].matches_any(['%chunky%','%bacon%'])
429
+ mgr.to_sql.must_be_like %{
430
+ SELECT "users"."id" FROM "users" WHERE ("users"."name" LIKE '%chunky%' OR "users"."name" LIKE '%bacon%')
431
+ }
432
+ end
433
+ end
434
+
435
+ describe '#matches_all' do
436
+ it 'should create a Grouping node' do
437
+ relation = Table.new(:users)
438
+ relation[:name].matches_all(['%chunky%','%bacon%']).must_be_kind_of Nodes::Grouping
439
+ end
440
+
441
+ it 'should generate ANDs in sql' do
442
+ relation = Table.new(:users)
443
+ mgr = relation.project relation[:id]
444
+ mgr.where relation[:name].matches_all(['%chunky%','%bacon%'])
445
+ mgr.to_sql.must_be_like %{
446
+ SELECT "users"."id" FROM "users" WHERE ("users"."name" LIKE '%chunky%' AND "users"."name" LIKE '%bacon%')
447
+ }
448
+ end
449
+ end
450
+
451
+ describe '#does_not_match' do
452
+ it 'should create a DoesNotMatch node' do
453
+ relation = Table.new(:users)
454
+ relation[:name].does_not_match('%bacon%').must_be_kind_of Nodes::DoesNotMatch
455
+ end
456
+
457
+ it 'should generate NOT LIKE in sql' do
458
+ relation = Table.new(:users)
459
+ mgr = relation.project relation[:id]
460
+ mgr.where relation[:name].does_not_match('%bacon%')
461
+ mgr.to_sql.must_be_like %{
462
+ SELECT "users"."id" FROM "users" WHERE "users"."name" NOT LIKE '%bacon%'
463
+ }
464
+ end
465
+ end
466
+
467
+ describe '#does_not_match_any' do
468
+ it 'should create a Grouping node' do
469
+ relation = Table.new(:users)
470
+ relation[:name].does_not_match_any(['%chunky%','%bacon%']).must_be_kind_of Nodes::Grouping
471
+ end
472
+
473
+ it 'should generate ORs in sql' do
474
+ relation = Table.new(:users)
475
+ mgr = relation.project relation[:id]
476
+ mgr.where relation[:name].does_not_match_any(['%chunky%','%bacon%'])
477
+ mgr.to_sql.must_be_like %{
478
+ SELECT "users"."id" FROM "users" WHERE ("users"."name" NOT LIKE '%chunky%' OR "users"."name" NOT LIKE '%bacon%')
479
+ }
480
+ end
481
+ end
482
+
483
+ describe '#does_not_match_all' do
484
+ it 'should create a Grouping node' do
485
+ relation = Table.new(:users)
486
+ relation[:name].does_not_match_all(['%chunky%','%bacon%']).must_be_kind_of Nodes::Grouping
487
+ end
488
+
489
+ it 'should generate ANDs in sql' do
490
+ relation = Table.new(:users)
491
+ mgr = relation.project relation[:id]
492
+ mgr.where relation[:name].does_not_match_all(['%chunky%','%bacon%'])
493
+ mgr.to_sql.must_be_like %{
494
+ SELECT "users"."id" FROM "users" WHERE ("users"."name" NOT LIKE '%chunky%' AND "users"."name" NOT LIKE '%bacon%')
495
+ }
496
+ end
497
+ end
498
+
499
+ describe '#in' do
500
+ it 'can be constructed with a list' do
501
+ end
502
+
503
+ it 'should return an in node' do
504
+ attribute = Attribute.new nil, nil, nil
505
+ node = Nodes::In.new attribute, [1,2,3]
506
+ node.left.must_equal attribute
507
+ node.right.must_equal [1, 2, 3]
508
+ end
509
+
510
+ it 'should generate IN in sql' do
511
+ relation = Table.new(:users)
512
+ mgr = relation.project relation[:id]
513
+ mgr.where relation[:id].in([1,2,3])
514
+ mgr.to_sql.must_be_like %{
515
+ SELECT "users"."id" FROM "users" WHERE "users"."id" IN (1, 2, 3)
516
+ }
517
+ end
518
+ end
519
+
520
+ describe '#in_any' do
521
+ it 'should create a Grouping node' do
522
+ relation = Table.new(:users)
523
+ relation[:id].in_any([1,2]).must_be_kind_of Nodes::Grouping
524
+ end
525
+
526
+ it 'should generate ORs in sql' do
527
+ relation = Table.new(:users)
528
+ mgr = relation.project relation[:id]
529
+ mgr.where relation[:id].in_any([[1,2], [3,4]])
530
+ mgr.to_sql.must_be_like %{
531
+ SELECT "users"."id" FROM "users" WHERE ("users"."id" IN (1, 2) OR "users"."id" IN (3, 4))
532
+ }
533
+ end
534
+ end
535
+
536
+ describe '#in_all' do
537
+ it 'should create a Grouping node' do
538
+ relation = Table.new(:users)
539
+ relation[:id].in_all([1,2]).must_be_kind_of Nodes::Grouping
540
+ end
541
+
542
+ it 'should generate ANDs in sql' do
543
+ relation = Table.new(:users)
544
+ mgr = relation.project relation[:id]
545
+ mgr.where relation[:id].in_all([[1,2], [3,4]])
546
+ mgr.to_sql.must_be_like %{
547
+ SELECT "users"."id" FROM "users" WHERE ("users"."id" IN (1, 2) AND "users"."id" IN (3, 4))
548
+ }
549
+ end
550
+ end
551
+
552
+ describe '#not_in' do
553
+ it 'can be constructed with a list' do
554
+ end
555
+
556
+ it 'should return a NotIn node' do
557
+ attribute = Attribute.new nil, nil, nil
558
+ node = Nodes::NotIn.new attribute, [1,2,3]
559
+ node.left.must_equal attribute
560
+ node.right.must_equal [1, 2, 3]
561
+ end
562
+
563
+ it 'should generate NOT IN in sql' do
564
+ relation = Table.new(:users)
565
+ mgr = relation.project relation[:id]
566
+ mgr.where relation[:id].not_in([1,2,3])
567
+ mgr.to_sql.must_be_like %{
568
+ SELECT "users"."id" FROM "users" WHERE "users"."id" NOT IN (1, 2, 3)
569
+ }
570
+ end
571
+ end
572
+
573
+ describe '#not_in_any' do
574
+ it 'should create a Grouping node' do
575
+ relation = Table.new(:users)
576
+ relation[:id].not_in_any([1,2]).must_be_kind_of Nodes::Grouping
577
+ end
578
+
579
+ it 'should generate ORs in sql' do
580
+ relation = Table.new(:users)
581
+ mgr = relation.project relation[:id]
582
+ mgr.where relation[:id].not_in_any([[1,2], [3,4]])
583
+ mgr.to_sql.must_be_like %{
584
+ SELECT "users"."id" FROM "users" WHERE ("users"."id" NOT IN (1, 2) OR "users"."id" NOT IN (3, 4))
585
+ }
586
+ end
587
+ end
588
+
589
+ describe '#not_in_all' do
590
+ it 'should create a Grouping node' do
591
+ relation = Table.new(:users)
592
+ relation[:id].not_in_all([1,2]).must_be_kind_of Nodes::Grouping
593
+ end
594
+
595
+ it 'should generate ANDs in sql' do
596
+ relation = Table.new(:users)
597
+ mgr = relation.project relation[:id]
598
+ mgr.where relation[:id].not_in_all([[1,2], [3,4]])
599
+ mgr.to_sql.must_be_like %{
600
+ SELECT "users"."id" FROM "users" WHERE ("users"."id" NOT IN (1, 2) AND "users"."id" NOT IN (3, 4))
601
+ }
602
+ end
603
+ end
604
+
605
+ describe '#eq_all' do
606
+ it 'should create a Grouping node' do
607
+ relation = Table.new(:users)
608
+ relation[:id].eq_all([1,2]).must_be_kind_of Nodes::Grouping
609
+ end
610
+
611
+ it 'should generate ANDs in sql' do
612
+ relation = Table.new(:users)
613
+ mgr = relation.project relation[:id]
614
+ mgr.where relation[:id].eq_all([1,2])
615
+ mgr.to_sql.must_be_like %{
616
+ SELECT "users"."id" FROM "users" WHERE ("users"."id" = 1 AND "users"."id" = 2)
617
+ }
618
+ end
619
+ end
620
+
621
+ describe '#asc' do
622
+ it 'should create an Ordering node' do
623
+ relation = Table.new(:users)
624
+ relation[:id].asc.must_be_kind_of Nodes::Ordering
625
+ end
626
+
627
+ it 'should generate ASC in sql' do
628
+ relation = Table.new(:users)
629
+ mgr = relation.project relation[:id]
630
+ mgr.order relation[:id].asc
631
+ mgr.to_sql.must_be_like %{
632
+ SELECT "users"."id" FROM "users" ORDER BY "users"."id" ASC
633
+ }
634
+ end
635
+ end
636
+
637
+ describe '#desc' do
638
+ it 'should create an Ordering node' do
639
+ relation = Table.new(:users)
640
+ relation[:id].desc.must_be_kind_of Nodes::Ordering
641
+ end
642
+
643
+ it 'should generate DESC in sql' do
644
+ relation = Table.new(:users)
645
+ mgr = relation.project relation[:id]
646
+ mgr.order relation[:id].desc
647
+ mgr.to_sql.must_be_like %{
648
+ SELECT "users"."id" FROM "users" ORDER BY "users"."id" DESC
649
+ }
650
+ end
651
+ end
652
+ end
653
+
654
+ describe 'equality' do
655
+ describe '#to_sql' do
656
+ it 'should produce sql' do
657
+ table = Table.new :users
658
+ condition = table['id'].eq 1
659
+ condition.to_sql.must_equal '"users"."id" = 1'
660
+ end
661
+ end
662
+ end
663
+ end
664
+ end