class Perpetuity::Mapper

Attributes

collection_name[RW]
dirty_tracker[R]
identity_map[R]
mapper_registry[R]

Public Class Methods

attribute(name, options = {}) click to toggle source
# File lib/perpetuity/mapper.rb, line 32
def self.attribute name, options = {}
  type = options.fetch(:type) { nil }
  attribute_set << Attribute.new(name, type, options)
end
attribute_set() click to toggle source
# File lib/perpetuity/mapper.rb, line 28
def self.attribute_set
  @attribute_set ||= AttributeSet.new
end
attributes() click to toggle source
# File lib/perpetuity/mapper.rb, line 37
def self.attributes
  attribute_set.map(&:name)
end
collection(name) click to toggle source
# File lib/perpetuity/mapper.rb, line 274
def self.collection name
  @collection_name = name.to_s
end
data_source(configuration=Perpetuity.configuration) click to toggle source
# File lib/perpetuity/mapper.rb, line 103
def self.data_source(configuration=Perpetuity.configuration)
  configuration.data_source
end
id(type=nil, &block) click to toggle source
# File lib/perpetuity/mapper.rb, line 202
def self.id type=nil, &block
  if block_given?
    @id = block
    if type
      attribute :id, type: type
    end
    nil
  else
    @id ||= -> { nil }
  end
end
index(attribute_names, options={}) click to toggle source
# File lib/perpetuity/mapper.rb, line 41
def self.index attribute_names, options={}
  attributes = Array(attribute_names).map { |name| attribute_set[name] }
  if attributes.one?
    data_source.index collection_name, attributes.first, options
  else
    data_source.index collection_name, attributes, options
  end
end
map(klass, registry=Perpetuity.mapper_registry) click to toggle source
# File lib/perpetuity/mapper.rb, line 22
def self.map klass, registry=Perpetuity.mapper_registry
  registry[klass] = self
  @mapped_class = klass
  collection klass.name
end
mapped_class() click to toggle source
# File lib/perpetuity/mapper.rb, line 270
def self.mapped_class
  @mapped_class
end
new(registry=Perpetuity.mapper_registry, id_map=IdentityMap.new) click to toggle source
# File lib/perpetuity/mapper.rb, line 16
def initialize registry=Perpetuity.mapper_registry, id_map=IdentityMap.new
  @mapper_registry = registry
  @identity_map = id_map
  @dirty_tracker = DirtyTracker.new
end

Public Instance Methods

all() click to toggle source
# File lib/perpetuity/mapper.rb, line 131
def all
  retrieve
end
all?(&block) click to toggle source
# File lib/perpetuity/mapper.rb, line 115
def all? &block
  count(&block) == count
end
any?(&block) click to toggle source
# File lib/perpetuity/mapper.rb, line 111
def any? &block
  count(&block) > 0
end
attribute_set() click to toggle source
# File lib/perpetuity/mapper.rb, line 75
def attribute_set
  self.class.attribute_set
end
attributes() click to toggle source
# File lib/perpetuity/mapper.rb, line 71
def attributes
  self.class.attributes
end
collection_name() click to toggle source
# File lib/perpetuity/mapper.rb, line 282
def collection_name
  self.class.collection_name
end
count(&block) click to toggle source
# File lib/perpetuity/mapper.rb, line 107
def count &block
  data_source.count collection_name, &block
end
data_source() click to toggle source
# File lib/perpetuity/mapper.rb, line 250
def data_source
  self.class.data_source
end
decrement(object, attribute, count=1) click to toggle source
# File lib/perpetuity/mapper.rb, line 233
def decrement object, attribute, count=1
  id = id_for(object) || object
  data_source.increment collection_name, id, attribute, -count
end
delete(object_or_array) click to toggle source
# File lib/perpetuity/mapper.rb, line 178
def delete object_or_array
  ids = Array(object_or_array).map { |object|
    persisted?(object) ? id_for(object) : object
  }
  data_source.delete ids, collection_name
end
delete_all() click to toggle source
# File lib/perpetuity/mapper.rb, line 79
def delete_all
  data_source.delete_all collection_name
end
detect(id=nil, &block)
Alias for: find
find(id=nil, &block) click to toggle source
# File lib/perpetuity/mapper.rb, line 141
def find id=nil, &block
  return select(&block).first if block_given?

  result = if id.is_a? Array
             find_all_by_ids id
           else
             identity_map[mapped_class, id] ||
             select { |object| object.id == id }.first
           end

  Array(result).each do |r|
    identity_map << r
    dirty_tracker << r
  end

  result
end
Also aliased as: detect
find_all(&block)
Alias for: select
find_all_by_ids(ids) click to toggle source
# File lib/perpetuity/mapper.rb, line 161
def find_all_by_ids ids
  ids_in_map    = ids & identity_map.ids_for(mapped_class)
  ids_to_select = ids - ids_in_map
  retrieved     = if ids_to_select.any?
                    select { |object| object.id.in ids_to_select }.to_a
                  else
                    []
                  end
  from_map      = ids_in_map.map { |id| identity_map[mapped_class, id] }

  retrieved.concat from_map
end
first() click to toggle source
# File lib/perpetuity/mapper.rb, line 127
def first
  retrieve.limit(1).first
end
generate_id_for(object) click to toggle source
# File lib/perpetuity/mapper.rb, line 99
def generate_id_for object
  object.instance_exec(&self.class.id)
end
id_for(object) click to toggle source
# File lib/perpetuity/mapper.rb, line 246
def id_for object
  object.instance_variable_get(:@id)
end
increment(object, attribute, count=1) click to toggle source
# File lib/perpetuity/mapper.rb, line 228
def increment object, attribute, count=1
  id = id_for(object) || object
  data_source.increment collection_name, id, attribute, count
end
indexes() click to toggle source
# File lib/perpetuity/mapper.rb, line 54
def indexes
  data_source.indexes(collection_name)
end
insert(object) click to toggle source
# File lib/perpetuity/mapper.rb, line 83
def insert object
  objects = Array(object)
  serialized_objects = objects.map { |obj| serialize(obj) }

  new_ids = data_source.insert(collection_name, serialized_objects, attribute_set)
  objects.each_with_index do |obj, index|
    give_id_to obj, new_ids[index]
  end

  if object.is_a? Array
    new_ids
  else
    new_ids.first
  end
end
load_association!(object, attribute) click to toggle source
# File lib/perpetuity/mapper.rb, line 185
def load_association! object, attribute
  objects = Array(object)
  dereferencer = Dereferencer.new(mapper_registry, identity_map)
  dereferencer.load objects.map { |obj| obj.instance_variable_get("@#{attribute}") }

  objects.each do |obj|
    reference = obj.instance_variable_get("@#{attribute}")
    if reference.is_a? Array
      refs = reference
      real_objects = refs.map { |ref| dereferencer[ref] }
      inject_attribute obj, attribute, real_objects
    else
      inject_attribute obj, attribute, dereferencer[reference]
    end
  end
end
mapped_class() click to toggle source
# File lib/perpetuity/mapper.rb, line 278
def mapped_class
  self.class.mapped_class
end
none?(&block) click to toggle source
# File lib/perpetuity/mapper.rb, line 123
def none? &block
  !any?(&block)
end
one?(&block) click to toggle source
# File lib/perpetuity/mapper.rb, line 119
def one? &block
  count(&block) == 1
end
persisted?(object) click to toggle source
# File lib/perpetuity/mapper.rb, line 242
def persisted? object
  !!id_for(object)
end
reindex!() click to toggle source
# File lib/perpetuity/mapper.rb, line 58
def reindex!
  indexes.each { |index| data_source.activate_index! index }
  unspecified_indexes.each do |index|
    data_source.remove_index index
  end
end
reject(&block) click to toggle source
# File lib/perpetuity/mapper.rb, line 174
def reject &block
  retrieve data_source.negate_query(&block)
end
remove_index!(index) click to toggle source
# File lib/perpetuity/mapper.rb, line 50
def remove_index! index
  data_source.remove_index index
end
sample() click to toggle source
# File lib/perpetuity/mapper.rb, line 238
def sample
  all.sample
end
save(object) click to toggle source
# File lib/perpetuity/mapper.rb, line 219
def save object
  changed_attributes = serialize_changed_attributes(object)
  if changed_attributes && changed_attributes.any?
    update object, changed_attributes
  else
    update object, serialize(object)
  end
end
select(&block) click to toggle source
# File lib/perpetuity/mapper.rb, line 135
def select &block
  retrieve data_source.query(&block)
end
Also aliased as: find_all
serialize(object) click to toggle source
# File lib/perpetuity/mapper.rb, line 254
def serialize object
  attributes = data_source.serialize(object, self)
  if o_id = generate_id_for(object)
    attributes['id'] = o_id
  end

  attributes
end
serialize_changed_attributes(object) click to toggle source
# File lib/perpetuity/mapper.rb, line 263
def serialize_changed_attributes object
  cached = dirty_tracker[object.class, id_for(object)]
  if cached
    data_source.serialize_changed_attributes(object, cached, self)
  end
end
unspecified_indexes() click to toggle source
# File lib/perpetuity/mapper.rb, line 65
def unspecified_indexes
  active_indexes = data_source.active_indexes(collection_name)
  active_but_unspecified_indexes = (active_indexes - indexes)
  active_but_unspecified_indexes.reject { |index| index.attribute =~ /id/ }
end
update(object, new_data) click to toggle source
# File lib/perpetuity/mapper.rb, line 214
def update object, new_data
  id = object.is_a?(mapped_class) ? id_for(object) : object
  data_source.update collection_name, id, new_data
end

Private Instance Methods

retrieve(query=data_source.query) click to toggle source
# File lib/perpetuity/mapper.rb, line 288
def retrieve query=data_source.query
  Perpetuity::Retrieval.new self, query, identity_map: identity_map
end