lib/memory_model/collection/index/unique.rb
module MemoryModel
class NilValueError < IndexError
def initialize(index)
super "`#{index.name}` cannot be nil"
end
end
class RecordNotUniqueError < IndexError
def initialize(args)
index, key = args
super "`#{index.name}` with `#{key}` already exists"
end
end
class Collection
class Index
class MemoryModel::Collection::Index::Unique < MemoryModel::Collection::Index
delegate :values_at, to: :index
# `create` should implement creating a new record, raising an error if an item with the matching storage id already
# exists in the index.
def create(key, item)
raise(NilValueError, self) if key.nil? && !options[:allow_nil]
raise(RecordNotUniqueError, [self, key]) if index.has_key?(key)
return if key.nil?
index[key] = item
end
# `update` should find a record in the collection by its storage_id, remove it, and add with the new value.
def update(key, item)
raise(RecordNotInIndexError, [self, item]) unless exists? item
delete(item.uuid)
create(key, item)
end
# `read` should find a record in the collection by its indexed_value, remove it, and add with the new value.
def read(key)
index[key]
end
# `delete` should find a record in the collection by its indexed_value, and remove it.
def delete(key)
index.delete_if { |k, value| key == value.uuid }
end
# `exists?` return whether or not an item with the given storage id exists.
def exists?(item)
index.any? { |key, value| item.uuid == value.uuid }
end
# `values` should return the values of the index
def values
index.values
end
private
def where_using_default(matcher)
[read(matcher)]
end
def where_using_proc(matcher)
index.values_at *index.keys.select(&matcher)
end
def where_using_regexp(matcher)
where_using_proc ->(key) { key =~ matcher }
end
end
end
end
end