lib/cequel/metal/writer.rb
# -*- encoding : utf-8 -*-
module Cequel
module Metal
#
# Internal representation of a data manipulation statement
#
# @abstract Subclasses must implement #write_to_statement, which writes
# internal state to a Statement instance
#
# @since 1.0.0
# @api private
#
class Writer
extend Util::Forwardable
attr_accessor :type_hints
#
# @param data_set [DataSet] data set to write to
#
def initialize(data_set, &block)
@data_set, @options, @block = data_set, options, block
@statements, @bind_vars = [], []
SimpleDelegator.new(self).instance_eval(&block) if block
end
#
# Execute the statement as a write operation
#
# @param options [Options] options
# @option options [Symbol] :consistency what consistency level to use for
# the operation
# @option options [Integer] :ttl time-to-live in seconds for the written
# data
# @option options [Time,Integer] :timestamp the timestamp associated with
# the column values
# @return [void]
#
def execute(options = {})
options.assert_valid_keys(:timestamp, :ttl, :consistency)
return if empty?
statement = Statement.new
consistency = options.fetch(:consistency, data_set.query_consistency)
write_to_statement(statement, options)
statement.append(*data_set.row_specifications_cql)
data_set.write_with_options(statement,
consistency: consistency)
end
private
attr_reader :data_set, :options, :statements, :bind_vars
def_delegator :data_set, :table_name
def_delegator :statements, :empty?
def prepare_upsert_value(value)
yield '?', value
end
#
# Generate CQL option statement for inserts and updates
#
def generate_upsert_options(options)
upsert_options = options.slice(:timestamp, :ttl)
if upsert_options.empty?
''
else
' USING ' <<
upsert_options.map do |key, value|
serialized_value =
case key
when :timestamp then (value.to_f * 1_000_000).to_i
else value
end
"#{key.to_s.upcase} #{serialized_value}"
end.join(' AND ')
end
end
end
end
end