arel 2.0.6 → 2.0.7.beta.20110110114925

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,10 @@
1
+ == 2.0.7 (unreleased)
2
+
3
+ * Bug Fixes
4
+
5
+ * Limit members are visited
6
+ * Fixing MSSQL TOP support
7
+
1
8
  == 2.0.6 12/01/2010
2
9
 
3
10
  * Bug Fixes
@@ -39,6 +39,7 @@ lib/arel/nodes/insert_statement.rb
39
39
  lib/arel/nodes/join.rb
40
40
  lib/arel/nodes/less_than.rb
41
41
  lib/arel/nodes/less_than_or_equal.rb
42
+ lib/arel/nodes/limit.rb
42
43
  lib/arel/nodes/lock.rb
43
44
  lib/arel/nodes/matches.rb
44
45
  lib/arel/nodes/max.rb
@@ -58,6 +59,7 @@ lib/arel/nodes/sql_literal.rb
58
59
  lib/arel/nodes/string_join.rb
59
60
  lib/arel/nodes/sum.rb
60
61
  lib/arel/nodes/table_alias.rb
62
+ lib/arel/nodes/top.rb
61
63
  lib/arel/nodes/unary.rb
62
64
  lib/arel/nodes/unqualified_column.rb
63
65
  lib/arel/nodes/update_statement.rb
@@ -74,6 +76,7 @@ lib/arel/visitors.rb
74
76
  lib/arel/visitors/depth_first.rb
75
77
  lib/arel/visitors/dot.rb
76
78
  lib/arel/visitors/join_sql.rb
79
+ lib/arel/visitors/mssql.rb
77
80
  lib/arel/visitors/mysql.rb
78
81
  lib/arel/visitors/oracle.rb
79
82
  lib/arel/visitors/order_clauses.rb
@@ -107,7 +110,9 @@ test/test_select_manager.rb
107
110
  test/test_table.rb
108
111
  test/test_update_manager.rb
109
112
  test/visitors/test_depth_first.rb
113
+ test/visitors/test_dot.rb
110
114
  test/visitors/test_join_sql.rb
115
+ test/visitors/test_mssql.rb
111
116
  test/visitors/test_mysql.rb
112
117
  test/visitors/test_oracle.rb
113
118
  test/visitors/test_postgres.rb
@@ -2,22 +2,22 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{arel}
5
- s.version = "2.0.5.20101130111154"
5
+ s.version = "2.0.7.beta.20110110114925"
6
6
 
7
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
7
+ s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") 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-30}
9
+ s.date = %q{2011-01-10}
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"]
13
- s.files = [".autotest", "History.txt", "MIT-LICENSE.txt", "Manifest.txt", "README.markdown", "Rakefile", "arel.gemspec", "lib/arel.rb", "lib/arel/attributes.rb", "lib/arel/attributes/attribute.rb", "lib/arel/compatibility/wheres.rb", "lib/arel/crud.rb", "lib/arel/delete_manager.rb", "lib/arel/deprecated.rb", "lib/arel/expression.rb", "lib/arel/expressions.rb", "lib/arel/insert_manager.rb", "lib/arel/nodes.rb", "lib/arel/nodes/and.rb", "lib/arel/nodes/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/exists.rb", "lib/arel/nodes/function.rb", "lib/arel/nodes/greater_than.rb", "lib/arel/nodes/greater_than_or_equal.rb", "lib/arel/nodes/group.rb", "lib/arel/nodes/grouping.rb", "lib/arel/nodes/having.rb", "lib/arel/nodes/in.rb", "lib/arel/nodes/inner_join.rb", "lib/arel/nodes/insert_statement.rb", "lib/arel/nodes/join.rb", "lib/arel/nodes/less_than.rb", "lib/arel/nodes/less_than_or_equal.rb", "lib/arel/nodes/lock.rb", "lib/arel/nodes/matches.rb", "lib/arel/nodes/max.rb", "lib/arel/nodes/min.rb", "lib/arel/nodes/node.rb", "lib/arel/nodes/not.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/unary.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/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_join_sql.rb", "test/visitors/test_mysql.rb", "test/visitors/test_oracle.rb", "test/visitors/test_postgres.rb", "test/visitors/test_sqlite.rb", "test/visitors/test_to_sql.rb"]
13
+ s.files = [".autotest", "History.txt", "MIT-LICENSE.txt", "Manifest.txt", "README.markdown", "Rakefile", "arel.gemspec", "lib/arel.rb", "lib/arel/attributes.rb", "lib/arel/attributes/attribute.rb", "lib/arel/compatibility/wheres.rb", "lib/arel/crud.rb", "lib/arel/delete_manager.rb", "lib/arel/deprecated.rb", "lib/arel/expression.rb", "lib/arel/expressions.rb", "lib/arel/insert_manager.rb", "lib/arel/nodes.rb", "lib/arel/nodes/and.rb", "lib/arel/nodes/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/exists.rb", "lib/arel/nodes/function.rb", "lib/arel/nodes/greater_than.rb", "lib/arel/nodes/greater_than_or_equal.rb", "lib/arel/nodes/group.rb", "lib/arel/nodes/grouping.rb", "lib/arel/nodes/having.rb", "lib/arel/nodes/in.rb", "lib/arel/nodes/inner_join.rb", "lib/arel/nodes/insert_statement.rb", "lib/arel/nodes/join.rb", "lib/arel/nodes/less_than.rb", "lib/arel/nodes/less_than_or_equal.rb", "lib/arel/nodes/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/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
14
  s.homepage = %q{http://github.com/rails/arel}
15
15
  s.rdoc_options = ["--main", "README.markdown"]
16
16
  s.require_paths = ["lib"]
17
17
  s.rubyforge_project = %q{arel}
18
18
  s.rubygems_version = %q{1.3.7}
19
19
  s.summary = %q{Arel is a Relational Algebra for Ruby}
20
- s.test_files = ["test/attributes/test_attribute.rb", "test/nodes/test_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_join_sql.rb", "test/visitors/test_mysql.rb", "test/visitors/test_oracle.rb", "test/visitors/test_postgres.rb", "test/visitors/test_sqlite.rb", "test/visitors/test_to_sql.rb"]
20
+ 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
21
 
22
22
  if s.respond_to? :specification_version then
23
23
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
@@ -27,17 +27,17 @@ Gem::Specification.new do |s|
27
27
  s.add_development_dependency(%q<minitest>, [">= 2.0.0"])
28
28
  s.add_development_dependency(%q<hoe>, [">= 2.1.0"])
29
29
  s.add_development_dependency(%q<minitest>, [">= 1.6.0"])
30
- s.add_development_dependency(%q<hoe>, [">= 2.6.2"])
30
+ s.add_development_dependency(%q<hoe>, [">= 2.8.0"])
31
31
  else
32
32
  s.add_dependency(%q<minitest>, [">= 2.0.0"])
33
33
  s.add_dependency(%q<hoe>, [">= 2.1.0"])
34
34
  s.add_dependency(%q<minitest>, [">= 1.6.0"])
35
- s.add_dependency(%q<hoe>, [">= 2.6.2"])
35
+ s.add_dependency(%q<hoe>, [">= 2.8.0"])
36
36
  end
37
37
  else
38
38
  s.add_dependency(%q<minitest>, [">= 2.0.0"])
39
39
  s.add_dependency(%q<hoe>, [">= 2.1.0"])
40
40
  s.add_dependency(%q<minitest>, [">= 1.6.0"])
41
- s.add_dependency(%q<hoe>, [">= 2.6.2"])
41
+ s.add_dependency(%q<hoe>, [">= 2.8.0"])
42
42
  end
43
43
  end
@@ -29,7 +29,7 @@ require 'arel/sql_literal'
29
29
  ####
30
30
 
31
31
  module Arel
32
- VERSION = '2.0.6'
32
+ VERSION = '2.0.7.beta'
33
33
 
34
34
  def self.sql raw_sql
35
35
  Arel::Nodes::SqlLiteral.new raw_sql
@@ -13,7 +13,7 @@ module Arel
13
13
  end
14
14
  um.table relation
15
15
  um.set values
16
- um.take @ast.limit
16
+ um.take @ast.limit.expr if @ast.limit
17
17
  um.order(*@ast.orders)
18
18
  um.wheres = @ctx.wheres
19
19
 
@@ -3,6 +3,7 @@ module Arel
3
3
  def initialize engine
4
4
  super
5
5
  @ast = Nodes::DeleteStatement.new
6
+ @ctx = @ast
6
7
  end
7
8
 
8
9
  def from relation
@@ -10,11 +11,6 @@ module Arel
10
11
  self
11
12
  end
12
13
 
13
- def where expression
14
- @ast.wheres << expression
15
- self
16
- end
17
-
18
14
  def wheres= list
19
15
  @ast.wheres = list
20
16
  end
@@ -24,6 +24,8 @@ require 'arel/nodes/function'
24
24
  require 'arel/nodes/count'
25
25
  require 'arel/nodes/values'
26
26
  require 'arel/nodes/offset'
27
+ require 'arel/nodes/limit'
28
+ require 'arel/nodes/top'
27
29
  require 'arel/nodes/sum'
28
30
  require 'arel/nodes/exists'
29
31
  require 'arel/nodes/max'
@@ -0,0 +1,7 @@
1
+ module Arel
2
+ module Nodes
3
+ class Limit < Arel::Nodes::Unary
4
+ end
5
+ end
6
+ end
7
+
@@ -7,7 +7,7 @@ module Arel
7
7
  # Factory method to create a Nodes::Not node that has the recipient of
8
8
  # the caller as a child.
9
9
  def not
10
- Nodes::Not.new self
10
+ Nodes::Not.new Nodes::Grouping.new self
11
11
  end
12
12
 
13
13
  ###
@@ -1,10 +1,11 @@
1
1
  module Arel
2
2
  module Nodes
3
3
  class SelectCore < Arel::Nodes::Node
4
- attr_accessor :froms, :projections, :wheres, :groups
4
+ attr_accessor :top, :froms, :projections, :wheres, :groups
5
5
  attr_accessor :having
6
6
 
7
7
  def initialize
8
+ @top = nil
8
9
  @froms = nil
9
10
  @projections = []
10
11
  @wheres = []
@@ -0,0 +1,6 @@
1
+ module Arel
2
+ module Nodes
3
+ class Top < Arel::Nodes::Unary
4
+ end
5
+ end
6
+ end
@@ -31,7 +31,7 @@ module Arel
31
31
  def in other
32
32
  case other
33
33
  when Arel::SelectManager
34
- Nodes::In.new self, other.to_a.map { |x| x.id }
34
+ Arel::Nodes::In.new(self, other.ast)
35
35
  when Range
36
36
  if other.exclude_end?
37
37
  left = Nodes::GreaterThanOrEqual.new(self, other.begin)
@@ -56,7 +56,7 @@ module Arel
56
56
  def not_in other
57
57
  case other
58
58
  when Arel::SelectManager
59
- Nodes::NotIn.new self, other.to_a.map { |x| x.id }
59
+ Arel::Nodes::NotIn.new(self, other.ast)
60
60
  when Range
61
61
  if other.exclude_end?
62
62
  left = Nodes::LessThan.new(self, other.begin)
@@ -10,7 +10,7 @@ module Arel
10
10
  end
11
11
 
12
12
  def taken
13
- @ast.limit
13
+ @ast.limit && @ast.limit.expr
14
14
  end
15
15
 
16
16
  def constraints
@@ -107,11 +107,6 @@ module Arel
107
107
  self
108
108
  end
109
109
 
110
- def where expr
111
- @ctx.wheres << expr
112
- self
113
- end
114
-
115
110
  def order *expr
116
111
  # FIXME: We SHOULD NOT be converting these to SqlLiteral automatically
117
112
  @ast.orders.concat expr.map { |x|
@@ -136,7 +131,8 @@ module Arel
136
131
  end
137
132
 
138
133
  def take limit
139
- @ast.limit = limit
134
+ @ast.limit = Nodes::Limit.new(limit)
135
+ @ctx.top = Nodes::Top.new(limit)
140
136
  self
141
137
  end
142
138
 
@@ -9,6 +9,7 @@ module Arel
9
9
  def initialize engine
10
10
  @engine = engine
11
11
  @visitor = Visitors.visitor_for @engine
12
+ @ctx = nil
12
13
  end
13
14
 
14
15
  def to_dot
@@ -23,5 +24,13 @@ module Arel
23
24
  super
24
25
  @ast = @ast.clone
25
26
  end
27
+
28
+ def where expr
29
+ if Arel::TreeManager === expr
30
+ expr = expr.ast
31
+ end
32
+ @ctx.wheres << expr
33
+ self
34
+ end
26
35
  end
27
36
  end
@@ -3,10 +3,11 @@ module Arel
3
3
  def initialize engine
4
4
  super
5
5
  @ast = Nodes::UpdateStatement.new
6
+ @ctx = @ast
6
7
  end
7
8
 
8
9
  def take limit
9
- @ast.limit = limit
10
+ @ast.limit = Nodes::Limit.new(limit) if limit
10
11
  self
11
12
  end
12
13
 
@@ -4,6 +4,7 @@ require 'arel/visitors/to_sql'
4
4
  require 'arel/visitors/sqlite'
5
5
  require 'arel/visitors/postgresql'
6
6
  require 'arel/visitors/mysql'
7
+ require 'arel/visitors/mssql'
7
8
  require 'arel/visitors/oracle'
8
9
  require 'arel/visitors/join_sql'
9
10
  require 'arel/visitors/where_sql'
@@ -16,6 +17,8 @@ module Arel
16
17
  'postgresql' => Arel::Visitors::PostgreSQL,
17
18
  'mysql' => Arel::Visitors::MySQL,
18
19
  'mysql2' => Arel::Visitors::MySQL,
20
+ 'mssql' => Arel::Visitors::MSSQL,
21
+ 'sqlserver' => Arel::Visitors::MSSQL,
19
22
  'oracle_enhanced' => Arel::Visitors::Oracle,
20
23
  'sqlite' => Arel::Visitors::SQLite,
21
24
  'sqlite3' => Arel::Visitors::SQLite,
@@ -18,9 +18,11 @@ module Arel
18
18
  alias :visit_Arel_Nodes_Group :unary
19
19
  alias :visit_Arel_Nodes_Grouping :unary
20
20
  alias :visit_Arel_Nodes_Having :unary
21
+ alias :visit_Arel_Nodes_Limit :unary
21
22
  alias :visit_Arel_Nodes_Not :unary
22
23
  alias :visit_Arel_Nodes_Offset :unary
23
24
  alias :visit_Arel_Nodes_On :unary
25
+ alias :visit_Arel_Nodes_Top :unary
24
26
  alias :visit_Arel_Nodes_UnqualifiedColumn :unary
25
27
 
26
28
  def function o
@@ -28,10 +28,6 @@ module Arel
28
28
  end
29
29
 
30
30
  private
31
- def visit_Arel_Nodes_Grouping o
32
- visit_edge o, "expr"
33
- end
34
-
35
31
  def visit_Arel_Nodes_Ordering o
36
32
  visit_edge o, "expr"
37
33
  visit_edge o, "direction"
@@ -55,10 +51,6 @@ module Arel
55
51
  visit_edge o, "distinct"
56
52
  end
57
53
 
58
- def visit_Arel_Nodes_On o
59
- visit_edge o, "expr"
60
- end
61
-
62
54
  def visit_Arel_Nodes_Values o
63
55
  visit_edge o, "expressions"
64
56
  end
@@ -80,13 +72,18 @@ module Arel
80
72
  visit_edge o, "wheres"
81
73
  end
82
74
 
83
- def visit_Arel_Nodes_UnqualifiedColumn o
84
- visit_edge o, "attribute"
85
- end
86
-
87
- def visit_Arel_Nodes_Offset o
88
- visit_edge o, "value"
75
+ def unary o
76
+ visit_edge o, "expr"
89
77
  end
78
+ alias :visit_Arel_Nodes_Group :unary
79
+ alias :visit_Arel_Nodes_Grouping :unary
80
+ alias :visit_Arel_Nodes_Having :unary
81
+ alias :visit_Arel_Nodes_Limit :unary
82
+ alias :visit_Arel_Nodes_Not :unary
83
+ alias :visit_Arel_Nodes_Offset :unary
84
+ alias :visit_Arel_Nodes_On :unary
85
+ alias :visit_Arel_Nodes_Top :unary
86
+ alias :visit_Arel_Nodes_UnqualifiedColumn :unary
90
87
 
91
88
  def visit_Arel_Nodes_InsertStatement o
92
89
  visit_edge o, "relation"
@@ -0,0 +1,16 @@
1
+ module Arel
2
+ module Visitors
3
+ class MSSQL < Arel::Visitors::ToSql
4
+ private
5
+
6
+ def visit_Arel_Nodes_Limit o
7
+ ""
8
+ end
9
+
10
+ def visit_Arel_Nodes_Top o
11
+ "TOP #{visit o.expr}"
12
+ end
13
+
14
+ end
15
+ end
16
+ end
@@ -10,7 +10,7 @@ module Arel
10
10
  # :'(
11
11
  # http://dev.mysql.com/doc/refman/5.0/en/select.html#id3482214
12
12
  def visit_Arel_Nodes_SelectStatement o
13
- o.limit = 18446744073709551615 if o.offset && !o.limit
13
+ o.limit = Arel::Nodes::Limit.new(18446744073709551615) if o.offset && !o.limit
14
14
  super
15
15
  end
16
16
 
@@ -25,7 +25,7 @@ module Arel
25
25
  ("SET #{o.values.map { |value| visit value }.join ', '}" unless o.values.empty?),
26
26
  ("WHERE #{o.wheres.map { |x| visit x }.join ' AND '}" unless o.wheres.empty?),
27
27
  ("ORDER BY #{o.orders.map { |x| visit x }.join(', ')}" unless o.orders.empty?),
28
- ("LIMIT #{o.limit}" if o.limit),
28
+ (visit(o.limit) if o.limit),
29
29
  ].compact.join ' '
30
30
  end
31
31
 
@@ -10,17 +10,15 @@ module Arel
10
10
  # then can use simple ROWNUM in WHERE clause
11
11
  if o.limit && o.orders.empty? && !o.offset && o.cores.first.projections.first !~ /^DISTINCT /
12
12
  o.cores.last.wheres.push Nodes::LessThanOrEqual.new(
13
- Nodes::SqlLiteral.new('ROWNUM'), o.limit
13
+ Nodes::SqlLiteral.new('ROWNUM'), o.limit.expr
14
14
  )
15
- o.limit = nil
16
15
  return super
17
16
  end
18
17
 
19
18
  if o.limit && o.offset
20
19
  o = o.dup
21
- limit = o.limit.to_i
20
+ limit = o.limit.expr.to_i
22
21
  offset = o.offset
23
- o.limit = nil
24
22
  o.offset = nil
25
23
  sql = super(o)
26
24
  return <<-eosql
@@ -35,9 +33,8 @@ module Arel
35
33
 
36
34
  if o.limit
37
35
  o = o.dup
38
- limit = o.limit
39
- o.limit = nil
40
- return "SELECT * FROM (#{super(o)}) WHERE ROWNUM <= #{limit}"
36
+ limit = o.limit.expr
37
+ return "SELECT * FROM (#{super(o)}) WHERE ROWNUM <= #{visit limit}"
41
38
  end
42
39
 
43
40
  if o.offset
@@ -57,6 +54,9 @@ module Arel
57
54
  super
58
55
  end
59
56
 
57
+ def visit_Arel_Nodes_Limit o
58
+ end
59
+
60
60
  def visit_Arel_Nodes_Offset o
61
61
  "raw_rnum_ > #{visit o.value}"
62
62
  end
@@ -17,7 +17,7 @@ module Arel
17
17
  [
18
18
  "SELECT * FROM (#{sql}) AS id_list",
19
19
  "ORDER BY #{aliased_orders(o.orders).join(', ')}",
20
- ("LIMIT #{o.limit}" if o.limit),
20
+ (visit(o.limit) if o.limit),
21
21
  (visit(o.offset) if o.offset),
22
22
  ].compact.join ' '
23
23
  else
@@ -3,7 +3,7 @@ module Arel
3
3
  class SQLite < Arel::Visitors::ToSql
4
4
  private
5
5
  def visit_Arel_Nodes_SelectStatement o
6
- o.limit = -1 if o.offset && !o.limit
6
+ o.limit = Arel::Nodes::Limit.new(-1) if o.offset && !o.limit
7
7
  super
8
8
  end
9
9
  end
@@ -76,7 +76,7 @@ module Arel
76
76
  [
77
77
  o.cores.map { |x| visit_Arel_Nodes_SelectCore x }.join,
78
78
  ("ORDER BY #{o.orders.map { |x| visit x }.join(', ')}" unless o.orders.empty?),
79
- ("LIMIT #{o.limit}" if o.limit),
79
+ (visit(o.limit) if o.limit),
80
80
  (visit(o.offset) if o.offset),
81
81
  (visit(o.lock) if o.lock),
82
82
  ].compact.join ' '
@@ -84,7 +84,9 @@ module Arel
84
84
 
85
85
  def visit_Arel_Nodes_SelectCore o
86
86
  [
87
- "SELECT #{o.projections.map { |x| visit x }.join ', '}",
87
+ "SELECT",
88
+ (visit(o.top) if o.top),
89
+ "#{o.projections.map { |x| visit x }.join ', '}",
88
90
  ("FROM #{visit o.froms}" if o.froms),
89
91
  ("WHERE #{o.wheres.map { |x| visit x }.join ' AND ' }" unless o.wheres.empty?),
90
92
  ("GROUP BY #{o.groups.map { |x| visit x }.join ', ' }" unless o.groups.empty?),
@@ -100,6 +102,15 @@ module Arel
100
102
  "OFFSET #{visit o.expr}"
101
103
  end
102
104
 
105
+ def visit_Arel_Nodes_Limit o
106
+ "LIMIT #{visit o.expr}"
107
+ end
108
+
109
+ # FIXME: this does nothing on most databases, but does on MSSQL
110
+ def visit_Arel_Nodes_Top o
111
+ ""
112
+ end
113
+
103
114
  # FIXME: this does nothing on SQLLite3, but should do things on other
104
115
  # databases.
105
116
  def visit_Arel_Nodes_Lock o
@@ -192,7 +203,7 @@ module Arel
192
203
  end
193
204
 
194
205
  def visit_Arel_Nodes_Not o
195
- "NOT #{visit o.expr}"
206
+ "NOT (#{visit o.expr})"
196
207
  end
197
208
 
198
209
  def visit_Arel_Table o
@@ -204,17 +215,11 @@ module Arel
204
215
  end
205
216
 
206
217
  def visit_Arel_Nodes_In o
207
- right = o.right
208
- "#{visit o.left} IN (#{
209
- right.empty? ? 'NULL' : right.map { |x| visit x }.join(', ')
210
- })"
218
+ "#{visit o.left} IN (#{visit o.right})"
211
219
  end
212
220
 
213
221
  def visit_Arel_Nodes_NotIn o
214
- right = o.right
215
- "#{visit o.left} NOT IN (#{
216
- right.empty? ? 'NULL' : right.map { |x| visit x }.join(', ')
217
- })"
222
+ "#{visit o.left} NOT IN (#{visit o.right})"
218
223
  end
219
224
 
220
225
  def visit_Arel_Nodes_And o
@@ -291,6 +296,10 @@ module Arel
291
296
  alias :visit_ActiveSupport_StringInquirer :visit_String
292
297
  alias :visit_Class :visit_String
293
298
 
299
+ def visit_Array o
300
+ o.empty? ? 'NULL' : o.map { |x| visit x }.join(', ')
301
+ end
302
+
294
303
  def quote value, column = nil
295
304
  @connection.quote value, column
296
305
  end
@@ -13,8 +13,8 @@ module Arel
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
16
+ rescue NoMethodError => e
17
+ raise e if respond_to?(DISPATCH[object.class], true)
18
18
  superklass = object.class.ancestors.find { |klass|
19
19
  respond_to?(DISPATCH[klass], true)
20
20
  }
@@ -8,6 +8,15 @@ module Arel
8
8
  end
9
9
  end
10
10
 
11
+ it 'handles limit properly' do
12
+ table = Table.new(:users)
13
+ um = Arel::UpdateManager.new Table.engine
14
+ um.take 10
15
+ um.table table
16
+ um.set [[table[:name], nil]]
17
+ assert_match(/LIMIT 10/, um.to_sql)
18
+ end
19
+
11
20
  describe 'set' do
12
21
  it "updates with null" do
13
22
  table = Table.new(:users)
@@ -30,6 +30,8 @@ module Arel
30
30
  Arel::Nodes::Offset,
31
31
  Arel::Nodes::Having,
32
32
  Arel::Nodes::UnqualifiedColumn,
33
+ Arel::Nodes::Top,
34
+ Arel::Nodes::Limit,
33
35
  ].each do |klass|
34
36
  define_method("test_#{klass.name.gsub('::', '_')}") do
35
37
  op = klass.new(:a)
@@ -0,0 +1,29 @@
1
+ require 'helper'
2
+
3
+ module Arel
4
+ module Visitors
5
+ class TestDot < MiniTest::Unit::TestCase
6
+ def setup
7
+ @visitor = Visitors::Dot.new
8
+ end
9
+
10
+ # unary ops
11
+ [
12
+ Arel::Nodes::Not,
13
+ Arel::Nodes::Group,
14
+ Arel::Nodes::On,
15
+ Arel::Nodes::Grouping,
16
+ Arel::Nodes::Offset,
17
+ Arel::Nodes::Having,
18
+ Arel::Nodes::UnqualifiedColumn,
19
+ Arel::Nodes::Top,
20
+ Arel::Nodes::Limit,
21
+ ].each do |klass|
22
+ define_method("test_#{klass.name.gsub('::', '_')}") do
23
+ op = klass.new(:a)
24
+ @visitor.accept op
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,18 @@
1
+ require 'helper'
2
+
3
+ module Arel
4
+ module Visitors
5
+ describe 'the mssql visitor' do
6
+ before do
7
+ @visitor = MSSQL.new Table.engine
8
+ end
9
+
10
+ it 'uses TOP to limit results' do
11
+ stmt = Nodes::SelectStatement.new
12
+ stmt.cores.last.top = Nodes::Top.new(1)
13
+ sql = @visitor.accept(stmt)
14
+ sql.must_be_like "SELECT TOP 1"
15
+ end
16
+ end
17
+ end
18
+ end
@@ -17,6 +17,12 @@ module Arel
17
17
  sql.must_be_like "SELECT FROM DUAL LIMIT 18446744073709551615 OFFSET 1"
18
18
  end
19
19
 
20
+ it "should escape LIMIT" do
21
+ sc = Arel::Nodes::UpdateStatement.new
22
+ sc.limit = Nodes::Limit.new("omg")
23
+ assert_equal("UPDATE NULL LIMIT 'omg'", @visitor.accept(sc))
24
+ end
25
+
20
26
  it 'uses DUAL for empty from' do
21
27
  stmt = Nodes::SelectStatement.new
22
28
  sql = @visitor.accept(stmt)
@@ -59,7 +59,7 @@ module Arel
59
59
  describe 'limit' do
60
60
  it 'adds a rownum clause' do
61
61
  stmt = Nodes::SelectStatement.new
62
- stmt.limit = 10
62
+ stmt.limit = Nodes::Limit.new(10)
63
63
  sql = @visitor.accept stmt
64
64
  sql.must_be_like %{ SELECT WHERE ROWNUM <= 10 }
65
65
  end
@@ -67,7 +67,7 @@ module Arel
67
67
  it 'is idempotent' do
68
68
  stmt = Nodes::SelectStatement.new
69
69
  stmt.orders << Nodes::SqlLiteral.new('foo')
70
- stmt.limit = 10
70
+ stmt.limit = Nodes::Limit.new(10)
71
71
  sql = @visitor.accept stmt
72
72
  sql2 = @visitor.accept stmt
73
73
  sql.must_equal sql2
@@ -76,7 +76,7 @@ module Arel
76
76
  it 'creates a subquery when there is order_by' do
77
77
  stmt = Nodes::SelectStatement.new
78
78
  stmt.orders << Nodes::SqlLiteral.new('foo')
79
- stmt.limit = 10
79
+ stmt.limit = Nodes::Limit.new(10)
80
80
  sql = @visitor.accept stmt
81
81
  sql.must_be_like %{
82
82
  SELECT * FROM (SELECT ORDER BY foo) WHERE ROWNUM <= 10
@@ -86,7 +86,7 @@ module Arel
86
86
  it 'creates a subquery when there is DISTINCT' do
87
87
  stmt = Nodes::SelectStatement.new
88
88
  stmt.cores.first.projections << Nodes::SqlLiteral.new('DISTINCT id')
89
- stmt.limit = 10
89
+ stmt.limit = Arel::Nodes::Limit.new(10)
90
90
  sql = @visitor.accept stmt
91
91
  sql.must_be_like %{
92
92
  SELECT * FROM (SELECT DISTINCT id) WHERE ROWNUM <= 10
@@ -95,7 +95,7 @@ module Arel
95
95
 
96
96
  it 'creates a different subquery when there is an offset' do
97
97
  stmt = Nodes::SelectStatement.new
98
- stmt.limit = 10
98
+ stmt.limit = Nodes::Limit.new(10)
99
99
  stmt.offset = Nodes::Offset.new(10)
100
100
  sql = @visitor.accept stmt
101
101
  sql.must_be_like %{
@@ -110,7 +110,7 @@ module Arel
110
110
 
111
111
  it 'is idempotent with different subquery' do
112
112
  stmt = Nodes::SelectStatement.new
113
- stmt.limit = 10
113
+ stmt.limit = Nodes::Limit.new(10)
114
114
  stmt.offset = Nodes::Offset.new(10)
115
115
  sql = @visitor.accept stmt
116
116
  sql2 = @visitor.accept stmt
@@ -12,6 +12,16 @@ module Arel
12
12
  FOR UPDATE
13
13
  }
14
14
  end
15
+
16
+ it "should escape LIMIT" do
17
+ sc = Arel::Nodes::SelectStatement.new
18
+ sc.limit = Nodes::Limit.new("omg")
19
+ sc.cores.first.projections << 'DISTINCT ON'
20
+ sc.orders << "xyz"
21
+ sql = @visitor.accept(sc)
22
+ assert_match(/LIMIT 'omg'/, sql)
23
+ assert_equal 1, sql.scan(/LIMIT/).length, 'should have one limit'
24
+ end
15
25
  end
16
26
  end
17
27
  end
@@ -30,6 +30,12 @@ module Arel
30
30
  @visitor.accept(DateTime).must_equal "'DateTime'"
31
31
  end
32
32
 
33
+ it "should escape LIMIT" do
34
+ sc = Arel::Nodes::SelectStatement.new
35
+ sc.limit = Arel::Nodes::Limit.new("omg")
36
+ assert_match(/LIMIT 'omg'/, @visitor.accept(sc))
37
+ end
38
+
33
39
  it "should visit_DateTime" do
34
40
  @visitor.accept DateTime.now
35
41
  end
@@ -40,7 +46,13 @@ module Arel
40
46
 
41
47
  it "should visit_Not" do
42
48
  sql = @visitor.accept Nodes::Not.new(Arel.sql("foo"))
43
- sql.must_be_like "NOT foo"
49
+ sql.must_be_like "NOT (foo)"
50
+ end
51
+
52
+ it "should apply Not to the whole expression" do
53
+ node = Nodes::And.new @attr.eq(10), @attr.eq(11)
54
+ sql = @visitor.accept Nodes::Not.new(node)
55
+ sql.must_be_like %{NOT ("users"."id" = 10 AND "users"."id" = 11)}
44
56
  end
45
57
 
46
58
  it "should visit_As" do
@@ -131,6 +143,15 @@ module Arel
131
143
  }
132
144
  end
133
145
 
146
+ it 'can handle subqueries' do
147
+ table = Table.new(:users)
148
+ subquery = table.project(:id).where(table[:name].eq('Aaron'))
149
+ node = @attr.in subquery
150
+ @visitor.accept(node).must_be_like %{
151
+ "users"."id" IN (SELECT id FROM "users" WHERE "users"."name" = 'Aaron')
152
+ }
153
+ end
154
+
134
155
  it 'uses the same column for escaping values' do
135
156
  @attr = Table.new(:users)[:name]
136
157
  visitor = Class.new(ToSql) do
@@ -177,6 +198,15 @@ module Arel
177
198
  }
178
199
  end
179
200
 
201
+ it 'can handle subqueries' do
202
+ table = Table.new(:users)
203
+ subquery = table.project(:id).where(table[:name].eq('Aaron'))
204
+ node = @attr.not_in subquery
205
+ @visitor.accept(node).must_be_like %{
206
+ "users"."id" NOT IN (SELECT id FROM "users" WHERE "users"."name" = 'Aaron')
207
+ }
208
+ end
209
+
180
210
  it 'uses the same column for escaping values' do
181
211
  @attr = Table.new(:users)[:name]
182
212
  visitor = Class.new(ToSql) do
metadata CHANGED
@@ -1,13 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: arel
3
3
  version: !ruby/object:Gem::Version
4
- hash: 3
5
- prerelease: false
4
+ hash: 40220158689793
5
+ prerelease: true
6
6
  segments:
7
7
  - 2
8
8
  - 0
9
- - 6
10
- version: 2.0.6
9
+ - 7
10
+ - beta
11
+ - 20110110114925
12
+ version: 2.0.7.beta.20110110114925
11
13
  platform: ruby
12
14
  authors:
13
15
  - Aaron Patterson
@@ -18,7 +20,7 @@ autorequire:
18
20
  bindir: bin
19
21
  cert_chain: []
20
22
 
21
- date: 2010-12-01 00:00:00 -08:00
23
+ date: 2011-01-10 00:00:00 -08:00
22
24
  default_executable:
23
25
  dependencies:
24
26
  - !ruby/object:Gem::Dependency
@@ -77,12 +79,12 @@ dependencies:
77
79
  requirements:
78
80
  - - ">="
79
81
  - !ruby/object:Gem::Version
80
- hash: 19
82
+ hash: 47
81
83
  segments:
82
84
  - 2
83
- - 6
84
- - 2
85
- version: 2.6.2
85
+ - 8
86
+ - 0
87
+ version: 2.8.0
86
88
  type: :development
87
89
  version_requirements: *id004
88
90
  description: 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.
@@ -142,6 +144,7 @@ files:
142
144
  - lib/arel/nodes/join.rb
143
145
  - lib/arel/nodes/less_than.rb
144
146
  - lib/arel/nodes/less_than_or_equal.rb
147
+ - lib/arel/nodes/limit.rb
145
148
  - lib/arel/nodes/lock.rb
146
149
  - lib/arel/nodes/matches.rb
147
150
  - lib/arel/nodes/max.rb
@@ -161,6 +164,7 @@ files:
161
164
  - lib/arel/nodes/string_join.rb
162
165
  - lib/arel/nodes/sum.rb
163
166
  - lib/arel/nodes/table_alias.rb
167
+ - lib/arel/nodes/top.rb
164
168
  - lib/arel/nodes/unary.rb
165
169
  - lib/arel/nodes/unqualified_column.rb
166
170
  - lib/arel/nodes/update_statement.rb
@@ -177,6 +181,7 @@ files:
177
181
  - lib/arel/visitors/depth_first.rb
178
182
  - lib/arel/visitors/dot.rb
179
183
  - lib/arel/visitors/join_sql.rb
184
+ - lib/arel/visitors/mssql.rb
180
185
  - lib/arel/visitors/mysql.rb
181
186
  - lib/arel/visitors/oracle.rb
182
187
  - lib/arel/visitors/order_clauses.rb
@@ -210,7 +215,9 @@ files:
210
215
  - test/test_table.rb
211
216
  - test/test_update_manager.rb
212
217
  - test/visitors/test_depth_first.rb
218
+ - test/visitors/test_dot.rb
213
219
  - test/visitors/test_join_sql.rb
220
+ - test/visitors/test_mssql.rb
214
221
  - test/visitors/test_mysql.rb
215
222
  - test/visitors/test_oracle.rb
216
223
  - test/visitors/test_postgres.rb
@@ -238,12 +245,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
238
245
  required_rubygems_version: !ruby/object:Gem::Requirement
239
246
  none: false
240
247
  requirements:
241
- - - ">="
248
+ - - ">"
242
249
  - !ruby/object:Gem::Version
243
- hash: 3
250
+ hash: 25
244
251
  segments:
245
- - 0
246
- version: "0"
252
+ - 1
253
+ - 3
254
+ - 1
255
+ version: 1.3.1
247
256
  requirements: []
248
257
 
249
258
  rubyforge_project: arel
@@ -275,7 +284,9 @@ test_files:
275
284
  - test/test_table.rb
276
285
  - test/test_update_manager.rb
277
286
  - test/visitors/test_depth_first.rb
287
+ - test/visitors/test_dot.rb
278
288
  - test/visitors/test_join_sql.rb
289
+ - test/visitors/test_mssql.rb
279
290
  - test/visitors/test_mysql.rb
280
291
  - test/visitors/test_oracle.rb
281
292
  - test/visitors/test_postgres.rb