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