arel 2.0.4 → 2.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +18 -0
- data/Manifest.txt +8 -0
- data/Rakefile +1 -0
- data/arel.gemspec +2 -2
- data/lib/arel.rb +4 -1
- data/lib/arel/nodes.rb +3 -0
- data/lib/arel/nodes/as.rb +6 -0
- data/lib/arel/nodes/delete_statement.rb +8 -6
- data/lib/arel/nodes/group.rb +1 -6
- data/lib/arel/nodes/grouping.rb +1 -6
- data/lib/arel/nodes/having.rb +1 -6
- data/lib/arel/nodes/insert_statement.rb +1 -1
- data/lib/arel/nodes/join.rb +1 -1
- data/lib/arel/nodes/lock.rb +1 -1
- data/lib/arel/nodes/node.rb +16 -0
- data/lib/arel/nodes/not.rb +6 -0
- data/lib/arel/nodes/offset.rb +2 -6
- data/lib/arel/nodes/on.rb +1 -6
- data/lib/arel/nodes/ordering.rb +5 -4
- data/lib/arel/nodes/select_core.rb +1 -1
- data/lib/arel/nodes/select_statement.rb +1 -1
- data/lib/arel/nodes/table_alias.rb +4 -12
- data/lib/arel/nodes/unary.rb +11 -0
- data/lib/arel/nodes/unqualified_column.rb +5 -8
- data/lib/arel/nodes/update_statement.rb +1 -1
- data/lib/arel/nodes/values.rb +6 -4
- data/lib/arel/predications.rb +5 -1
- data/lib/arel/table.rb +2 -2
- data/lib/arel/visitors.rb +1 -0
- data/lib/arel/visitors/depth_first.rb +152 -0
- data/lib/arel/visitors/mysql.rb +4 -0
- data/lib/arel/visitors/to_sql.rb +9 -1
- data/lib/arel/visitors/visitor.rb +8 -1
- data/test/nodes/test_as.rb +16 -0
- data/test/nodes/test_node.rb +33 -0
- data/test/nodes/test_not.rb +20 -0
- data/test/visitors/test_depth_first.rb +203 -0
- data/test/visitors/test_mysql.rb +7 -0
- data/test/visitors/test_to_sql.rb +16 -0
- metadata +25 -6
data/History.txt
CHANGED
@@ -1,3 +1,21 @@
|
|
1
|
+
== 2.0.5 11/30/2010
|
2
|
+
|
3
|
+
* Enhancements
|
4
|
+
|
5
|
+
* Arel::Visitors::DepthFirst can walk your AST depth first
|
6
|
+
* Arel::Nodes::Node is enumerable, depth first
|
7
|
+
|
8
|
+
* Bug fixes
|
9
|
+
|
10
|
+
* #lock will lock SELECT statements "FOR UPDATE" on mysql
|
11
|
+
* Nodes::Node#not factory method added for creating Nodes::Not nodes
|
12
|
+
* Added an As node
|
13
|
+
|
14
|
+
* Deprecations
|
15
|
+
|
16
|
+
* Support for Subclasses of core classes will be removed in ARel version
|
17
|
+
2.2.0
|
18
|
+
|
1
19
|
== 2.0.4
|
2
20
|
|
3
21
|
* Bug fixes
|
data/Manifest.txt
CHANGED
@@ -17,6 +17,7 @@ lib/arel/expressions.rb
|
|
17
17
|
lib/arel/insert_manager.rb
|
18
18
|
lib/arel/nodes.rb
|
19
19
|
lib/arel/nodes/and.rb
|
20
|
+
lib/arel/nodes/as.rb
|
20
21
|
lib/arel/nodes/assignment.rb
|
21
22
|
lib/arel/nodes/avg.rb
|
22
23
|
lib/arel/nodes/between.rb
|
@@ -43,6 +44,7 @@ lib/arel/nodes/matches.rb
|
|
43
44
|
lib/arel/nodes/max.rb
|
44
45
|
lib/arel/nodes/min.rb
|
45
46
|
lib/arel/nodes/node.rb
|
47
|
+
lib/arel/nodes/not.rb
|
46
48
|
lib/arel/nodes/not_equal.rb
|
47
49
|
lib/arel/nodes/not_in.rb
|
48
50
|
lib/arel/nodes/offset.rb
|
@@ -56,6 +58,7 @@ lib/arel/nodes/sql_literal.rb
|
|
56
58
|
lib/arel/nodes/string_join.rb
|
57
59
|
lib/arel/nodes/sum.rb
|
58
60
|
lib/arel/nodes/table_alias.rb
|
61
|
+
lib/arel/nodes/unary.rb
|
59
62
|
lib/arel/nodes/unqualified_column.rb
|
60
63
|
lib/arel/nodes/update_statement.rb
|
61
64
|
lib/arel/nodes/values.rb
|
@@ -68,6 +71,7 @@ lib/arel/table.rb
|
|
68
71
|
lib/arel/tree_manager.rb
|
69
72
|
lib/arel/update_manager.rb
|
70
73
|
lib/arel/visitors.rb
|
74
|
+
lib/arel/visitors/depth_first.rb
|
71
75
|
lib/arel/visitors/dot.rb
|
72
76
|
lib/arel/visitors/join_sql.rb
|
73
77
|
lib/arel/visitors/mysql.rb
|
@@ -80,10 +84,13 @@ lib/arel/visitors/visitor.rb
|
|
80
84
|
lib/arel/visitors/where_sql.rb
|
81
85
|
test/attributes/test_attribute.rb
|
82
86
|
test/helper.rb
|
87
|
+
test/nodes/test_as.rb
|
83
88
|
test/nodes/test_count.rb
|
84
89
|
test/nodes/test_delete_statement.rb
|
85
90
|
test/nodes/test_equality.rb
|
86
91
|
test/nodes/test_insert_statement.rb
|
92
|
+
test/nodes/test_node.rb
|
93
|
+
test/nodes/test_not.rb
|
87
94
|
test/nodes/test_or.rb
|
88
95
|
test/nodes/test_select_core.rb
|
89
96
|
test/nodes/test_select_statement.rb
|
@@ -99,6 +106,7 @@ test/test_insert_manager.rb
|
|
99
106
|
test/test_select_manager.rb
|
100
107
|
test/test_table.rb
|
101
108
|
test/test_update_manager.rb
|
109
|
+
test/visitors/test_depth_first.rb
|
102
110
|
test/visitors/test_join_sql.rb
|
103
111
|
test/visitors/test_mysql.rb
|
104
112
|
test/visitors/test_oracle.rb
|
data/Rakefile
CHANGED
data/arel.gemspec
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{arel}
|
5
|
-
s.version = "2.0.
|
5
|
+
s.version = "2.0.4.20101119081136"
|
6
6
|
|
7
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-11-
|
9
|
+
s.date = %q{2010-11-19}
|
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
12
|
s.extra_rdoc_files = ["History.txt", "MIT-LICENSE.txt", "Manifest.txt", "README.markdown"]
|
data/lib/arel.rb
CHANGED
@@ -21,6 +21,7 @@ require 'arel/update_manager'
|
|
21
21
|
require 'arel/delete_manager'
|
22
22
|
require 'arel/nodes'
|
23
23
|
|
24
|
+
|
24
25
|
#### these are deprecated
|
25
26
|
require 'arel/deprecated'
|
26
27
|
require 'arel/sql/engine'
|
@@ -28,9 +29,11 @@ require 'arel/sql_literal'
|
|
28
29
|
####
|
29
30
|
|
30
31
|
module Arel
|
31
|
-
VERSION = '2.0.
|
32
|
+
VERSION = '2.0.5'
|
32
33
|
|
33
34
|
def self.sql raw_sql
|
34
35
|
Arel::Nodes::SqlLiteral.new raw_sql
|
35
36
|
end
|
37
|
+
## Convenience Alias
|
38
|
+
Node = Arel::Nodes::Node
|
36
39
|
end
|
data/lib/arel/nodes.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'arel/nodes/node'
|
2
|
+
require 'arel/nodes/unary'
|
2
3
|
require 'arel/nodes/binary'
|
3
4
|
require 'arel/nodes/equality'
|
4
5
|
require 'arel/nodes/between'
|
@@ -6,6 +7,8 @@ require 'arel/nodes/not_equal'
|
|
6
7
|
require 'arel/nodes/assignment'
|
7
8
|
require 'arel/nodes/or'
|
8
9
|
require 'arel/nodes/and'
|
10
|
+
require 'arel/nodes/as'
|
11
|
+
require 'arel/nodes/not'
|
9
12
|
require 'arel/nodes/greater_than'
|
10
13
|
require 'arel/nodes/greater_than_or_equal'
|
11
14
|
require 'arel/nodes/less_than'
|
@@ -1,16 +1,18 @@
|
|
1
1
|
module Arel
|
2
2
|
module Nodes
|
3
|
-
class DeleteStatement
|
4
|
-
|
3
|
+
class DeleteStatement < Arel::Nodes::Binary
|
4
|
+
alias :relation :left
|
5
|
+
alias :relation= :left=
|
6
|
+
alias :wheres :right
|
7
|
+
alias :wheres= :right=
|
5
8
|
|
6
|
-
def initialize
|
7
|
-
|
8
|
-
@wheres = []
|
9
|
+
def initialize relation = nil, wheres = []
|
10
|
+
super
|
9
11
|
end
|
10
12
|
|
11
13
|
def initialize_copy other
|
12
14
|
super
|
13
|
-
@
|
15
|
+
@right = @right.clone
|
14
16
|
end
|
15
17
|
end
|
16
18
|
end
|
data/lib/arel/nodes/group.rb
CHANGED
data/lib/arel/nodes/grouping.rb
CHANGED
data/lib/arel/nodes/having.rb
CHANGED
data/lib/arel/nodes/join.rb
CHANGED
data/lib/arel/nodes/lock.rb
CHANGED
data/lib/arel/nodes/node.rb
CHANGED
@@ -3,6 +3,15 @@ module Arel
|
|
3
3
|
###
|
4
4
|
# Abstract base class for all AST nodes
|
5
5
|
class Node
|
6
|
+
include Enumerable
|
7
|
+
|
8
|
+
###
|
9
|
+
# Factory method to create a Nodes::Not node that has the recipient of
|
10
|
+
# the caller as a child.
|
11
|
+
def not
|
12
|
+
Nodes::Not.new self
|
13
|
+
end
|
14
|
+
|
6
15
|
###
|
7
16
|
# Factory method to create a Nodes::Grouping node that has an Nodes::Or
|
8
17
|
# node as a child.
|
@@ -25,6 +34,13 @@ module Arel
|
|
25
34
|
viz = Visitors.for engine
|
26
35
|
viz.accept self
|
27
36
|
end
|
37
|
+
|
38
|
+
# Iterate through AST, nodes will be yielded depth-first
|
39
|
+
def each &block
|
40
|
+
return enum_for(:each) unless block_given?
|
41
|
+
|
42
|
+
Visitors::DepthFirst.new(block).accept self
|
43
|
+
end
|
28
44
|
end
|
29
45
|
end
|
30
46
|
end
|
data/lib/arel/nodes/offset.rb
CHANGED
data/lib/arel/nodes/on.rb
CHANGED
data/lib/arel/nodes/ordering.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
module Arel
|
2
2
|
module Nodes
|
3
|
-
class Ordering < Arel::Nodes::
|
4
|
-
|
3
|
+
class Ordering < Arel::Nodes::Binary
|
4
|
+
alias :expr :left
|
5
|
+
alias :direction :right
|
5
6
|
|
6
|
-
def initialize
|
7
|
-
|
7
|
+
def initialize expr, direction = :asc
|
8
|
+
super
|
8
9
|
end
|
9
10
|
|
10
11
|
def ascending?
|
@@ -1,20 +1,12 @@
|
|
1
1
|
module Arel
|
2
2
|
module Nodes
|
3
|
-
class TableAlias
|
4
|
-
|
3
|
+
class TableAlias < Arel::Nodes::Binary
|
4
|
+
alias :name :left
|
5
|
+
alias :relation :right
|
5
6
|
alias :table_alias :name
|
6
7
|
|
7
|
-
def initialize name, relation
|
8
|
-
@name = name
|
9
|
-
@relation = relation
|
10
|
-
@columns = relation.columns.map { |column|
|
11
|
-
column.dup.tap { |col| col.relation = self }
|
12
|
-
}
|
13
|
-
end
|
14
|
-
|
15
8
|
def [] name
|
16
|
-
|
17
|
-
columns.find { |column| column.name == name }
|
9
|
+
Attribute.new self, name
|
18
10
|
end
|
19
11
|
end
|
20
12
|
end
|
@@ -1,18 +1,15 @@
|
|
1
1
|
module Arel
|
2
2
|
module Nodes
|
3
|
-
class UnqualifiedColumn
|
4
|
-
|
5
|
-
|
6
|
-
def initialize attribute
|
7
|
-
@attribute = attribute
|
8
|
-
end
|
3
|
+
class UnqualifiedColumn < Arel::Nodes::Unary
|
4
|
+
alias :attribute :expr
|
5
|
+
alias :attribute= :expr=
|
9
6
|
|
10
7
|
def column
|
11
|
-
@
|
8
|
+
@expr.column
|
12
9
|
end
|
13
10
|
|
14
11
|
def name
|
15
|
-
@
|
12
|
+
@expr.name
|
16
13
|
end
|
17
14
|
end
|
18
15
|
end
|
data/lib/arel/nodes/values.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
module Arel
|
2
2
|
module Nodes
|
3
|
-
class Values
|
4
|
-
|
3
|
+
class Values < Arel::Nodes::Binary
|
4
|
+
alias :expressions :left
|
5
|
+
alias :expressions= :left=
|
6
|
+
alias :columns :right
|
7
|
+
alias :columns= :right=
|
5
8
|
|
6
9
|
def initialize exprs, columns = []
|
7
|
-
|
8
|
-
@columns = columns
|
10
|
+
super
|
9
11
|
end
|
10
12
|
end
|
11
13
|
end
|
data/lib/arel/predications.rb
CHANGED
data/lib/arel/table.rb
CHANGED
data/lib/arel/visitors.rb
CHANGED
@@ -0,0 +1,152 @@
|
|
1
|
+
module Arel
|
2
|
+
module Visitors
|
3
|
+
class DepthFirst < Arel::Visitors::Visitor
|
4
|
+
def initialize block = nil
|
5
|
+
@block = block || Proc.new
|
6
|
+
end
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def visit o
|
11
|
+
super
|
12
|
+
@block.call o
|
13
|
+
end
|
14
|
+
|
15
|
+
def unary o
|
16
|
+
visit o.expr
|
17
|
+
end
|
18
|
+
alias :visit_Arel_Nodes_Group :unary
|
19
|
+
alias :visit_Arel_Nodes_Grouping :unary
|
20
|
+
alias :visit_Arel_Nodes_Having :unary
|
21
|
+
alias :visit_Arel_Nodes_Not :unary
|
22
|
+
alias :visit_Arel_Nodes_Offset :unary
|
23
|
+
alias :visit_Arel_Nodes_On :unary
|
24
|
+
alias :visit_Arel_Nodes_UnqualifiedColumn :unary
|
25
|
+
|
26
|
+
def function o
|
27
|
+
visit o.expressions
|
28
|
+
visit o.alias
|
29
|
+
end
|
30
|
+
alias :visit_Arel_Nodes_Avg :function
|
31
|
+
alias :visit_Arel_Nodes_Exists :function
|
32
|
+
alias :visit_Arel_Nodes_Max :function
|
33
|
+
alias :visit_Arel_Nodes_Min :function
|
34
|
+
alias :visit_Arel_Nodes_Sum :function
|
35
|
+
|
36
|
+
def visit_Arel_Nodes_Count o
|
37
|
+
visit o.expressions
|
38
|
+
visit o.alias
|
39
|
+
visit o.distinct
|
40
|
+
end
|
41
|
+
|
42
|
+
def join o
|
43
|
+
visit o.left
|
44
|
+
visit o.right
|
45
|
+
visit o.constraint
|
46
|
+
end
|
47
|
+
alias :visit_Arel_Nodes_InnerJoin :join
|
48
|
+
alias :visit_Arel_Nodes_OuterJoin :join
|
49
|
+
|
50
|
+
def binary o
|
51
|
+
visit o.left
|
52
|
+
visit o.right
|
53
|
+
end
|
54
|
+
alias :visit_Arel_Nodes_And :binary
|
55
|
+
alias :visit_Arel_Nodes_As :binary
|
56
|
+
alias :visit_Arel_Nodes_Assignment :binary
|
57
|
+
alias :visit_Arel_Nodes_Between :binary
|
58
|
+
alias :visit_Arel_Nodes_DeleteStatement :binary
|
59
|
+
alias :visit_Arel_Nodes_DoesNotMatch :binary
|
60
|
+
alias :visit_Arel_Nodes_Equality :binary
|
61
|
+
alias :visit_Arel_Nodes_GreaterThan :binary
|
62
|
+
alias :visit_Arel_Nodes_GreaterThanOrEqual :binary
|
63
|
+
alias :visit_Arel_Nodes_In :binary
|
64
|
+
alias :visit_Arel_Nodes_LessThan :binary
|
65
|
+
alias :visit_Arel_Nodes_LessThanOrEqual :binary
|
66
|
+
alias :visit_Arel_Nodes_Matches :binary
|
67
|
+
alias :visit_Arel_Nodes_NotEqual :binary
|
68
|
+
alias :visit_Arel_Nodes_NotIn :binary
|
69
|
+
alias :visit_Arel_Nodes_Or :binary
|
70
|
+
alias :visit_Arel_Nodes_Ordering :binary
|
71
|
+
alias :visit_Arel_Nodes_StringJoin :binary
|
72
|
+
alias :visit_Arel_Nodes_TableAlias :binary
|
73
|
+
alias :visit_Arel_Nodes_Values :binary
|
74
|
+
|
75
|
+
def visit_Arel_Attribute o
|
76
|
+
visit o.relation
|
77
|
+
visit o.name
|
78
|
+
end
|
79
|
+
alias :visit_Arel_Attributes_Integer :visit_Arel_Attribute
|
80
|
+
alias :visit_Arel_Attributes_Float :visit_Arel_Attribute
|
81
|
+
alias :visit_Arel_Attributes_String :visit_Arel_Attribute
|
82
|
+
alias :visit_Arel_Attributes_Time :visit_Arel_Attribute
|
83
|
+
alias :visit_Arel_Attributes_Boolean :visit_Arel_Attribute
|
84
|
+
alias :visit_Arel_Attributes_Attribute :visit_Arel_Attribute
|
85
|
+
alias :visit_Arel_Attributes_Decimal :visit_Arel_Attribute
|
86
|
+
|
87
|
+
def visit_Arel_Table o
|
88
|
+
visit o.name
|
89
|
+
end
|
90
|
+
|
91
|
+
def terminal o
|
92
|
+
end
|
93
|
+
alias :visit_ActiveSupport_Multibyte_Chars :terminal
|
94
|
+
alias :visit_ActiveSupport_StringInquirer :terminal
|
95
|
+
alias :visit_Arel_Nodes_Lock :terminal
|
96
|
+
alias :visit_Arel_Nodes_Node :terminal
|
97
|
+
alias :visit_Arel_Nodes_SqlLiteral :terminal
|
98
|
+
alias :visit_Arel_SqlLiteral :terminal
|
99
|
+
alias :visit_BigDecimal :terminal
|
100
|
+
alias :visit_Bignum :terminal
|
101
|
+
alias :visit_Class :terminal
|
102
|
+
alias :visit_Date :terminal
|
103
|
+
alias :visit_DateTime :terminal
|
104
|
+
alias :visit_FalseClass :terminal
|
105
|
+
alias :visit_Fixnum :terminal
|
106
|
+
alias :visit_Float :terminal
|
107
|
+
alias :visit_NilClass :terminal
|
108
|
+
alias :visit_String :terminal
|
109
|
+
alias :visit_Symbol :terminal
|
110
|
+
alias :visit_Time :terminal
|
111
|
+
alias :visit_TrueClass :terminal
|
112
|
+
|
113
|
+
def visit_Arel_Nodes_InsertStatement o
|
114
|
+
visit o.relation
|
115
|
+
visit o.columns
|
116
|
+
visit o.values
|
117
|
+
end
|
118
|
+
|
119
|
+
def visit_Arel_Nodes_SelectCore o
|
120
|
+
visit o.projections
|
121
|
+
visit o.froms
|
122
|
+
visit o.wheres
|
123
|
+
visit o.groups
|
124
|
+
visit o.having
|
125
|
+
end
|
126
|
+
|
127
|
+
def visit_Arel_Nodes_SelectStatement o
|
128
|
+
visit o.cores
|
129
|
+
visit o.orders
|
130
|
+
visit o.limit
|
131
|
+
visit o.lock
|
132
|
+
visit o.offset
|
133
|
+
end
|
134
|
+
|
135
|
+
def visit_Arel_Nodes_UpdateStatement o
|
136
|
+
visit o.relation
|
137
|
+
visit o.values
|
138
|
+
visit o.wheres
|
139
|
+
visit o.orders
|
140
|
+
visit o.limit
|
141
|
+
end
|
142
|
+
|
143
|
+
def visit_Array o
|
144
|
+
o.each { |i| visit i }
|
145
|
+
end
|
146
|
+
|
147
|
+
def visit_Hash o
|
148
|
+
o.each { |k,v| visit(k); visit(v) }
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
data/lib/arel/visitors/mysql.rb
CHANGED
data/lib/arel/visitors/to_sql.rb
CHANGED
@@ -97,7 +97,7 @@ module Arel
|
|
97
97
|
end
|
98
98
|
|
99
99
|
def visit_Arel_Nodes_Offset o
|
100
|
-
"OFFSET #{visit o.
|
100
|
+
"OFFSET #{visit o.expr}"
|
101
101
|
end
|
102
102
|
|
103
103
|
# FIXME: this does nothing on SQLLite3, but should do things on other
|
@@ -191,6 +191,10 @@ module Arel
|
|
191
191
|
"ON #{visit o.expr}"
|
192
192
|
end
|
193
193
|
|
194
|
+
def visit_Arel_Nodes_Not o
|
195
|
+
"NOT #{visit o.expr}"
|
196
|
+
end
|
197
|
+
|
194
198
|
def visit_Arel_Table o
|
195
199
|
if o.table_alias
|
196
200
|
"#{quote_table_name o.name} #{quote_table_name o.table_alias}"
|
@@ -246,6 +250,10 @@ module Arel
|
|
246
250
|
end
|
247
251
|
end
|
248
252
|
|
253
|
+
def visit_Arel_Nodes_As o
|
254
|
+
"#{visit o.left} AS #{visit o.right}"
|
255
|
+
end
|
256
|
+
|
249
257
|
def visit_Arel_Nodes_UnqualifiedColumn o
|
250
258
|
"#{quote_column_name o.name}"
|
251
259
|
end
|
@@ -8,11 +8,18 @@ module Arel
|
|
8
8
|
private
|
9
9
|
|
10
10
|
DISPATCH = Hash.new do |hash, klass|
|
11
|
-
hash[klass] = "visit_#{klass.name.gsub('::', '_')}"
|
11
|
+
hash[klass] = "visit_#{(klass.name || '').gsub('::', '_')}"
|
12
12
|
end
|
13
13
|
|
14
14
|
def visit object
|
15
15
|
send DISPATCH[object.class], object
|
16
|
+
rescue NoMethodError
|
17
|
+
warn "visiting #{object.class} via superclass, this will be removed in arel 2.2.0" if $VERBOSE
|
18
|
+
superklass = object.class.ancestors.find { |klass|
|
19
|
+
respond_to?(DISPATCH[klass], true)
|
20
|
+
}
|
21
|
+
DISPATCH[object.class] = DISPATCH[superklass]
|
22
|
+
retry
|
16
23
|
end
|
17
24
|
end
|
18
25
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module Arel
|
4
|
+
module Nodes
|
5
|
+
describe 'As' do
|
6
|
+
describe '#as' do
|
7
|
+
it 'makes an AS node' do
|
8
|
+
attr = Table.new(:users)[:id]
|
9
|
+
as = attr.as(Arel.sql('foo'))
|
10
|
+
assert_equal attr, as.left
|
11
|
+
assert_equal 'foo', as.right
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module Arel
|
4
|
+
class TestNode < MiniTest::Unit::TestCase
|
5
|
+
def test_all_nodes_are_nodes
|
6
|
+
Nodes.constants.map { |k|
|
7
|
+
Nodes.const_get(k)
|
8
|
+
}.grep(Class).each do |klass|
|
9
|
+
next if Nodes::SqlLiteral == klass
|
10
|
+
assert klass.ancestors.include?(Nodes::Node), klass.name
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_each
|
15
|
+
list = []
|
16
|
+
node = Nodes::Node.new
|
17
|
+
node.each { |n| list << n }
|
18
|
+
assert_equal [node], list
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_generator
|
22
|
+
list = []
|
23
|
+
node = Nodes::Node.new
|
24
|
+
node.each.each { |n| list << n }
|
25
|
+
assert_equal [node], list
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_enumerable
|
29
|
+
node = Nodes::Node.new
|
30
|
+
assert_kind_of Enumerable, node
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module Arel
|
4
|
+
module Nodes
|
5
|
+
describe 'not' do
|
6
|
+
describe '#not' do
|
7
|
+
it 'makes a NOT node' do
|
8
|
+
attr = Table.new(:users)[:id]
|
9
|
+
left = attr.eq(10)
|
10
|
+
right = attr.eq(11)
|
11
|
+
node = left.or right
|
12
|
+
node.expr.left.must_equal left
|
13
|
+
node.expr.right.must_equal right
|
14
|
+
|
15
|
+
node.or(right).not
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,203 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module Arel
|
4
|
+
module Visitors
|
5
|
+
class TestDepthFirst < MiniTest::Unit::TestCase
|
6
|
+
Collector = Struct.new(:calls) do
|
7
|
+
def call object
|
8
|
+
calls << object
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def setup
|
13
|
+
@collector = Collector.new []
|
14
|
+
@visitor = Visitors::DepthFirst.new @collector
|
15
|
+
end
|
16
|
+
|
17
|
+
# unary ops
|
18
|
+
[
|
19
|
+
Arel::Nodes::Not,
|
20
|
+
Arel::Nodes::Group,
|
21
|
+
Arel::Nodes::On,
|
22
|
+
Arel::Nodes::Grouping,
|
23
|
+
Arel::Nodes::Offset,
|
24
|
+
Arel::Nodes::Having,
|
25
|
+
Arel::Nodes::UnqualifiedColumn,
|
26
|
+
].each do |klass|
|
27
|
+
define_method("test_#{klass.name.gsub('::', '_')}") do
|
28
|
+
op = klass.new(:a)
|
29
|
+
@visitor.accept op
|
30
|
+
assert_equal [:a, op], @collector.calls
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# functions
|
35
|
+
[
|
36
|
+
Arel::Nodes::Exists,
|
37
|
+
Arel::Nodes::Avg,
|
38
|
+
Arel::Nodes::Min,
|
39
|
+
Arel::Nodes::Max,
|
40
|
+
Arel::Nodes::Sum,
|
41
|
+
].each do |klass|
|
42
|
+
define_method("test_#{klass.name.gsub('::', '_')}") do
|
43
|
+
func = klass.new(:a, :b)
|
44
|
+
@visitor.accept func
|
45
|
+
assert_equal [:a, :b, func], @collector.calls
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_lock
|
50
|
+
lock = Nodes::Lock.new
|
51
|
+
@visitor.accept lock
|
52
|
+
assert_equal [lock], @collector.calls
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_count
|
56
|
+
count = Nodes::Count.new :a, :b, :c
|
57
|
+
@visitor.accept count
|
58
|
+
assert_equal [:a, :c, :b, count], @collector.calls
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_inner_join
|
62
|
+
join = Nodes::InnerJoin.new :a, :b, :c
|
63
|
+
@visitor.accept join
|
64
|
+
assert_equal [:a, :b, :c, join], @collector.calls
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_outer_join
|
68
|
+
join = Nodes::OuterJoin.new :a, :b, :c
|
69
|
+
@visitor.accept join
|
70
|
+
assert_equal [:a, :b, :c, join], @collector.calls
|
71
|
+
end
|
72
|
+
|
73
|
+
[
|
74
|
+
Arel::Nodes::And,
|
75
|
+
Arel::Nodes::Assignment,
|
76
|
+
Arel::Nodes::Between,
|
77
|
+
Arel::Nodes::DoesNotMatch,
|
78
|
+
Arel::Nodes::Equality,
|
79
|
+
Arel::Nodes::GreaterThan,
|
80
|
+
Arel::Nodes::GreaterThanOrEqual,
|
81
|
+
Arel::Nodes::In,
|
82
|
+
Arel::Nodes::LessThan,
|
83
|
+
Arel::Nodes::LessThanOrEqual,
|
84
|
+
Arel::Nodes::Matches,
|
85
|
+
Arel::Nodes::NotEqual,
|
86
|
+
Arel::Nodes::NotIn,
|
87
|
+
Arel::Nodes::Or,
|
88
|
+
Arel::Nodes::StringJoin,
|
89
|
+
Arel::Nodes::TableAlias,
|
90
|
+
Arel::Nodes::Values,
|
91
|
+
Arel::Nodes::As,
|
92
|
+
Arel::Nodes::DeleteStatement,
|
93
|
+
Arel::Nodes::Ordering,
|
94
|
+
].each do |klass|
|
95
|
+
define_method("test_#{klass.name.gsub('::', '_')}") do
|
96
|
+
binary = klass.new(:a, :b)
|
97
|
+
@visitor.accept binary
|
98
|
+
assert_equal [:a, :b, binary], @collector.calls
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
[
|
103
|
+
Arel::Attributes::Integer,
|
104
|
+
Arel::Attributes::Float,
|
105
|
+
Arel::Attributes::String,
|
106
|
+
Arel::Attributes::Time,
|
107
|
+
Arel::Attributes::Boolean,
|
108
|
+
Arel::Attributes::Attribute
|
109
|
+
].each do |klass|
|
110
|
+
define_method("test_#{klass.name.gsub('::', '_')}") do
|
111
|
+
binary = klass.new(:a, :b)
|
112
|
+
@visitor.accept binary
|
113
|
+
assert_equal [:a, :b, binary], @collector.calls
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def test_table
|
118
|
+
relation = Arel::Table.new(:users)
|
119
|
+
@visitor.accept relation
|
120
|
+
assert_equal ['users', relation], @collector.calls
|
121
|
+
end
|
122
|
+
|
123
|
+
def test_array
|
124
|
+
node = Nodes::Or.new(:a, :b)
|
125
|
+
list = [node]
|
126
|
+
@visitor.accept list
|
127
|
+
assert_equal [:a, :b, node, list], @collector.calls
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_hash
|
131
|
+
node = Nodes::Or.new(:a, :b)
|
132
|
+
hash = { node => node }
|
133
|
+
@visitor.accept hash
|
134
|
+
assert_equal [:a, :b, node, :a, :b, node, hash], @collector.calls
|
135
|
+
end
|
136
|
+
|
137
|
+
def test_update_statement
|
138
|
+
stmt = Nodes::UpdateStatement.new
|
139
|
+
stmt.relation = :a
|
140
|
+
stmt.values << :b
|
141
|
+
stmt.wheres << :c
|
142
|
+
stmt.orders << :d
|
143
|
+
stmt.limit = :e
|
144
|
+
|
145
|
+
@visitor.accept stmt
|
146
|
+
assert_equal [:a, :b, stmt.values, :c, stmt.wheres, :d, stmt.orders,
|
147
|
+
:e, stmt], @collector.calls
|
148
|
+
end
|
149
|
+
|
150
|
+
def test_select_core
|
151
|
+
core = Nodes::SelectCore.new
|
152
|
+
core.projections << :a
|
153
|
+
core.froms = :b
|
154
|
+
core.wheres << :c
|
155
|
+
core.groups << :d
|
156
|
+
core.having = :e
|
157
|
+
|
158
|
+
@visitor.accept core
|
159
|
+
assert_equal [
|
160
|
+
:a, core.projections,
|
161
|
+
:b,
|
162
|
+
:c, core.wheres,
|
163
|
+
:d, core.groups,
|
164
|
+
:e,
|
165
|
+
core], @collector.calls
|
166
|
+
end
|
167
|
+
|
168
|
+
def test_select_statement
|
169
|
+
ss = Nodes::SelectStatement.new
|
170
|
+
ss.cores.replace [:a]
|
171
|
+
ss.orders << :b
|
172
|
+
ss.limit = :c
|
173
|
+
ss.lock = :d
|
174
|
+
ss.offset = :e
|
175
|
+
|
176
|
+
@visitor.accept ss
|
177
|
+
assert_equal [
|
178
|
+
:a, ss.cores,
|
179
|
+
:b, ss.orders,
|
180
|
+
:c,
|
181
|
+
:d,
|
182
|
+
:e,
|
183
|
+
ss], @collector.calls
|
184
|
+
end
|
185
|
+
|
186
|
+
def test_insert_statement
|
187
|
+
stmt = Nodes::InsertStatement.new
|
188
|
+
stmt.relation = :a
|
189
|
+
stmt.columns << :b
|
190
|
+
stmt.values = :c
|
191
|
+
|
192
|
+
@visitor.accept stmt
|
193
|
+
assert_equal [:a, :b, stmt.columns, :c, stmt], @collector.calls
|
194
|
+
end
|
195
|
+
|
196
|
+
def test_node
|
197
|
+
node = Nodes::Node.new
|
198
|
+
@visitor.accept node
|
199
|
+
assert_equal [node], @collector.calls
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
data/test/visitors/test_mysql.rb
CHANGED
@@ -22,6 +22,13 @@ module Arel
|
|
22
22
|
sql = @visitor.accept(stmt)
|
23
23
|
sql.must_be_like "SELECT FROM DUAL"
|
24
24
|
end
|
25
|
+
|
26
|
+
it 'uses FOR UPDATE when locking' do
|
27
|
+
stmt = Nodes::SelectStatement.new
|
28
|
+
stmt.lock = Nodes::Lock.new
|
29
|
+
sql = @visitor.accept(stmt)
|
30
|
+
sql.must_be_like "SELECT FROM DUAL FOR UPDATE"
|
31
|
+
end
|
25
32
|
end
|
26
33
|
end
|
27
34
|
end
|
@@ -21,6 +21,11 @@ module Arel
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
+
it "should visit string subclass" do
|
25
|
+
@visitor.accept(Class.new(String).new(":'("))
|
26
|
+
@visitor.accept(Class.new(Class.new(String)).new(":'("))
|
27
|
+
end
|
28
|
+
|
24
29
|
it "should visit_Class" do
|
25
30
|
@visitor.accept(DateTime).must_equal "'DateTime'"
|
26
31
|
end
|
@@ -33,6 +38,17 @@ module Arel
|
|
33
38
|
@visitor.accept 2.14
|
34
39
|
end
|
35
40
|
|
41
|
+
it "should visit_Not" do
|
42
|
+
sql = @visitor.accept Nodes::Not.new(Arel.sql("foo"))
|
43
|
+
sql.must_be_like "NOT foo"
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should visit_As" do
|
47
|
+
as = Nodes::As.new(Arel.sql("foo"), Arel.sql("bar"))
|
48
|
+
sql = @visitor.accept as
|
49
|
+
sql.must_be_like "foo AS bar"
|
50
|
+
end
|
51
|
+
|
36
52
|
it "should visit_Bignum" do
|
37
53
|
@visitor.accept 8787878092
|
38
54
|
end
|
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: arel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 5
|
4
5
|
prerelease: false
|
5
6
|
segments:
|
6
7
|
- 2
|
7
8
|
- 0
|
8
|
-
-
|
9
|
-
version: 2.0.
|
9
|
+
- 5
|
10
|
+
version: 2.0.5
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Aaron Patterson
|
@@ -17,22 +18,23 @@ autorequire:
|
|
17
18
|
bindir: bin
|
18
19
|
cert_chain: []
|
19
20
|
|
20
|
-
date: 2010-11-
|
21
|
+
date: 2010-11-30 00:00:00 -08:00
|
21
22
|
default_executable:
|
22
23
|
dependencies:
|
23
24
|
- !ruby/object:Gem::Dependency
|
24
|
-
name:
|
25
|
+
name: minitest
|
25
26
|
prerelease: false
|
26
27
|
requirement: &id001 !ruby/object:Gem::Requirement
|
27
28
|
none: false
|
28
29
|
requirements:
|
29
30
|
- - ">="
|
30
31
|
- !ruby/object:Gem::Version
|
32
|
+
hash: 15
|
31
33
|
segments:
|
32
34
|
- 2
|
33
35
|
- 0
|
34
|
-
-
|
35
|
-
version: 2.0.
|
36
|
+
- 0
|
37
|
+
version: 2.0.0
|
36
38
|
type: :development
|
37
39
|
version_requirements: *id001
|
38
40
|
- !ruby/object:Gem::Dependency
|
@@ -43,6 +45,7 @@ dependencies:
|
|
43
45
|
requirements:
|
44
46
|
- - ">="
|
45
47
|
- !ruby/object:Gem::Version
|
48
|
+
hash: 11
|
46
49
|
segments:
|
47
50
|
- 2
|
48
51
|
- 1
|
@@ -58,6 +61,7 @@ dependencies:
|
|
58
61
|
requirements:
|
59
62
|
- - ">="
|
60
63
|
- !ruby/object:Gem::Version
|
64
|
+
hash: 15
|
61
65
|
segments:
|
62
66
|
- 1
|
63
67
|
- 6
|
@@ -73,6 +77,7 @@ dependencies:
|
|
73
77
|
requirements:
|
74
78
|
- - ">="
|
75
79
|
- !ruby/object:Gem::Version
|
80
|
+
hash: 19
|
76
81
|
segments:
|
77
82
|
- 2
|
78
83
|
- 6
|
@@ -115,6 +120,7 @@ files:
|
|
115
120
|
- lib/arel/insert_manager.rb
|
116
121
|
- lib/arel/nodes.rb
|
117
122
|
- lib/arel/nodes/and.rb
|
123
|
+
- lib/arel/nodes/as.rb
|
118
124
|
- lib/arel/nodes/assignment.rb
|
119
125
|
- lib/arel/nodes/avg.rb
|
120
126
|
- lib/arel/nodes/between.rb
|
@@ -141,6 +147,7 @@ files:
|
|
141
147
|
- lib/arel/nodes/max.rb
|
142
148
|
- lib/arel/nodes/min.rb
|
143
149
|
- lib/arel/nodes/node.rb
|
150
|
+
- lib/arel/nodes/not.rb
|
144
151
|
- lib/arel/nodes/not_equal.rb
|
145
152
|
- lib/arel/nodes/not_in.rb
|
146
153
|
- lib/arel/nodes/offset.rb
|
@@ -154,6 +161,7 @@ files:
|
|
154
161
|
- lib/arel/nodes/string_join.rb
|
155
162
|
- lib/arel/nodes/sum.rb
|
156
163
|
- lib/arel/nodes/table_alias.rb
|
164
|
+
- lib/arel/nodes/unary.rb
|
157
165
|
- lib/arel/nodes/unqualified_column.rb
|
158
166
|
- lib/arel/nodes/update_statement.rb
|
159
167
|
- lib/arel/nodes/values.rb
|
@@ -166,6 +174,7 @@ files:
|
|
166
174
|
- lib/arel/tree_manager.rb
|
167
175
|
- lib/arel/update_manager.rb
|
168
176
|
- lib/arel/visitors.rb
|
177
|
+
- lib/arel/visitors/depth_first.rb
|
169
178
|
- lib/arel/visitors/dot.rb
|
170
179
|
- lib/arel/visitors/join_sql.rb
|
171
180
|
- lib/arel/visitors/mysql.rb
|
@@ -178,10 +187,13 @@ files:
|
|
178
187
|
- lib/arel/visitors/where_sql.rb
|
179
188
|
- test/attributes/test_attribute.rb
|
180
189
|
- test/helper.rb
|
190
|
+
- test/nodes/test_as.rb
|
181
191
|
- test/nodes/test_count.rb
|
182
192
|
- test/nodes/test_delete_statement.rb
|
183
193
|
- test/nodes/test_equality.rb
|
184
194
|
- test/nodes/test_insert_statement.rb
|
195
|
+
- test/nodes/test_node.rb
|
196
|
+
- test/nodes/test_not.rb
|
185
197
|
- test/nodes/test_or.rb
|
186
198
|
- test/nodes/test_select_core.rb
|
187
199
|
- test/nodes/test_select_statement.rb
|
@@ -197,6 +209,7 @@ files:
|
|
197
209
|
- test/test_select_manager.rb
|
198
210
|
- test/test_table.rb
|
199
211
|
- test/test_update_manager.rb
|
212
|
+
- test/visitors/test_depth_first.rb
|
200
213
|
- test/visitors/test_join_sql.rb
|
201
214
|
- test/visitors/test_mysql.rb
|
202
215
|
- test/visitors/test_oracle.rb
|
@@ -218,6 +231,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
218
231
|
requirements:
|
219
232
|
- - ">="
|
220
233
|
- !ruby/object:Gem::Version
|
234
|
+
hash: 3
|
221
235
|
segments:
|
222
236
|
- 0
|
223
237
|
version: "0"
|
@@ -226,6 +240,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
226
240
|
requirements:
|
227
241
|
- - ">="
|
228
242
|
- !ruby/object:Gem::Version
|
243
|
+
hash: 3
|
229
244
|
segments:
|
230
245
|
- 0
|
231
246
|
version: "0"
|
@@ -238,10 +253,13 @@ specification_version: 3
|
|
238
253
|
summary: Arel is a Relational Algebra for Ruby
|
239
254
|
test_files:
|
240
255
|
- test/attributes/test_attribute.rb
|
256
|
+
- test/nodes/test_as.rb
|
241
257
|
- test/nodes/test_count.rb
|
242
258
|
- test/nodes/test_delete_statement.rb
|
243
259
|
- test/nodes/test_equality.rb
|
244
260
|
- test/nodes/test_insert_statement.rb
|
261
|
+
- test/nodes/test_node.rb
|
262
|
+
- test/nodes/test_not.rb
|
245
263
|
- test/nodes/test_or.rb
|
246
264
|
- test/nodes/test_select_core.rb
|
247
265
|
- test/nodes/test_select_statement.rb
|
@@ -256,6 +274,7 @@ test_files:
|
|
256
274
|
- test/test_select_manager.rb
|
257
275
|
- test/test_table.rb
|
258
276
|
- test/test_update_manager.rb
|
277
|
+
- test/visitors/test_depth_first.rb
|
259
278
|
- test/visitors/test_join_sql.rb
|
260
279
|
- test/visitors/test_mysql.rb
|
261
280
|
- test/visitors/test_oracle.rb
|