arel 2.0.10 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. data/History.txt +51 -4
  2. data/Manifest.txt +15 -31
  3. data/README.markdown +27 -3
  4. data/Rakefile +0 -2
  5. data/arel.gemspec +20 -19
  6. data/lib/arel.rb +9 -1
  7. data/lib/arel/alias_predication.rb +7 -0
  8. data/lib/arel/attributes/attribute.rb +10 -1
  9. data/lib/arel/crud.rb +43 -8
  10. data/lib/arel/expression.rb +1 -0
  11. data/lib/arel/factory_methods.rb +35 -0
  12. data/lib/arel/insert_manager.rb +5 -1
  13. data/lib/arel/math.rb +19 -0
  14. data/lib/arel/nodes.rb +32 -42
  15. data/lib/arel/nodes/and.rb +18 -1
  16. data/lib/arel/nodes/binary.rb +28 -0
  17. data/lib/arel/nodes/count.rb +0 -3
  18. data/lib/arel/nodes/function.rb +13 -2
  19. data/lib/arel/nodes/infix_operation.rb +43 -0
  20. data/lib/arel/nodes/join_source.rb +14 -0
  21. data/lib/arel/nodes/named_function.rb +14 -0
  22. data/lib/arel/nodes/node.rb +5 -2
  23. data/lib/arel/nodes/select_core.rb +24 -10
  24. data/lib/arel/nodes/select_statement.rb +8 -6
  25. data/lib/arel/nodes/sql_literal.rb +2 -0
  26. data/lib/arel/nodes/string_join.rb +2 -4
  27. data/lib/arel/nodes/table_alias.rb +7 -3
  28. data/lib/arel/nodes/{as.rb → terminal.rb} +1 -1
  29. data/lib/arel/nodes/unary.rb +17 -0
  30. data/lib/arel/nodes/unqualified_column.rb +4 -0
  31. data/lib/arel/nodes/update_statement.rb +4 -2
  32. data/lib/arel/nodes/with.rb +10 -0
  33. data/lib/arel/order_predications.rb +13 -0
  34. data/lib/arel/predications.rb +6 -24
  35. data/lib/arel/select_manager.rb +95 -40
  36. data/lib/arel/table.rb +32 -19
  37. data/lib/arel/tree_manager.rb +1 -0
  38. data/lib/arel/update_manager.rb +4 -0
  39. data/lib/arel/visitors.rb +2 -0
  40. data/lib/arel/visitors/depth_first.rb +19 -9
  41. data/lib/arel/visitors/dot.rb +42 -25
  42. data/lib/arel/visitors/ibm_db.rb +12 -0
  43. data/lib/arel/visitors/join_sql.rb +2 -23
  44. data/lib/arel/visitors/mssql.rb +7 -0
  45. data/lib/arel/visitors/mysql.rb +4 -0
  46. data/lib/arel/visitors/oracle.rb +2 -2
  47. data/lib/arel/visitors/postgresql.rb +2 -38
  48. data/lib/arel/visitors/to_sql.rb +148 -67
  49. data/test/attributes/test_attribute.rb +3 -3
  50. data/test/helper.rb +1 -1
  51. data/test/nodes/test_as.rb +6 -0
  52. data/test/nodes/test_bin.rb +23 -0
  53. data/test/nodes/test_named_function.rb +30 -0
  54. data/test/nodes/test_node.rb +10 -0
  55. data/test/nodes/test_not.rb +4 -7
  56. data/test/nodes/test_select_core.rb +23 -14
  57. data/test/support/fake_record.rb +21 -4
  58. data/test/test_attributes.rb +8 -0
  59. data/test/test_crud.rb +6 -12
  60. data/test/test_factory_methods.rb +34 -0
  61. data/test/test_insert_manager.rb +19 -0
  62. data/test/test_select_manager.rb +343 -64
  63. data/test/test_table.rb +36 -45
  64. data/test/visitors/test_depth_first.rb +29 -11
  65. data/test/visitors/test_dot.rb +47 -0
  66. data/test/visitors/test_ibm_db.rb +27 -0
  67. data/test/visitors/test_join_sql.rb +14 -7
  68. data/test/visitors/test_mssql.rb +9 -0
  69. data/test/visitors/test_oracle.rb +11 -10
  70. data/test/visitors/test_postgres.rb +12 -0
  71. data/test/visitors/test_to_sql.rb +80 -17
  72. metadata +80 -101
  73. data/lib/arel/nodes/assignment.rb +0 -6
  74. data/lib/arel/nodes/avg.rb +0 -6
  75. data/lib/arel/nodes/between.rb +0 -6
  76. data/lib/arel/nodes/does_not_match.rb +0 -6
  77. data/lib/arel/nodes/except.rb +0 -7
  78. data/lib/arel/nodes/exists.rb +0 -7
  79. data/lib/arel/nodes/greater_than.rb +0 -6
  80. data/lib/arel/nodes/greater_than_or_equal.rb +0 -6
  81. data/lib/arel/nodes/group.rb +0 -6
  82. data/lib/arel/nodes/grouping.rb +0 -6
  83. data/lib/arel/nodes/having.rb +0 -6
  84. data/lib/arel/nodes/intersect.rb +0 -7
  85. data/lib/arel/nodes/join.rb +0 -13
  86. data/lib/arel/nodes/less_than.rb +0 -6
  87. data/lib/arel/nodes/less_than_or_equal.rb +0 -6
  88. data/lib/arel/nodes/limit.rb +0 -7
  89. data/lib/arel/nodes/lock.rb +0 -6
  90. data/lib/arel/nodes/matches.rb +0 -6
  91. data/lib/arel/nodes/max.rb +0 -6
  92. data/lib/arel/nodes/min.rb +0 -6
  93. data/lib/arel/nodes/not.rb +0 -6
  94. data/lib/arel/nodes/not_equal.rb +0 -6
  95. data/lib/arel/nodes/not_in.rb +0 -6
  96. data/lib/arel/nodes/offset.rb +0 -7
  97. data/lib/arel/nodes/on.rb +0 -6
  98. data/lib/arel/nodes/or.rb +0 -6
  99. data/lib/arel/nodes/sum.rb +0 -6
  100. data/lib/arel/nodes/top.rb +0 -6
  101. data/lib/arel/nodes/union.rb +0 -7
  102. data/lib/arel/nodes/union_all.rb +0 -7
@@ -27,8 +27,12 @@ module Arel
27
27
  @ast.columns << column
28
28
  values << value
29
29
  end
30
- @ast.values = Nodes::Values.new values, @ast.columns
30
+ @ast.values = create_values values, @ast.columns
31
31
  end
32
32
  end
33
+
34
+ def create_values values, columns
35
+ Nodes::Values.new values, columns
36
+ end
33
37
  end
34
38
  end
@@ -0,0 +1,19 @@
1
+ module Arel
2
+ module Math
3
+ def *(other)
4
+ Arel::Nodes::Multiplication.new(self, other)
5
+ end
6
+
7
+ def +(other)
8
+ Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new(self, other))
9
+ end
10
+
11
+ def -(other)
12
+ Arel::Nodes::Grouping.new(Arel::Nodes::Subtraction.new(self, other))
13
+ end
14
+
15
+ def /(other)
16
+ Arel::Nodes::Division.new(self, other)
17
+ end
18
+ end
19
+ end
@@ -1,53 +1,43 @@
1
+ # node
1
2
  require 'arel/nodes/node'
3
+ require 'arel/nodes/select_statement'
4
+ require 'arel/nodes/select_core'
5
+ require 'arel/nodes/insert_statement'
6
+ require 'arel/nodes/update_statement'
7
+
8
+ # terminal
9
+
10
+ require 'arel/nodes/terminal'
11
+
12
+ # unary
2
13
  require 'arel/nodes/unary'
14
+ require 'arel/nodes/unqualified_column'
15
+ require 'arel/nodes/with'
16
+
17
+ # binary
3
18
  require 'arel/nodes/binary'
4
19
  require 'arel/nodes/equality'
5
- require 'arel/nodes/between'
6
- require 'arel/nodes/not_equal'
7
- require 'arel/nodes/assignment'
8
- require 'arel/nodes/or'
9
- require 'arel/nodes/and'
10
- require 'arel/nodes/as'
11
- require 'arel/nodes/not'
12
- require 'arel/nodes/greater_than'
13
- require 'arel/nodes/greater_than_or_equal'
14
- require 'arel/nodes/less_than'
15
- require 'arel/nodes/less_than_or_equal'
16
- require 'arel/nodes/matches'
17
- require 'arel/nodes/does_not_match'
18
-
19
- require 'arel/nodes/in'
20
- require 'arel/nodes/not_in'
20
+ require 'arel/nodes/in' # Why is this subclassed from equality?
21
+ require 'arel/nodes/join_source'
21
22
  require 'arel/nodes/ordering'
22
- require 'arel/nodes/lock'
23
+ require 'arel/nodes/delete_statement'
24
+ require 'arel/nodes/table_alias'
25
+ require 'arel/nodes/infix_operation'
26
+
27
+ # nary
28
+ require 'arel/nodes/and'
29
+
30
+ # function
31
+ # FIXME: Function + Alias can be rewritten as a Function and Alias node.
32
+ # We should make Function a Unary node and deprecate the use of "aliaz"
23
33
  require 'arel/nodes/function'
24
34
  require 'arel/nodes/count'
25
35
  require 'arel/nodes/values'
26
- require 'arel/nodes/offset'
27
- require 'arel/nodes/limit'
28
- require 'arel/nodes/top'
29
- require 'arel/nodes/sum'
30
- require 'arel/nodes/exists'
31
- require 'arel/nodes/max'
32
- require 'arel/nodes/min'
33
- require 'arel/nodes/avg'
34
- require 'arel/nodes/having'
35
- require 'arel/nodes/sql_literal'
36
- require 'arel/nodes/select_core'
37
- require 'arel/nodes/select_statement'
38
- require 'arel/nodes/insert_statement'
39
- require 'arel/nodes/update_statement'
40
- require 'arel/nodes/delete_statement'
41
- require 'arel/nodes/unqualified_column'
42
- require 'arel/nodes/table_alias'
43
- require 'arel/nodes/join'
44
- require 'arel/nodes/group'
45
- require 'arel/nodes/grouping'
36
+ require 'arel/nodes/named_function'
37
+
38
+ # joins
46
39
  require 'arel/nodes/inner_join'
47
40
  require 'arel/nodes/outer_join'
48
41
  require 'arel/nodes/string_join'
49
- require 'arel/nodes/on'
50
- require 'arel/nodes/except'
51
- require 'arel/nodes/intersect'
52
- require 'arel/nodes/union'
53
- require 'arel/nodes/union_all'
42
+
43
+ require 'arel/nodes/sql_literal'
@@ -1,6 +1,23 @@
1
1
  module Arel
2
2
  module Nodes
3
- class And < Arel::Nodes::Binary
3
+ class And < Arel::Nodes::Node
4
+ attr_reader :children
5
+
6
+ def initialize children, right = nil
7
+ unless Array === children
8
+ warn "(#{caller.first}) AND nodes should be created with a list"
9
+ children = [children, right]
10
+ end
11
+ @children = children
12
+ end
13
+
14
+ def left
15
+ children.first
16
+ end
17
+
18
+ def right
19
+ children[1]
20
+ end
4
21
  end
5
22
  end
6
23
  end
@@ -7,6 +7,34 @@ module Arel
7
7
  @left = left
8
8
  @right = right
9
9
  end
10
+
11
+ def initialize_copy other
12
+ super
13
+ @left = @left.clone if @left
14
+ @right = @right.clone if @right
15
+ end
16
+ end
17
+
18
+ %w{
19
+ As
20
+ Assignment
21
+ Between
22
+ DoesNotMatch
23
+ GreaterThan
24
+ GreaterThanOrEqual
25
+ Join
26
+ LessThan
27
+ LessThanOrEqual
28
+ Matches
29
+ NotEqual
30
+ NotIn
31
+ Or
32
+ Union
33
+ UnionAll
34
+ Intersect
35
+ Except
36
+ }.each do |name|
37
+ const_set name, Class.new(Binary)
10
38
  end
11
39
  end
12
40
  end
@@ -1,9 +1,6 @@
1
1
  module Arel
2
2
  module Nodes
3
3
  class Count < Arel::Nodes::Function
4
-
5
- attr_accessor :distinct
6
-
7
4
  def initialize expr, distinct = false, aliaz = nil
8
5
  super(expr, aliaz)
9
6
  @distinct = distinct
@@ -2,11 +2,12 @@ module Arel
2
2
  module Nodes
3
3
  class Function < Arel::Nodes::Node
4
4
  include Arel::Expression
5
- attr_accessor :expressions, :alias
5
+ attr_accessor :expressions, :alias, :distinct
6
6
 
7
7
  def initialize expr, aliaz = nil
8
8
  @expressions = expr
9
- @alias = aliaz
9
+ @alias = aliaz && SqlLiteral.new(aliaz)
10
+ @distinct = false
10
11
  end
11
12
 
12
13
  def as aliaz
@@ -14,5 +15,15 @@ module Arel
14
15
  self
15
16
  end
16
17
  end
18
+
19
+ %w{
20
+ Sum
21
+ Exists
22
+ Max
23
+ Min
24
+ Avg
25
+ }.each do |name|
26
+ const_set(name, Class.new(Function))
27
+ end
17
28
  end
18
29
  end
@@ -0,0 +1,43 @@
1
+ module Arel
2
+ module Nodes
3
+
4
+ class InfixOperation < Binary
5
+ include Arel::Expressions
6
+ include Arel::Predications
7
+ include Arel::AliasPredication
8
+ include Arel::Math
9
+
10
+ attr_reader :operator
11
+
12
+ def initialize operator, left, right
13
+ super(left, right)
14
+ @operator = operator
15
+ end
16
+ end
17
+
18
+ class Multiplication < InfixOperation
19
+ def initialize left, right
20
+ super(:*, left, right)
21
+ end
22
+ end
23
+
24
+ class Division < InfixOperation
25
+ def initialize left, right
26
+ super(:/, left, right)
27
+ end
28
+ end
29
+
30
+ class Addition < InfixOperation
31
+ def initialize left, right
32
+ super(:+, left, right)
33
+ end
34
+ end
35
+
36
+ class Subtraction < InfixOperation
37
+ def initialize left, right
38
+ super(:-, left, right)
39
+ end
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,14 @@
1
+ module Arel
2
+ module Nodes
3
+ ###
4
+ # Class that represents a join source
5
+ #
6
+ # http://www.sqlite.org/syntaxdiagrams.html#join-source
7
+
8
+ class JoinSource < Arel::Nodes::Binary
9
+ def initialize single_source, joinop = []
10
+ super
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ module Arel
2
+ module Nodes
3
+ class NamedFunction < Arel::Nodes::Function
4
+ attr_accessor :name
5
+
6
+ include Arel::Predications
7
+
8
+ def initialize name, expr, aliaz = nil
9
+ super(expr, aliaz)
10
+ @name = name
11
+ end
12
+ end
13
+ end
14
+ end
@@ -3,11 +3,14 @@ module Arel
3
3
  ###
4
4
  # Abstract base class for all AST nodes
5
5
  class Node
6
+ include Arel::FactoryMethods
7
+ include Enumerable
8
+
6
9
  ###
7
10
  # Factory method to create a Nodes::Not node that has the recipient of
8
11
  # the caller as a child.
9
12
  def not
10
- Nodes::Not.new Nodes::Grouping.new self
13
+ Nodes::Not.new self
11
14
  end
12
15
 
13
16
  ###
@@ -20,7 +23,7 @@ module Arel
20
23
  ###
21
24
  # Factory method to create an Nodes::And node.
22
25
  def and right
23
- Nodes::And.new self, right
26
+ Nodes::And.new [self, right]
24
27
  end
25
28
 
26
29
  # FIXME: this method should go away. I don't like people calling
@@ -1,24 +1,38 @@
1
1
  module Arel
2
2
  module Nodes
3
3
  class SelectCore < Arel::Nodes::Node
4
- attr_accessor :top, :froms, :projections, :wheres, :groups
5
- attr_accessor :having
4
+ attr_accessor :top, :projections, :wheres, :groups
5
+ attr_accessor :having, :source, :set_quantifier
6
6
 
7
7
  def initialize
8
- @top = nil
9
- @froms = nil
10
- @projections = []
11
- @wheres = []
12
- @groups = []
13
- @having = nil
8
+ @source = JoinSource.new nil
9
+ @top = nil
10
+
11
+ # http://savage.net.au/SQL/sql-92.bnf.html#set%20quantifier
12
+ @set_quantifier = nil
13
+ @projections = []
14
+ @wheres = []
15
+ @groups = []
16
+ @having = nil
17
+ end
18
+
19
+ def from
20
+ @source.left
14
21
  end
15
22
 
23
+ def from= value
24
+ @source.left = value
25
+ end
26
+
27
+ alias :froms= :from=
28
+ alias :froms :from
29
+
16
30
  def initialize_copy other
17
31
  super
18
- @froms = @froms.clone if @froms
32
+ @source = @source.clone if @source
19
33
  @projections = @projections.clone
20
34
  @wheres = @wheres.clone
21
- @group = @groups.clone
35
+ @groups = @groups.clone
22
36
  @having = @having.clone if @having
23
37
  end
24
38
  end
@@ -2,14 +2,16 @@ module Arel
2
2
  module Nodes
3
3
  class SelectStatement < Arel::Nodes::Node
4
4
  attr_reader :cores
5
- attr_accessor :limit, :orders, :lock, :offset
5
+ attr_accessor :limit, :orders, :lock, :offset, :with
6
6
 
7
7
  def initialize cores = [SelectCore.new]
8
- @cores = cores
9
- @orders = []
10
- @limit = nil
11
- @lock = nil
12
- @offset = nil
8
+ #puts caller
9
+ @cores = cores
10
+ @orders = []
11
+ @limit = nil
12
+ @lock = nil
13
+ @offset = nil
14
+ @with = nil
13
15
  end
14
16
 
15
17
  def initialize_copy other
@@ -3,6 +3,8 @@ module Arel
3
3
  class SqlLiteral < String
4
4
  include Arel::Expressions
5
5
  include Arel::Predications
6
+ include Arel::AliasPredication
7
+ include Arel::OrderPredications
6
8
  end
7
9
  end
8
10
  end
@@ -1,10 +1,8 @@
1
1
  module Arel
2
2
  module Nodes
3
3
  class StringJoin < Arel::Nodes::Join
4
- undef :constraint
5
-
6
- def initialize left, right
7
- super(left, right, nil)
4
+ def initialize left, right = nil
5
+ super
8
6
  end
9
7
  end
10
8
  end
@@ -1,12 +1,16 @@
1
1
  module Arel
2
2
  module Nodes
3
3
  class TableAlias < Arel::Nodes::Binary
4
- alias :name :left
5
- alias :relation :right
4
+ alias :name :right
5
+ alias :relation :left
6
6
  alias :table_alias :name
7
7
 
8
8
  def [] name
9
- Attribute.new self, name
9
+ Attribute.new(self, name)
10
+ end
11
+
12
+ def table_name
13
+ relation.name
10
14
  end
11
15
  end
12
16
  end
@@ -1,6 +1,6 @@
1
1
  module Arel
2
2
  module Nodes
3
- class As < Arel::Nodes::Binary
3
+ class Distinct < Arel::Nodes::Node
4
4
  end
5
5
  end
6
6
  end