arel 2.0.10 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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