Class: Kerbi::State::EntrySet

Inherits:
Object
  • Object
show all
Includes:
Mixins::EntryTagLogic
Defined in:
lib/state/entry_set.rb

Overview

Baby version of ActiveRecord::Relation. Holds an array of entries (i.e Kerbi::State::Entry) and exposes useful group-level operations, like sorting, find maximums, etc…

Constant Summary

Constants included from Mixins::EntryTagLogic

Mixins::EntryTagLogic::CANDIDATE_WORD, Mixins::EntryTagLogic::LATEST_PLUS_WORD, Mixins::EntryTagLogic::LATEST_WORD, Mixins::EntryTagLogic::NEW_CANDIDATE_WORD, Mixins::EntryTagLogic::OLDEST_WORD, Mixins::EntryTagLogic::RANDOM_WORD, Mixins::EntryTagLogic::SPECIAL_CHAR, Mixins::EntryTagLogic::SPECIAL_READ_WORDS, Mixins::EntryTagLogic::SPECIAL_WRITE_WORDS

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Mixins::EntryTagLogic

#do_resolve_tag_expr, #resolve_candidate_read_word, #resolve_candidate_write_word, #resolve_latest_word, #resolve_new_candidate_word, #resolve_oldest_word, #resolve_random_word, #resolve_read_tag_expr, #resolve_word, #resolve_write_tag_expr

Constructor Details

#initialize(dicts, **opts) ⇒ EntrySet

Returns a new instance of EntrySet.

Parameters:

  • dicts (Array<Hash>)


23
24
25
26
27
# File 'lib/state/entry_set.rb', line 23

def initialize(dicts, **opts)
  @entries = dicts.map { |h| Entry.from_dict(self, h) }
  @release_name = opts[:release_name]
  sort_by_created_at
end

Instance Attribute Details

#entriesArray<Kerbi::State::Entry> (readonly)

Memoized list of state entries

Returns:



15
16
17
# File 'lib/state/entry_set.rb', line 15

def entries
  @entries
end

#release_nameString (readonly)

Made available to states, as a convenience

Returns:

  • (String)


20
21
22
# File 'lib/state/entry_set.rb', line 20

def release_name
  @release_name
end

Instance Method Details

#candidatesArray<Kerbi::State::Entry>

Filters entries by candidate status, returning only the ones that ARE candidates.

Returns:



55
56
57
# File 'lib/state/entry_set.rb', line 55

def candidates
  entries.reject(&:committed?).to_a
end

#committedArray<Kerbi::State::Entry>

Filters entries by candidate status, returning only the ones that are NOT candidates.

Returns:



47
48
49
# File 'lib/state/entry_set.rb', line 47

def committed
  entries.select(&:committed?).to_a
end

#find_by_literal_tag(tag_expr) ⇒ ?Kerbi::State::Entry Also known as: get

Performs simple linear search for an entry whose tags matches exactly tag_expr.

Parameters:

  • tag_expr (String)

Returns:



131
132
133
134
# File 'lib/state/entry_set.rb', line 131

def find_by_literal_tag(tag_expr)
  return nil unless tag_expr.present?
  entries.find { |e| e.tag == tag_expr }
end

#find_entry_for_read(tag_expr) ⇒ Kerbi::State::Entry

Given a target entry tag expression, searches underlying array for the corresponding entry.

Assumes the tag expression contains special interpolatable words, and thus resolves the tag expression into a literal tag first.

Invokes tag resolution logic specific to reading entries, which is different than for writing entries (see #resolve_read_tag_expr).

Parameters:

  • tag_expr (String)

Returns:

Raises:



94
95
96
97
98
99
# File 'lib/state/entry_set.rb', line 94

def find_entry_for_read(tag_expr)
  resolved_tag = resolve_read_tag_expr(tag_expr)
  entry = find_by_literal_tag(resolved_tag)
  raise Kerbi::StateNotFoundError.new(tag_expr) unless entry
  entry
end

#find_or_init_entry_for_write(tag_expr) ⇒ ?Kerbi::State::Entry

Given a target entry tag expression, searches underlying array for the corresponding entry.

Assumes the tag expression contains special interpolatable words, and thus resolves the tag expression into a literal tag first.

Invokes tag resolution logic specific to writing entries, which is different than for reading entries (see #resolve_write_tag_expr).

If an entry is not found, initializes a new empty entry with the given resolved tag, and adds it to the set’s underlying array.

Parameters:

  • tag_expr (String)

Returns:



115
116
117
118
119
120
121
122
123
124
# File 'lib/state/entry_set.rb', line 115

def find_or_init_entry_for_write(tag_expr)
  resolved_tag = resolve_write_tag_expr(tag_expr)
  if(existing_entry = find_by_literal_tag(resolved_tag))
    existing_entry
  else
    entry = Kerbi::State::Entry.new(self, tag: resolved_tag)
    entries.unshift(entry)
    entry
  end
end

#latest?Kerbi::State::Entry

Finds the most recently created/updated entry in the list that is not a candidate.

Returns:



63
64
65
# File 'lib/state/entry_set.rb', line 63

def latest
  committed.first
end

#latest_candidate?Kerbi::State::Entry

Finds the most recently created/updated entry in the list that is a candidate.

Returns:



79
80
81
# File 'lib/state/entry_set.rb', line 79

def latest_candidate
  candidates.first
end

#oldest?Kerbi::State::Entry

Finds the least recently created/updated entry in the list that is not a candidate.

Returns:



71
72
73
# File 'lib/state/entry_set.rb', line 71

def oldest
  committed.last
end

#prune_candidatesObject

Updates internal list of state entries to itself minus states marked as candidates. Does NOT save to backend.



140
141
142
# File 'lib/state/entry_set.rb', line 140

def prune_candidates
  entries.reject!(&:candidate?)
end

#sort_by_created_atObject

Sorts internal list of candidates by age.



146
147
148
149
150
151
# File 'lib/state/entry_set.rb', line 146

def sort_by_created_at
  entries.sort! do |a, b|
    both_defined = a.created_at && b.created_at
    both_defined ? b.created_at <=> a.created_at : 0
  end
end

#validate!Object

Performs simple validation logic, checking if each state is valid, doing noting if all are valid, and raising an exception otherwise.



33
34
35
36
37
38
39
40
41
# File 'lib/state/entry_set.rb', line 33

def validate!
  entries.each(&:validate)
  if (bad_entries = entries.reject(&:valid?)).any?
    errors = Hash[bad_entries.map do |entry|
      [entry.tag, entry.validation_errors.deep_dup]
    end]
    raise Kerbi::EntryValidationError.new(errors)
  end
end