class MARC::Spec::Queries::Query
Attributes
condition[R]
selector[R]
subqueries[R]
tag[R]
Public Class Methods
new(tag: nil, selector: nil, condition: nil, subqueries: [])
click to toggle source
TODO: separate factory methods for possible cases? (see transform.rb) TODO: separate query (w/o subqueries) from wrapper w/subqueries?
# File lib/marc/spec/queries/query.rb, line 14 def initialize(tag: nil, selector: nil, condition: nil, subqueries: []) @tag = ensure_type(tag, Tag, allow_nil: true) # TODO: do we need the Selector interface at all? @selector = ensure_type(selector, Applicable, allow_nil: true) @condition = ensure_type(condition, Condition, allow_nil: true) @subqueries = subqueries.map { |sq| ensure_type(sq, Query) } end
Public Instance Methods
any_results?(executor, context_fields, context_result = nil)
click to toggle source
# File lib/marc/spec/queries/query.rb, line 43 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
execute(executor, context_fields, context_result = nil)
click to toggle source
TODO: don’t support nested subqueries
# File lib/marc/spec/queries/query.rb, line 36 def execute(executor, context_fields, context_result = nil) fields = tag_or_context_fields(executor, context_fields) return [] if fields.empty? field_results(executor, fields, context_result) end
tag_str()
click to toggle source
# File lib/marc/spec/queries/query.rb, line 22 def tag_str tag.to_s if tag end
to_s()
click to toggle source
# File lib/marc/spec/queries/query.rb, line 26 def to_s StringIO.new.tap do |out| out << tag if tag out << selector if selector out << "{#{condition}}" if condition out << subqueries.join end.string end
Protected Instance Methods
equality_attrs()
click to toggle source
# File lib/marc/spec/queries/query.rb, line 52 def equality_attrs %i[tag selector condition subqueries] end
to_s_inspect()
click to toggle source
rubocop:disable Metrics/AbcSize
# File lib/marc/spec/queries/query.rb, line 57 def to_s_inspect StringIO.new.tap do |out| out << tag.inspect if tag out << selector.inspect if selector out << "{#{condition.inspect}}" if condition out << subqueries.map(&:inspect).join end.string end
Private Instance Methods
any_field_results?(executor, fields, context_result)
click to toggle source
# File lib/marc/spec/queries/query.rb, line 118 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
any_root_results?(executor, fields, context_result)
click to toggle source
# File lib/marc/spec/queries/query.rb, line 124 def any_root_results?(executor, fields, context_result) root_results(fields, executor, context_result).any? end
any_subfield_results?(executor, fields)
click to toggle source
# File lib/marc/spec/queries/query.rb, line 128 def any_subfield_results?(executor, fields) fields.any? do |field| subqueries.any? { |sq| sq.any_results?(executor, [field]) } end end
field_results(executor, fields, context_result)
click to toggle source
# File lib/marc/spec/queries/query.rb, line 73 def field_results(executor, fields, context_result) return root_results(fields, executor, context_result) if subqueries.empty? subquery_results(executor, fields) end
results_for_field(executor, field)
click to toggle source
# File lib/marc/spec/queries/query.rb, line 111 def results_for_field(executor, field) results = executor.apply_selector(selector, field) return results unless condition results.select { |result| executor.condition_met?(condition, field, result) } end
results_for_fields(executor, fields)
click to toggle source
# File lib/marc/spec/queries/query.rb, line 104 def results_for_fields(executor, fields) fields.each_with_object([]) do |field, results| field_results = results_for_field(executor, field) results.concat(field_results) end end
root_results(fields, executor, context_result)
click to toggle source
# File lib/marc/spec/queries/query.rb, line 79 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
select_from_context?(context_result)
click to toggle source
# File lib/marc/spec/queries/query.rb, line 100 def select_from_context?(context_result) tag.nil? && context_result && selector.can_apply?(context_result) end
subquery_results(executor, fields)
click to toggle source
# File lib/marc/spec/queries/query.rb, line 87 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
tag_or_context_fields(executor, context_fields)
click to toggle source
rubocop:enable Metrics/AbcSize
# File lib/marc/spec/queries/query.rb, line 69 def tag_or_context_fields(executor, context_fields) tag ? executor.apply_tag(tag) : context_fields end