module Hikki module Adapters class MongoCollection < Hikki::Collection attr_reader :connection, :db, :uuid_generator def initialize(collection, connection, db, uuid_generator) super(collection) @connection = connection @db = db @uuid_generator = uuid_generator end def index(field) db[collection].create_index(field.to_s) true end def save(data) data = normalize_data(data) db[collection].update({ '_id' => data['_id'] }, data, { upsert: true }) data['_id'] = data['_id'].to_s data end def find(id) stringify_ids(db[collection].find('_id' => bson(id)).to_a).first || {} end def all(options={}) options = normalize_options(options) stringify_ids(limit(offset(db[collection].find.sort({ '_id' => 1 }), options[:offset]), options[:limit]).to_a) end def find_by(field, value, options={}) options = normalize_options(options) stringify_ids(limit(offset(db[collection].find({ field.to_s => value }).sort({ '_id' => 1 }), options[:offset]), options[:limit]).to_a) end def remove(id) db[collection].remove({ '_id' => bson(id)}) true end def remove_all db[collection].remove true end def stringify_ids(results) results.each do |result| result['_id'] = result['_id'].to_s if result.has_key? '_id' end results end def normalize_data(data) deep_copy(data).tap do |d| d.merge!('id' => id_for(d)) d.merge!('_id' => bson(d['id'])) end end def id_for(data) data.fetch('id', data.fetch('_id', uuid_generator.new)).to_s end private def bson(id) uuid_generator.from_string(id.to_s) rescue id.to_s end def offset(cursor, offset) return cursor unless offset > 0 cursor.skip(offset) end def limit(cursor, limit) return cursor unless limit > 0 cursor.limit(limit) end end end end