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.
@@ -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
@@ -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
@@ -2,6 +2,7 @@ require "rubygems"
2
2
  gem 'hoe', '>= 2.1.0'
3
3
  require 'hoe'
4
4
 
5
+ Hoe.plugins.delete :rubyforge
5
6
  Hoe.plugin :minitest
6
7
  Hoe.plugin :gemspec # `gem install hoe-gemspec`
7
8
  Hoe.plugin :git # `gem install hoe-git`
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{arel}
5
- s.version = "2.0.2.20101111111102"
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-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"]
@@ -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.4'
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
@@ -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'
@@ -0,0 +1,6 @@
1
+ module Arel
2
+ module Nodes
3
+ class As < Arel::Nodes::Binary
4
+ end
5
+ end
6
+ end
@@ -1,16 +1,18 @@
1
1
  module Arel
2
2
  module Nodes
3
- class DeleteStatement
4
- attr_accessor :relation, :wheres
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
- @from = nil
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
- @wheres = @wheres.clone
15
+ @right = @right.clone
14
16
  end
15
17
  end
16
18
  end
@@ -1,11 +1,6 @@
1
1
  module Arel
2
2
  module Nodes
3
- class Group
4
- attr_accessor :expr
5
-
6
- def initialize expr
7
- @expr = expr
8
- end
3
+ class Group < Arel::Nodes::Unary
9
4
  end
10
5
  end
11
6
  end
@@ -1,11 +1,6 @@
1
1
  module Arel
2
2
  module Nodes
3
- class Grouping < Arel::Nodes::Node
4
- attr_accessor :expr
5
-
6
- def initialize expression
7
- @expr = expression
8
- end
3
+ class Grouping < Arel::Nodes::Unary
9
4
  end
10
5
  end
11
6
  end
@@ -1,11 +1,6 @@
1
1
  module Arel
2
2
  module Nodes
3
- class Having
4
- attr_accessor :expr
5
-
6
- def initialize expr
7
- @expr = expr
8
- end
3
+ class Having < Arel::Nodes::Unary
9
4
  end
10
5
  end
11
6
  end
@@ -1,6 +1,6 @@
1
1
  module Arel
2
2
  module Nodes
3
- class InsertStatement
3
+ class InsertStatement < Arel::Nodes::Node
4
4
  attr_accessor :relation, :columns, :values
5
5
 
6
6
  def initialize
@@ -1,6 +1,6 @@
1
1
  module Arel
2
2
  module Nodes
3
- class Join
3
+ class Join < Arel::Nodes::Node
4
4
  attr_accessor :left, :right, :constraint
5
5
 
6
6
  def initialize left, right, constraint
@@ -1,6 +1,6 @@
1
1
  module Arel
2
2
  module Nodes
3
- class Lock
3
+ class Lock < Arel::Nodes::Node
4
4
  end
5
5
  end
6
6
  end
@@ -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
@@ -0,0 +1,6 @@
1
+ module Arel
2
+ module Nodes
3
+ class Not < Arel::Nodes::Unary
4
+ end
5
+ end
6
+ end
@@ -1,11 +1,7 @@
1
1
  module Arel
2
2
  module Nodes
3
- class Offset
4
- attr_accessor :value
5
-
6
- def initialize value
7
- @value = value
8
- end
3
+ class Offset < Arel::Nodes::Unary
4
+ alias :value :expr
9
5
  end
10
6
  end
11
7
  end
@@ -1,11 +1,6 @@
1
1
  module Arel
2
2
  module Nodes
3
- class On
4
- attr_accessor :expr
5
-
6
- def initialize expr
7
- @expr = expr
8
- end
3
+ class On < Arel::Nodes::Unary
9
4
  end
10
5
  end
11
6
  end
@@ -1,10 +1,11 @@
1
1
  module Arel
2
2
  module Nodes
3
- class Ordering < Arel::Nodes::Node
4
- attr_accessor :expr, :direction
3
+ class Ordering < Arel::Nodes::Binary
4
+ alias :expr :left
5
+ alias :direction :right
5
6
 
6
- def initialize expression, direction = :asc
7
- @expr, @direction = expression, direction
7
+ def initialize expr, direction = :asc
8
+ super
8
9
  end
9
10
 
10
11
  def ascending?
@@ -1,6 +1,6 @@
1
1
  module Arel
2
2
  module Nodes
3
- class SelectCore
3
+ class SelectCore < Arel::Nodes::Node
4
4
  attr_accessor :froms, :projections, :wheres, :groups
5
5
  attr_accessor :having
6
6
 
@@ -1,6 +1,6 @@
1
1
  module Arel
2
2
  module Nodes
3
- class SelectStatement
3
+ class SelectStatement < Arel::Nodes::Node
4
4
  attr_reader :cores
5
5
  attr_accessor :limit, :orders, :lock, :offset
6
6
 
@@ -1,20 +1,12 @@
1
1
  module Arel
2
2
  module Nodes
3
- class TableAlias
4
- attr_reader :name, :relation, :columns
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
- name = name.to_sym
17
- columns.find { |column| column.name == name }
9
+ Attribute.new self, name
18
10
  end
19
11
  end
20
12
  end
@@ -0,0 +1,11 @@
1
+ module Arel
2
+ module Nodes
3
+ class Unary < Arel::Nodes::Node
4
+ attr_accessor :expr
5
+
6
+ def initialize expr
7
+ @expr = expr
8
+ end
9
+ end
10
+ end
11
+ end
@@ -1,18 +1,15 @@
1
1
  module Arel
2
2
  module Nodes
3
- class UnqualifiedColumn
4
- attr_accessor :attribute
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
- @attribute.column
8
+ @expr.column
12
9
  end
13
10
 
14
11
  def name
15
- @attribute.name
12
+ @expr.name
16
13
  end
17
14
  end
18
15
  end
@@ -1,6 +1,6 @@
1
1
  module Arel
2
2
  module Nodes
3
- class UpdateStatement
3
+ class UpdateStatement < Arel::Nodes::Node
4
4
  attr_accessor :relation, :wheres, :values, :orders, :limit
5
5
 
6
6
  def initialize
@@ -1,11 +1,13 @@
1
1
  module Arel
2
2
  module Nodes
3
- class Values
4
- attr_accessor :expressions, :columns
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
- @expressions = exprs
8
- @columns = columns
10
+ super
9
11
  end
10
12
  end
11
13
  end
@@ -1,5 +1,9 @@
1
1
  module Arel
2
2
  module Predications
3
+ def as other
4
+ Nodes::As.new self, other
5
+ end
6
+
3
7
  def not_eq other
4
8
  Nodes::NotEqual.new self, other
5
9
  end
@@ -174,4 +178,4 @@ module Arel
174
178
  }
175
179
  end
176
180
  end
177
- end
181
+ end
@@ -34,8 +34,8 @@ module Arel
34
34
  end
35
35
  end
36
36
 
37
- def alias
38
- Nodes::TableAlias.new("#{name}_2", self).tap do |node|
37
+ def alias name = "#{self.name}_2"
38
+ Nodes::TableAlias.new(name, self).tap do |node|
39
39
  @aliases << node
40
40
  end
41
41
  end
@@ -1,4 +1,5 @@
1
1
  require 'arel/visitors/visitor'
2
+ require 'arel/visitors/depth_first'
2
3
  require 'arel/visitors/to_sql'
3
4
  require 'arel/visitors/sqlite'
4
5
  require 'arel/visitors/postgresql'
@@ -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
@@ -2,6 +2,10 @@ module Arel
2
2
  module Visitors
3
3
  class MySQL < Arel::Visitors::ToSql
4
4
  private
5
+ def visit_Arel_Nodes_Lock o
6
+ "FOR UPDATE"
7
+ end
8
+
5
9
  ###
6
10
  # :'(
7
11
  # http://dev.mysql.com/doc/refman/5.0/en/select.html#id3482214
@@ -97,7 +97,7 @@ module Arel
97
97
  end
98
98
 
99
99
  def visit_Arel_Nodes_Offset o
100
- "OFFSET #{visit o.value}"
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
@@ -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
- - 4
9
- version: 2.0.4
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-17 00:00:00 -08:00
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: rubyforge
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
- - 4
35
- version: 2.0.4
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