require 'mongo' module Dragonfly module DataStorage class MongoDataStore include Configurable include Serializer configurable_attr :host configurable_attr :port configurable_attr :database, 'dragonfly' configurable_attr :username configurable_attr :password configurable_attr :connection configurable_attr :db # Mongo gem deprecated ObjectID in favour of ObjectId OBJECT_ID = defined?(BSON::ObjectId) ? BSON::ObjectId : BSON::ObjectID INVALID_OBJECT_ID = defined?(BSON::InvalidObjectId) ? BSON::InvalidObjectId : BSON::InvalidObjectID def initialize(opts={}) self.host = opts[:host] self.port = opts[:port] self.database = opts[:database] if opts[:database] self.username = opts[:username] self.password = opts[:password] self.connection = opts[:connection] self.db = opts[:db] end def store(temp_object, opts={}) ensure_authenticated! temp_object.file do |f| mongo_id = grid.put(f, :metadata => marshal_encode(opts[:meta] || {})) mongo_id.to_s end end def retrieve(uid) ensure_authenticated! grid_io = grid.get(bson_id(uid)) meta = marshal_decode(grid_io.metadata) meta.merge!(:stored_at => grid_io.upload_date) [ grid_io.read, meta ] rescue Mongo::GridFileNotFound, INVALID_OBJECT_ID => e raise DataNotFound, "#{e} - #{uid}" end def destroy(uid) ensure_authenticated! grid.delete(bson_id(uid)) rescue Mongo::GridFileNotFound, INVALID_OBJECT_ID => e raise DataNotFound, "#{e} - #{uid}" end def connection @connection ||= Mongo::Connection.new(host, port) end def db @db ||= connection.db(database) end def grid @grid ||= Mongo::Grid.new(db) end private def ensure_authenticated! if username @authenticated ||= db.authenticate(username, password) end end def bson_id(uid) OBJECT_ID.from_string(uid) end end end end