1
1
module SQLTree ::Node
2
2
3
+ # The UpdateQuery class represents an SQL +UPDATE+ query.
4
+ #
5
+ # This root node has three children: +table+, +updates+ and +where+.
3
6
class UpdateQuery < Base
4
7
5
- attr_accessor :table , :updates , :where
8
+ # The table ({SQLTree::Node::TableReference}) to update.
9
+ attr_accessor :table
10
+
11
+ # The updates to do in the table. This is an array of
12
+ # {SQLTree::Node::UpdateQuery::Assignment} instances.
13
+ attr_accessor :updates
14
+
15
+ # The {SQLTree::Node::Expression} instance that restricts the records that
16
+ # should be updated.
17
+ attr_accessor :where
6
18
7
19
def initialize ( table , updates = [ ] , where = nil )
8
20
@table , @updates , @where = table , updates , where
9
21
end
10
22
23
+ # Generates the SQL UPDATE query.
24
+ # @return [String] The SQL update query
11
25
def to_sql
12
26
sql = "UPDATE #{ table . to_sql } SET "
13
27
sql << updates . map { |u | u . to_sql } . join ( ', ' )
14
28
sql << " WHERE " << where . to_sql if self . where
15
29
sql
16
30
end
17
31
32
+ # Parses an SQL UPDATE query. Syntax:
33
+ #
34
+ # UpdateQuery -> UPDATE TableReference
35
+ # SET Assignment (COMMA Assignment)*
36
+ # (WHERE Expression)?
37
+ #
38
+ # @param [SQLTree::Parser] tokens The token stream to parse from.
39
+ # @return [SQLTree::Node::UpdateQuery] The parsed UpdateQuery instance.
40
+ # @raise [SQLTree::Parser::UnexpectedToken] if an unexpected token is
41
+ # encountered during parsing.
18
42
def self . parse ( tokens )
19
43
tokens . consume ( SQLTree ::Token ::UPDATE )
20
44
update_query = self . new ( SQLTree ::Node ::TableReference . parse ( tokens ) )
21
45
tokens . consume ( SQLTree ::Token ::SET )
22
- update_query . updates = [ SQLTree ::Node ::Assignment . parse ( tokens ) ]
46
+ update_query . updates = [ SQLTree ::Node ::UpdateQuery :: Assignment . parse ( tokens ) ]
23
47
while SQLTree ::Token ::COMMA === tokens . peek
24
48
tokens . consume ( SQLTree ::Token ::COMMA )
25
- update_query . updates << SQLTree ::Node ::Assignment . parse ( tokens )
49
+ update_query . updates << SQLTree ::Node ::UpdateQuery :: Assignment . parse ( tokens )
26
50
end
27
51
28
52
if SQLTree ::Token ::WHERE === tokens . peek
@@ -32,5 +56,46 @@ def self.parse(tokens)
32
56
33
57
update_query
34
58
end
59
+
60
+ # The Assignment node is used to represent the assignment of a new
61
+ # value to a field in an +UPDATE+ query.
62
+ #
63
+ # This node has two children: <tt>field</tt> and <tt>expression</tt>.
64
+ class Assignment < Base
65
+
66
+ # The field ({SQLTree::Node::Expression::Field}) to update.
67
+ attr_accessor :field
68
+
69
+ # A {SQLTree::Node::Expression} instance that is used to
70
+ # update the field with.
71
+ attr_accessor :expression
72
+
73
+ # Initializes a new assignment node.
74
+ def initialize ( field , expression = nil )
75
+ @field , @expression = field , expression
76
+ end
77
+
78
+ # Generates an SQL fragment for this node.
79
+ # @return [String] An SQL fragment that can be embedded in the SET
80
+ # clause of on SQL UPDATE query.
81
+ def to_sql
82
+ "#{ field . to_sql } = #{ expression . to_sql } "
83
+ end
84
+
85
+ # Parses an Assignment node from a stream of tokens. Syntax:
86
+ #
87
+ # Assignment -> <identifier> EQ Expression
88
+ #
89
+ # @param [SQLTree::Parser] tokens The token stream to parse from.
90
+ # @return [SQLTree::Node::Assignment] The parsed assignment instance.
91
+ # @raise [SQLTree::Parser::UnexpectedToken] if an unexpected token is
92
+ # encountered during parsing.
93
+ def self . parse ( tokens )
94
+ assignment = self . new ( SQLTree ::Node ::Expression ::Field . parse ( tokens ) )
95
+ tokens . consume ( SQLTree ::Token ::EQ )
96
+ assignment . expression = SQLTree ::Node ::Expression . parse ( tokens )
97
+ assignment
98
+ end
99
+ end
35
100
end
36
101
end
0 commit comments