Class: Textus::Projection

Inherits:
Object
  • Object
show all
Defined in:
lib/textus/projection.rb

Constant Summary collapse

MAX_LIMIT =
1000
REDUCER_TIMEOUT_SECONDS =
2

Instance Method Summary collapse

Constructor Details

#initialize(store, spec, bypass_freshness: false) ⇒ Projection

Returns a new instance of Projection.

Raises:



9
10
11
12
13
14
15
# File 'lib/textus/projection.rb', line 9

def initialize(store, spec, bypass_freshness: false)
  @store = store
  @spec = spec || {}
  @bypass_freshness = bypass_freshness
  @limit = (@spec["limit"] || MAX_LIMIT).to_i
  raise InvalidProjection.new("limit #{@limit} exceeds max #{MAX_LIMIT}") if @limit > MAX_LIMIT
end

Instance Method Details

#runObject



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/textus/projection.rb', line 17

def run
  keys = collect_keys
  explicit_pluck = !@spec["pluck"].nil? && @spec["pluck"] != "*"
  ops = Operations.for(@store, bypass_freshness: @bypass_freshness)
  rows = keys.map do |key|
    env = ops.reads.get.call(key)
    row = pluck(env.meta, env.body)
    explicit_pluck ? row : row.merge("_key" => key)
  end
  reduced = apply_reducer(rows)
  # Reducers may return either an Array of rows (legacy / templated builds)
  # or a Hash that becomes the structured-format payload base. In the Hash
  # case, downstream sort/limit/position markers don't apply, and the
  # builder owns `_meta.generated_at` so we don't stamp it here.
  return reduced if reduced.is_a?(Hash)

  rows = reduced
  rows = sort(rows)
  rows = rows.first(@limit)
  mark_positions(rows)
  { "entries" => rows, "count" => rows.length, "generated_at" => Time.now.utc.iso8601 }
end