lib/marc/spec/queries/query.rb in ruby-marc-spec-0.1.1 vs lib/marc/spec/queries/query.rb in ruby-marc-spec-0.1.2

- old
+ new

@@ -1,5 +1,6 @@ +require 'marc/spec/parsing/parser' require 'marc/spec/queries/part' module MARC module Spec module Queries @@ -31,22 +32,21 @@ end.string end # TODO: don't support nested subqueries def execute(executor, context_fields, context_result = nil) - fields = tag ? executor.apply_tag(tag) : context_fields + fields = tag_or_context_fields(executor, context_fields) return [] if fields.empty? - field_results = root_results(fields, executor, context_result) - return field_results if subqueries.empty? + field_results(executor, fields, context_result) + end - fields.each_with_object([]) do |field, results| - subqueries.each do |subquery| - subquery_results = subquery.execute(executor, [field]) - results.concat(subquery_results) - end - end + def any_results?(executor, context_fields, context_result = nil) + fields = tag_or_context_fields(executor, context_fields) + return false if fields.empty? + + any_field_results?(executor, fields, context_result) end protected def equality_attrs @@ -64,18 +64,41 @@ end # rubocop:enable Metrics/AbcSize private + def tag_or_context_fields(executor, context_fields) + tag ? executor.apply_tag(tag) : context_fields + end + + def field_results(executor, fields, context_result) + return root_results(fields, executor, context_result) if subqueries.empty? + + subquery_results(executor, fields) + end + def root_results(fields, executor, context_result) field_results = results_for_fields(executor, fields) # TODO: something less ridiculous return field_results unless field_results.empty? && select_from_context?(context_result) selector.apply(context_result) end + def subquery_results(executor, fields) + # NOTE: we do this one field at a time so that results are grouped + # by field, rather than by subfield code. Which isn't part of + # the MARCSpec spec, but it seems more in the spirit of MARC + # to preserve order wherever possible. + fields.each_with_object([]) do |field, results| + subqueries.each do |subquery| + subquery_results = subquery.execute(executor, [field]) + results.concat(subquery_results) + end + end + end + def select_from_context?(context_result) tag.nil? && context_result && selector.can_apply?(context_result) end def results_for_fields(executor, fields) @@ -90,9 +113,24 @@ return results unless condition results.select { |result| executor.condition_met?(condition, field, result) } end + def any_field_results?(executor, fields, context_result) + return any_root_results?(executor, fields, context_result) if subqueries.empty? + + any_subfield_results?(executor, fields) + end + + def any_root_results?(executor, fields, context_result) + root_results(fields, executor, context_result).any? + end + + def any_subfield_results?(executor, fields) + fields.any? do |field| + subqueries.any? { |sq| sq.any_results?(executor, [field]) } + end + end end end end end