module SQLTree::Node # The UpdateQuery class represents an SQL +UPDATE+ query. # # This root node has three children: +table+, +updates+ and +where+. class UpdateQuery < Base # The table ({SQLTree::Node::TableReference}) to update. child :table # The updates to do in the table. This is an array of # {SQLTree::Node::UpdateQuery::Assignment} instances. child :updates # The {SQLTree::Node::Expression} instance that restricts the records that # should be updated. child :where def initialize(table, updates = [], where = nil) @table, @updates, @where = table, updates, where end # Generates the SQL UPDATE query. # @return [String] The SQL update query def to_sql(options = {}) sql = "UPDATE #{table.to_sql(options)} SET " sql << updates.map { |u| u.to_sql(options) }.join(', ') sql << " WHERE " << where.to_sql(options) if self.where sql end # Parses an SQL UPDATE query. Syntax: # # UpdateQuery -> UPDATE TableReference # SET Assignment (COMMA Assignment)* # (WHERE Expression)? # # @param [SQLTree::Parser] tokens The token stream to parse from. # @return [SQLTree::Node::UpdateQuery] The parsed UpdateQuery instance. # @raise [SQLTree::Parser::UnexpectedToken] if an unexpected token is # encountered during parsing. def self.parse(tokens) tokens.consume(SQLTree::Token::UPDATE) update_query = self.new(SQLTree::Node::TableReference.parse(tokens)) tokens.consume(SQLTree::Token::SET) update_query.updates = parse_list(tokens, SQLTree::Node::UpdateQuery::Assignment) if SQLTree::Token::WHERE === tokens.peek tokens.consume(SQLTree::Token::WHERE) update_query.where = SQLTree::Node::Expression.parse(tokens) end update_query end # The Assignment node is used to represent the assignment of a new # value to a field in an +UPDATE+ query. # # This node has two children: field and expression. class Assignment < Base # The field ({SQLTree::Node::Expression::Field}) to update. child :field # A {SQLTree::Node::Expression} instance that is used to # update the field with. child :expression # Initializes a new assignment node. def initialize(field, expression = nil) @field, @expression = field, expression end # Generates an SQL fragment for this node. # @return [String] An SQL fragment that can be embedded in the SET # clause of on SQL UPDATE query. def to_sql(options = {}) "#{field.to_sql(options)} = #{expression.to_sql(options)}" end # Parses an Assignment node from a stream of tokens. Syntax: # # Assignment -> EQ Expression # # @param [SQLTree::Parser] tokens The token stream to parse from. # @return [SQLTree::Node::Assignment] The parsed assignment instance. # @raise [SQLTree::Parser::UnexpectedToken] if an unexpected token is # encountered during parsing. def self.parse(tokens) assignment = self.new(SQLTree::Node::Expression::Field.parse(tokens)) tokens.consume(SQLTree::Token::EQ) assignment.expression = SQLTree::Node::Expression.parse(tokens) assignment end end end end