module Quiver::Mapper

Attributes

adapter[RW]
adapter_type[RW]

Public Class Methods

included(host) click to toggle source
# File lib/quiver/mapper.rb, line 3
def self.included(host)
  host.send(:extend, ClassMethods)
end
new(adapter_type=nil) click to toggle source
# File lib/quiver/mapper.rb, line 72
def initialize(adapter_type=nil)
  adapter_type ||= self.class.parents[-2]::Application.default_adapter_type
  self.adapter_type = adapter_type
  self.adapter = self.class.send(:adapter_for, adapter_type).new
end

Public Instance Methods

all() click to toggle source
# File lib/quiver/mapper.rb, line 121
def all
  query({})
end
count() click to toggle source
# File lib/quiver/mapper.rb, line 174
def count
  adapter.count
end
filter(params) click to toggle source
# File lib/quiver/mapper.rb, line 178
def filter(params)
  SimpleQueryBuilder.new(self).filter(params)
end
find(pk) click to toggle source
# File lib/quiver/mapper.rb, line 112
def find(pk)
  adapter.find(pk).when(
    success: -> (attributes, result) {
      Quiver::Mapper::MapperResult.new { |e| hydrate(attributes) }
    },
    failure: -> (errors, result) { result }
  )
end
hard_delete(model) click to toggle source
# File lib/quiver/mapper.rb, line 125
def hard_delete(model)
  self.class.parents[-2]::Mappers.transaction do |transaction|
    attributes = dehydrate(model)

    Quiver::Mapper::MapperResult.new(nil, nil, {adapter_op: :hard_delete}) do |errors|
      adapter.hard_delete(attributes, transaction).when(
        success: -> (attributes, result) {
          {}
        },
        failure: -> (adapter_errors, result) { errors.add(adapter_errors); nil }
      )
    end
  end
end
paginate(params) click to toggle source
# File lib/quiver/mapper.rb, line 186
def paginate(params)
  SimpleQueryBuilder.new(self).paginate(params)
end
restore(model) click to toggle source
# File lib/quiver/mapper.rb, line 157
def restore(model)
  self.class.parents[-2]::Mappers.transaction do |transaction|
    model.deleted_at = nil

    attributes = dehydrate(model)

    Quiver::Mapper::MapperResult.new(nil, nil, {adapter_op: :restore}) do |errors|
      adapter.update(attributes, transaction).when(
        success: -> (attributes, result) {
          hydrate(attributes)
        },
        failure: -> (adapter_errors, result) { errors.add(adapter_errors); nil }
      )
    end
  end
end
save(model) click to toggle source
# File lib/quiver/mapper.rb, line 78
def save(model)
  self.class.parents[-2]::Mappers.transaction do |transaction|
    hooks = self.class.send(:hooks) || []

    if self.class.type_attribute
      type_key = model.send(self.class.type_attribute)
    end

    if hooks.is_a?(Hash)
      hooks = hooks[type_key.to_sym] || []
    end

    hooks = hooks.map(&:new)

    model = hooks.inject(model) do |model, hook|
      hook.before_save(model)
    end

    if model.persisted_by.include?(adapter_type)
      result = update(model, transaction)
    else
      result = create(model, transaction)

      if result.success?
        # model.persisted_by!(adapter_type)
      end
    end

    hooks.inject(result) do |result, hook|
      hook.after_save(result)
    end
  end
end
soft_delete(model) click to toggle source
# File lib/quiver/mapper.rb, line 140
def soft_delete(model)
  self.class.parents[-2]::Mappers.transaction do |transaction|
    model.deleted_at = Time.now

    attributes = dehydrate(model)

    Quiver::Mapper::MapperResult.new(nil, nil, {adapter_op: :soft_delete}) do |errors|
      adapter.update(attributes, transaction).when(
        success: -> (attributes, result) {
          hydrate(attributes)
        },
        failure: -> (adapter_errors, result) { errors.add(adapter_errors); nil }
      )
    end
  end
end
sort(params) click to toggle source
# File lib/quiver/mapper.rb, line 182
def sort(params)
  SimpleQueryBuilder.new(self).sort(params)
end

Private Instance Methods

create(model, transaction) click to toggle source
# File lib/quiver/mapper.rb, line 217
def create(model, transaction)
  when_valid(model, :create) do |model, errors|
    attributes = dehydrate(model)

    adapter.create(attributes, transaction).when({
      success: -> (attributes, result) {
        model.persisted_by!(adapter_type)
        model.send(:"#{adapter.send(:primary_key_name)}=", attributes[adapter.send(:primary_key_name)])
        hydrate(attributes)
      },
      failure: -> (adapter_errors, result) { errors.add(adapter_errors) }
    })
  end
end
dehydrate(model) click to toggle source
# File lib/quiver/mapper.rb, line 284
def dehydrate(model)
  attributes = model.attributes

  if self.class.type_attribute
    attributes = attributes.merge(:__type__ => {
      value: model.send(self.class.type_attribute),
      name: self.class.type_attribute
    })
  end

  hooks = self.class.send(:hooks) || []

  if hooks.is_a?(Hash)
    hooks = hooks[model.send(self.class.type_attribute)] || []
  end

  hooks.inject(attributes) do |attrs, hook|
    hook.new.after_dehydrate(attrs)
  end
end
hydrate(attributes) click to toggle source
# File lib/quiver/mapper.rb, line 258
def hydrate(attributes)
  attributes = attributes.dup

  hooks = self.class.send(:hooks) || []

  type_key = attributes.delete(self.class.type_attribute) || attributes.delete(self.class.type_attribute.to_s)

  if hooks.is_a?(Hash)
    hooks = hooks[type_key.to_sym] || []
  end

  attributes = hooks.inject(attributes) do |attrs, hook|
    hook.new.before_hydrate(attrs)
  end

  if self.class.send(:maps).is_a?(Hash)
    object = self.class.send(:maps)[type_key.to_sym].new(attributes)
  else
    object = self.class.send(:maps).new(attributes)
  end

  object.persisted_by!(adapter_type)

  object
end
query(q={}) click to toggle source
# File lib/quiver/mapper.rb, line 245
def query(q={})
  adapter.query(q).when(
    success: -> (items, result) {
      Quiver::Mapper::MapperResult.new(nil, nil, result.data) { |e|
        items.map do |attributes|
          hydrate(attributes)
        end
      }
    },
    failure: -> (errors, result) { result }
  )
  end
update(model, transaction) click to toggle source
# File lib/quiver/mapper.rb, line 232
def update(model, transaction)
  when_valid(model, :update) do |model, errors|
    attributes = dehydrate(model)

    adapter.update(attributes, transaction).when(
      success: -> (attributes, result) {
        hydrate(attributes)
      },
      failure: -> (adapter_errors, result) { errors.add(adapter_errors); nil }
    )
  end
end
when_valid(model, adapter_op) { |model, errors| ... } click to toggle source
# File lib/quiver/mapper.rb, line 194
def when_valid(model, adapter_op)
  raise ArgumentError, "requires block" unless block_given?

  errors = model.validate(
    tags: [adapter_op],
    mapper: self,
    model: model
  )

  if errors.success?
    current_time = Time.now.utc
    model.updated_at = current_time if model.respond_to?(:updated_at=)

    if adapter_op == :create
      model.created_at ||= current_time if model.respond_to?(:created_at)
    end

    object = yield(model, errors)
  end

  Quiver::Mapper::MapperResult.new(object, errors, adapter_op: adapter_op)
end