lib/nazrin/data_accessor.rb
require 'nazrin/result'
module Nazrin
class DataAccessor
class NoAccessorError < StandardError; end
class << self
def for(clazz)
accessor = registered_accessor_for(clazz) || register_accessor(clazz)
return accessor if accessor
raise NoAccessorError, "No accessor for #{clazz.name}"
end
def registered_accessor_for(clazz)
return nil if clazz.name.nil? || clazz.name.empty?
accessors[clazz.name.to_sym]
end
def register_accessor(clazz)
clazz.ancestors.each do |ancestor_class|
if accessor = accessor_for(ancestor_class)
register(accessor, clazz)
return accessor
end
end
nil
end
def accessor_for(clazz)
return nil if clazz.name.nil? || clazz.name.empty?
if clazz.respond_to?(:nazrin_searchable_config) && clazz.nazrin_searchable_config.domain_name
require 'nazrin/data_accessor/struct'
return Nazrin::DataAccessor::Struct[clazz.nazrin_searchable_config]
elsif defined?(::ActiveRecord::Base) && clazz.ancestors.include?(::ActiveRecord::Base)
require 'nazrin/data_accessor/active_record'
return Nazrin::DataAccessor::ActiveRecord
elsif defined?(::Mongoid::Document) && clazz.ancestors.include?(::Mongoid::Document)
require 'nazrin/data_accessor/mongoid'
return Nazrin::DataAccessor::Mongoid
end
nil
end
def register(accessor, clazz)
accessors[clazz.name.to_sym] = accessor
end
def accessors
@accessor ||= {}
end
end
attr_reader :model
attr_reader :options
def initialize(model, options)
@model = model
@options = options
end
def results(client)
res = client.search
collection = load_all(data_from_response(res))
start = client.parameters[:start]
size = client.parameters[:size]
if size && start
total_count = res.data.hits.found
records = Nazrin::PaginationGenerator.generate(
collection,
current_page: current_page(start, size),
per_page: size,
total_count: total_count,
last_page: last_page(size, total_count))
else
records = collection
end
Result.new(
records,
res.facets
)
end
def load_all
raise NotImplementedError
end
def data_from_response
raise NotImplementedError
end
private
def last_page(size, total_count)
(total_count / size.to_f).ceil
end
def current_page(start, size)
(start / size.to_f).ceil + 1
end
end
end