Module: EventStoreRuby::QueryProcessor

Defined in:
lib/eventstore_ruby/query_processor.rb

Overview

In-memory filtering helpers. Mirrors the behaviour of the TypeScript queryprocessor.

Class Method Summary collapse

Class Method Details

.check_event(event, filter) ⇒ Object

Internal —————————————————————–



17
18
19
20
21
22
23
24
25
# File 'lib/eventstore_ruby/query_processor.rb', line 17

def check_event(event, filter)
  if filter.is_a?(EventQuery)
    # Match if any inner filter matches
    filter.filters.any? { |inner| check_event(event, inner) }
  else
    check_event_types(event.event_type, filter.event_types) &&
      check_predicates(event.payload, filter.payload_predicates)
  end
end

.check_event_types(event_type, event_types) ⇒ Object



27
28
29
30
# File 'lib/eventstore_ruby/query_processor.rb', line 27

def check_event_types(event_type, event_types)
  return true if event_types.nil? || event_types.empty?
  event_types.include?(event_type)
end

.check_predicates(payload, predicates) ⇒ Object



32
33
34
35
# File 'lib/eventstore_ruby/query_processor.rb', line 32

def check_predicates(payload, predicates)
  return true if predicates.nil? || predicates.empty?
  predicates.any? { |predicate| subset?(payload, predicate) }
end

.process(events, filter = nil) ⇒ Object

Public: returns an array of EventRecord that satisfy the given filter. events - Array<EventRecord> filter - EventFilter or nil



9
10
11
12
13
# File 'lib/eventstore_ruby/query_processor.rb', line 9

def process(events, filter = nil)
  return events.dup if filter.nil? # return a shallow copy to avoid mutating original array

  events.select { |event| check_event(event, filter) }
end

.subset?(payload, predicate) ⇒ Boolean

Recursive inclusion check: is predicate a subset of payload?



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/eventstore_ruby/query_processor.rb', line 38

def subset?(payload, predicate)
  return true if predicate.nil?
  return false if payload.nil?

  # Primitive values
  if !payload.is_a?(Array) && !payload.is_a?(Hash)
    return payload == predicate
  end

  if predicate.is_a?(Array)
    return false unless payload.is_a?(Array)
    # Every element of predicate must match at least one element of payload.
    return predicate.all? do |pred_elem|
      payload.any? { |payload_elem| subset?(payload_elem, pred_elem) }
    end
  elsif predicate.is_a?(Hash)
    return false unless payload.is_a?(Hash)
    predicate.each do |key, pred_val|
      return false unless payload.key?(key)
      return false unless subset?(payload[key], pred_val)
    end
    true
  else
    # Non-Array, non-Hash but payload might be Array/Hash when predicate is primitive.
    payload == predicate
  end
end