lib/dynamoid/criteria/chain.rb in dynamoid-2.2.0 vs lib/dynamoid/criteria/chain.rb in dynamoid-3.0.0
- old
+ new
@@ -1,14 +1,12 @@
-# encoding: utf-8
+# frozen_string_literal: true
+
module Dynamoid #:nodoc:
module Criteria
-
# The criteria chain is equivalent to an ActiveRecord relation (and realistically I should change the name from
# chain to relation). It is a chainable object that builds up a query and eventually executes it by a Query or Scan.
class Chain
- # TODO: Should we transform any other types of query values?
- TYPES_TO_DUMP_FOR_QUERY = [:string, :integer, :boolean, :serialized]
attr_accessor :query, :source, :values, :consistent_read
attr_reader :hash_key, :range_key, :index_name
include Enumerable
# Create a new criteria chain.
#
@@ -35,18 +33,11 @@
# @example A more complicated criteria
# where(:name => 'Josh', 'created_at.gt' => DateTime.now - 1.day)
#
# @since 0.2.0
def where(args)
- args.each do |k, v|
- sym = k.to_sym
- query[sym] = if (field_options = source.attributes[sym]) && (type = field_options[:type]) && TYPES_TO_DUMP_FOR_QUERY.include?(type)
- source.dump_field(v, field_options)
- else
- v
- end
- end
+ query.update(args.dup.symbolize_keys)
self
end
def consistent
@consistent_read = true
@@ -77,22 +68,20 @@
if key_present?
Dynamoid.adapter.query(source.table_name, range_query).collect do |hash|
ids << hash[source.hash_key.to_sym]
ranges << hash[source.range_key.to_sym] if source.range_key
end
-
- Dynamoid.adapter.delete(source.table_name, ids, range_key: ranges.presence)
else
Dynamoid.adapter.scan(source.table_name, scan_query, scan_opts).collect do |hash|
ids << hash[source.hash_key.to_sym]
ranges << hash[source.range_key.to_sym] if source.range_key
end
-
- Dynamoid.adapter.delete(source.table_name, ids, range_key: ranges.presence)
end
+
+ Dynamoid.adapter.delete(source.table_name, ids, range_key: ranges.presence)
end
- alias_method :destroy_all, :delete_all
+ alias destroy_all delete_all
# The record limit is the limit of evaluated records returned by the
# query or scan.
def record_limit(limit)
@record_limit = limit
@@ -157,16 +146,16 @@
#
# @return [Enumerator] an iterator of the found records.
#
# @since 0.2.0
def records_via_scan
- if Dynamoid::Config.warn_on_scan
+ if Dynamoid::Config.warn_on_scan && query.present?
Dynamoid.logger.warn 'Queries without an index are forced to use scan and are generally much slower than indexed queries!'
Dynamoid.logger.warn "You can index this query by adding index declaration to #{source.to_s.downcase}.rb:"
Dynamoid.logger.warn "* global_secondary_index hash_key: 'some-name', range_key: 'some-another-name'"
Dynamoid.logger.warn "* local_secondary_indexe range_key: 'some-name'"
- Dynamoid.logger.warn "Not indexed attributes: #{query.keys.sort.collect{|name| ":#{name}"}.join(', ')}"
+ Dynamoid.logger.warn "Not indexed attributes: #{query.keys.sort.collect { |name| ":#{name}" }.join(', ')}"
end
Enumerator.new do |yielder|
Dynamoid.adapter.scan(source.table_name, scan_query, scan_opts).each do |hash|
yielder.yield source.from_database(hash)
@@ -197,33 +186,33 @@
def field_hash(key)
name, operation = key.to_s.split('.')
val = type_cast_condition_parameter(name, query[key])
hash = case operation
- when 'ne'
- { ne: val }
- when 'gt'
- { gt: val }
- when 'lt'
- { lt: val }
- when 'gte'
- { gte: val }
- when 'lte'
- { lte: val }
- when 'between'
- { between: val }
- when 'begins_with'
- { begins_with: val }
- when 'in'
- { in: val }
- when 'contains'
- { contains: val }
- when 'not_contains'
- { not_contains: val }
- end
+ when 'ne'
+ { ne: val }
+ when 'gt'
+ { gt: val }
+ when 'lt'
+ { lt: val }
+ when 'gte'
+ { gte: val }
+ when 'lte'
+ { lte: val }
+ when 'between'
+ { between: val }
+ when 'begins_with'
+ { begins_with: val }
+ when 'in'
+ { in: val }
+ when 'contains'
+ { contains: val }
+ when 'not_contains'
+ { not_contains: val }
+ end
- return { name.to_sym => hash }
+ { name.to_sym => hash }
end
def consistent_opts
{ consistent_read: consistent_read }
end
@@ -253,24 +242,30 @@
.each do |key|
if key.to_s.include?('.')
opts.update(field_hash(key))
else
value = type_cast_condition_parameter(key, query[key])
- opts[key] = {eq: value}
+ opts[key] = { eq: value }
end
end
opts.merge(query_opts).merge(consistent_opts)
end
def type_cast_condition_parameter(key, value)
- return value if [:array, :set].include?(source.attributes[key.to_sym][:type])
+ return value if %i[array set].include?(source.attributes[key.to_sym][:type])
if !value.respond_to?(:to_ary)
- source.dump_field(value, source.attributes[key.to_sym])
+ options = source.attributes[key.to_sym]
+ value_casted = TypeCasting.cast_field(value, options)
+ Dumping.dump_field(value_casted, options)
else
- value.to_ary.map { |el| source.dump_field(el, source.attributes[key.to_sym]) }
+ value.to_ary.map do |el|
+ options = source.attributes[key.to_sym]
+ value_casted = TypeCasting.cast_field(el, options)
+ Dumping.dump_field(value_casted, options)
+ end
end
end
def key_present?
query_keys = query.keys.collect { |k| k.to_s.split('.').first }
@@ -352,11 +347,11 @@
query.keys.map(&:to_sym).each do |key|
if key.to_s.include?('.')
opts.update(field_hash(key))
else
value = type_cast_condition_parameter(key, query[key])
- opts[key] = {eq: value}
+ opts[key] = { eq: value }
end
end
end
end
@@ -368,9 +363,7 @@
opts[:exclusive_start_key] = start_key if @start
opts[:consistent_read] = true if @consistent_read
opts
end
end
-
end
-
end