lib/dynamoid/criteria/chain.rb in dynamoid-3.4.1 vs lib/dynamoid/criteria/chain.rb in dynamoid-3.5.0

- old
+ new

@@ -100,16 +100,16 @@ def delete_all ids = [] ranges = [] if @key_fields_detector.key_present? - Dynamoid.adapter.query(source.table_name, range_query).flat_map{ |i| i }.collect do |hash| + Dynamoid.adapter.query(source.table_name, range_query).flat_map { |i| i }.collect do |hash| ids << hash[source.hash_key.to_sym] ranges << hash[source.range_key.to_sym] if source.range_key end else - Dynamoid.adapter.scan(source.table_name, scan_query, scan_opts).flat_map{ |i| i }.collect do |hash| + Dynamoid.adapter.scan(source.table_name, scan_query, scan_opts).flat_map { |i| i }.collect do |hash| ids << hash[source.hash_key.to_sym] ranges << hash[source.range_key.to_sym] if source.range_key end end @@ -162,63 +162,88 @@ def project(*fields) @project = fields.map(&:to_sym) self end + def pluck(*args) + fields = args.map(&:to_sym) + @project = fields + + if fields.many? + items.map do |item| + fields.map { |key| Undumping.undump_field(item[key], source.attributes[key]) } + end.to_a + else + key = fields.first + items.map { |item| Undumping.undump_field(item[key], source.attributes[key]) }.to_a + end + end + private # The actual records referenced by the association. # # @return [Enumerator] an iterator of the found records. # # @since 0.2.0 def records - pages.lazy.flat_map { |i| i } + pages.lazy.flat_map { |items, _| items } end + # Raw items like they are stored before type casting + def items + raw_pages.lazy.flat_map { |items, _| items } + end + # Arrays of records, sized based on the actual pages produced by DynamoDB # # @return [Enumerator] an iterator of the found records. # # @since 3.1.0 def pages + raw_pages.lazy.map do |items, options| + models = items.map { |i| source.from_database(i) } + [models, options] + end.each + end + + # Pages of items before type casting + def raw_pages if @key_fields_detector.key_present? - pages_via_query + raw_pages_via_query else issue_scan_warning if Dynamoid::Config.warn_on_scan && query.present? - pages_via_scan + raw_pages_via_scan end end # If the query matches an index, we'll query the associated table to find results. # # @return [Enumerator] an iterator of the found pages. An array of records # # @since 3.1.0 - def pages_via_query + def raw_pages_via_query Enumerator.new do |y| Dynamoid.adapter.query(source.table_name, range_query).each do |items, metadata| - page = items.map { |h| source.from_database(h) } options = metadata.slice(:last_evaluated_key) - y.yield page, options + y.yield items, options end end end # If the query does not match an index, we'll manually scan the associated table to find results. # # @return [Enumerator] an iterator of the found pages. An array of records # # @since 3.1.0 - def pages_via_scan + def raw_pages_via_scan Enumerator.new do |y| Dynamoid.adapter.scan(source.table_name, scan_query, scan_opts).each do |items, metadata| - page = items.map { |h| source.from_database(h) } options = metadata.slice(:last_evaluated_key) - y.yield page, options + y.yield items, options end end end def issue_scan_warning @@ -330,10 +355,10 @@ end opts.merge(query_opts).merge(consistent_opts) end - # TODO casting should be operator aware + # TODO: casting should be operator aware # e.g. for NULL operator value should be boolean # and isn't related to an attribute own type def type_cast_condition_parameter(key, value) return value if %i[array set].include?(source.attributes[key.to_sym][:type])