lib/cequel/metal/updater.rb
# -*- encoding : utf-8 -*-
module Cequel
module Metal
#
# Builder for `UPDATE` statement containing heterogeneous operations (set
# columns, atomically mutate collections)
#
# @see DataSet#update
# @see Deleter
# @see
# http://cassandra.apache.org/doc/cql3/CQL.html#updateStmt
# CQL UPDATE documentation
# @since 1.0.0
#
class Updater < Writer
#
# @see Writer#initialize
#
def initialize(*)
@column_updates = {}
super
end
#
# Directly set column values
#
# @param data [Hash] map of column names to values
# @return [void]
#
# @see DataSet#update
#
def set(data)
data.each_pair do |column, value|
column_updates[column.to_sym] = value
end
end
#
# Prepend elements to a list column
#
# @param column [Symbol] column name
# @param elements [Array<Object>] elements to prepend
# @return [void]
#
# @see DataSet#list_prepend
#
def list_prepend(column, elements)
elements = Array(elements)
statements << "#{column} = ? + #{column}"
bind_vars << elements
end
#
# Append elements to a list column
#
# @param column [Symbol] column name
# @param elements [Array] elements to append
# @return [void]
#
# @see DataSet#list_append
#
def list_append(column, elements)
elements = Array(elements)
statements << "#{column} = #{column} + ?"
bind_vars << elements
end
#
# Remove all occurrences of an element from a list
#
# @param column [Symbol] column name
# @param value value to remove
# @return [void]
#
# @see DataSet#list_remove
#
def list_remove(column, value)
value = Array(value)
statements << "#{column} = #{column} - ?"
bind_vars << value
end
#
# Replace a list item at a given position
#
# @param column [Symbol] column name
# @param index [Integer] index at which to replace value
# @param value new value for position
# @return [void]
#
# @see DataSet#list_replace
#
def list_replace(column, index, value)
statements << "#{column}[#{index}] = ?"
bind_vars << value
end
#
# Add elements to a set
#
# @param column [Symbol] column name
# @param values [Set] elements to add to set
# @return [void]
#
# @see DataSet#set_add
#
def set_add(column, values)
statements << "#{column} = #{column} + ?"
bind_vars << Set.new(::Kernel.Array(values))
end
#
# Remove elements from a set
#
# @param column [Symbol] column name
# @param values [Set] elements to remove from set
# @return [void]
#
# @see DataSet#set_remove
#
def set_remove(column, values)
statements << "#{column} = #{column} - ?"
bind_vars << Set.new(::Kernel.Array(values))
end
#
# Add or update elements in a map
#
# @param column [Symbol] column name
# @param updates [Hash] map of keys to values to update in map
# @return [void]
#
# @see DataSet#map_update
#
def map_update(column, updates)
statements << "#{column} = #{column} + ?"
bind_vars << updates
end
private
attr_reader :column_updates
def empty?
super && column_updates.empty?
end
def write_to_statement(statement, options)
all_statements, all_bind_vars = statements_with_column_updates
statement.append("UPDATE #{table_name}")
.append(generate_upsert_options(options))
.append(" SET ")
.append(all_statements.join(', '), *all_bind_vars)
end
def statements_with_column_updates
all_statements, all_bind_vars = statements.dup, bind_vars.dup
column_updates.each_pair do |column, value|
prepare_upsert_value(value) do |binding, *values|
all_statements << "#{column} = #{binding}"
all_bind_vars.concat(values)
end
end
[all_statements, all_bind_vars]
end
end
end
end