lib/dynamoid/adapter_plugin/aws_sdk_v3/filter_expression_convertor.rb
# frozen_string_literal: true
module Dynamoid
# @private
module AdapterPlugin
class AwsSdkV3
class FilterExpressionConvertor
attr_reader :expression, :name_placeholders, :value_placeholders
def initialize(conditions, name_placeholders, value_placeholders, name_placeholder_sequence, value_placeholder_sequence)
@conditions = conditions
@name_placeholders = name_placeholders.dup
@value_placeholders = value_placeholders.dup
@name_placeholder_sequence = name_placeholder_sequence
@value_placeholder_sequence = value_placeholder_sequence
build
end
private
def build
clauses = @conditions.map do |name, attribute_conditions|
attribute_conditions.map do |operator, value|
name_or_placeholder = name_or_placeholder_for(name)
case operator
when :eq
"#{name_or_placeholder} = #{value_placeholder_for(value)}"
when :ne
"#{name_or_placeholder} <> #{value_placeholder_for(value)}"
when :gt
"#{name_or_placeholder} > #{value_placeholder_for(value)}"
when :lt
"#{name_or_placeholder} < #{value_placeholder_for(value)}"
when :gte
"#{name_or_placeholder} >= #{value_placeholder_for(value)}"
when :lte
"#{name_or_placeholder} <= #{value_placeholder_for(value)}"
when :between
"#{name_or_placeholder} BETWEEN #{value_placeholder_for(value[0])} AND #{value_placeholder_for(value[1])}"
when :begins_with
"begins_with (#{name_or_placeholder}, #{value_placeholder_for(value)})"
when :in
list = value.map(&method(:value_placeholder_for)).join(' , ')
"#{name_or_placeholder} IN (#{list})"
when :contains
"contains (#{name_or_placeholder}, #{value_placeholder_for(value)})"
when :not_contains
"NOT contains (#{name_or_placeholder}, #{value_placeholder_for(value)})"
when :null
"attribute_not_exists (#{name_or_placeholder})"
when :not_null
"attribute_exists (#{name_or_placeholder})"
end
end
end.flatten
@expression = clauses.join(' AND ')
end
def name_or_placeholder_for(name)
return name unless name.upcase.in?(Dynamoid::AdapterPlugin::AwsSdkV3::RESERVED_WORDS)
placeholder = @name_placeholder_sequence.call
@name_placeholders[placeholder] = name
placeholder
end
def value_placeholder_for(value)
placeholder = @value_placeholder_sequence.call
@value_placeholders[placeholder] = value
placeholder
end
end
end
end
end