module Card::Lexicon

Translates names to ids and vice versa via a cached “lex” representation: name for simple cards, [left_id, right_id] for compound cards.

Note, unlike Card::Fetch, Card::Lexicon: does NOT return local name changes until stored

Public Class Methods

cache() click to toggle source
# File lib/card/lexicon.rb, line 26
def cache
  Card::Cache[Lexicon]
end
cache_key(lex) click to toggle source
# File lib/card/lexicon.rb, line 46
def cache_key lex
  "L-#{lex.is_a?(Array) ? lex.join('-') : lex.to_name.key}"
end
delete(card) click to toggle source
# File lib/card/lexicon.rb, line 35
def delete card
  cache.delete card.id.to_s
  cache.delete cache_key(card.lex_before_act)
end
id(name) click to toggle source

param name [String] @return [Integer]

# File lib/card/lexicon.rb, line 20
def id name
  return unless name.present?

  (lex = name_to_lex name.to_name) && lex_to_id(lex)
end
lex_query(lex) click to toggle source
# File lib/card/lexicon.rb, line 50
def lex_query lex
  if lex.is_a?(Array)
    { left_id: lex.first, right_id: lex.last }
  else
    { key: lex.to_name.key }
  end
end
lex_to_name(lex) click to toggle source
# File lib/card/lexicon.rb, line 40
def lex_to_name lex
  return lex unless lex.is_a? Array

  lex.map { |side_id| name side_id or return }.join(Card::Name.joint).to_name
end
name(id) click to toggle source

param id [Integer] @return [String]

# File lib/card/lexicon.rb, line 11
def name id
  return unless id.present?

  name = (lex = id_to_lex id) && lex_to_name(lex)
  (name || "").to_name
end
rescuing() { || ... } click to toggle source

this is to address problems whereby renaming errors leave the lexicon broken. NEEDS TESTING

# File lib/card/lexicon.rb, line 60
def rescuing
  @act_lexes = []
  @act_ids = []
  yield
rescue StandardError => e
  @act_lexes.each { |lex| expire_lex lex }
  @act_ids.each { |id| expire_id id }
  @act_lexes = @act_ids = nil
  raise e
end
update(card) click to toggle source
# File lib/card/lexicon.rb, line 30
def update card
  add card
  expire_lex card.lex_before_act
end
write(id, name, lex) click to toggle source
# File lib/card/lexicon.rb, line 76
def write id, name, lex
  cache.write id.to_s, name
  cache.write cache_key(lex), id
end
write_to_temp_cache(id, name, lex) click to toggle source
# File lib/card/lexicon.rb, line 71
def write_to_temp_cache id, name, lex
  cache.temp.write id.to_s, name if id.present?
  cache.temp.write cache_key(lex), id if lex
end

Private Class Methods

add(card) click to toggle source
# File lib/card/lexicon.rb, line 83
def add card
  lex = card.lex
  @act_lexes << lex
  @act_ids << card.id
  write card.id, card.name, card.lex
end
expire_id(id) click to toggle source
# File lib/card/lexicon.rb, line 94
def expire_id id
  cache.delete id.to_s
end
expire_lex(lex) click to toggle source
# File lib/card/lexicon.rb, line 90
def expire_lex lex
  cache.delete cache_key(lex)
end
id_to_lex(id) click to toggle source
# File lib/card/lexicon.rb, line 98
def id_to_lex id
  cache.fetch id.to_s do
    result = Card.where(id: id).pluck(:name, :left_id, :right_id).first
    return unless result

    (result[0] || [result[1], result[2]]).tap do |lex|
      cache.write cache_key(lex), id
    end
  end
end
lex_to_id(lex) click to toggle source
# File lib/card/lexicon.rb, line 117
def lex_to_id lex
  cache.fetch cache_key(lex) do
    query = lex_query(lex).merge trash: false
    Card.where(query).pluck(:id).first.tap do |id|
      # don't store name, because lex might not be the canonical name
      cache.write id.to_s, lex if lex.is_a?(Array)
    end
  end
end
name_to_lex(name) click to toggle source
# File lib/card/lexicon.rb, line 109
def name_to_lex name
  if name.simple?
    name
  elsif (left_id = id name.left_name) && (right_id = id name.right_name)
    [left_id, right_id]
  end
end