# encoding: utf-8 require "mongoid/collections/operations" require "mongoid/collections/cyclic_iterator" require "mongoid/collections/mimic" require "mongoid/collections/master" require "mongoid/collections/slaves" module Mongoid #:nodoc class Collection include Collections::Mimic attr_reader :counter, :name # All write operations should delegate to the master connection. These # operations mimic the methods on a Mongo:Collection. # # Example: # # collection.save({ :name => "Al" }) proxy(:master, Collections::Operations::PROXIED) # Determines where to send the next read query. If the slaves are not # defined then send to master. If the read counter is under the configured # maximum then return the master. In any other case return the slaves. # # Example: # # collection.directed # # Return: # # Either a +Master+ or +Slaves+ collection. def directed(options = {}) enslave = options.delete(:enslave) || @klass.enslaved? enslave ? master_or_slaves : master end # Find documents from the database given a selector and options. # # Options: # # selector: A +Hash+ selector that is the query. # options: The options to pass to the db. # # Example: # # collection.find({ :test => "value" }) def find(selector = {}, options = {}) cursor = Mongoid::Cursor.new(@klass, self, directed(options).find(selector, options)) if block_given? yield cursor; cursor.close else cursor end end # Find the first document from the database given a selector and options. # # Options: # # selector: A +Hash+ selector that is the query. # options: The options to pass to the db. # # Example: # # collection.find_one({ :test => "value" }) def find_one(selector = {}, options = {}) directed(options).find_one(selector, options) end # Initialize a new Mongoid::Collection, setting up the master, slave, and # name attributes. Masters will be used for writes, slaves for reads. # # Example: # # Mongoid::Collection.new(masters, slaves, "test") def initialize(klass, name) @klass, @name = klass, name end # Perform a map/reduce on the documents. # # Options: # # map: The map javascript funcdtion. # reduce: The reduce javascript function. def map_reduce(map, reduce, options = {}) directed(options).map_reduce(map, reduce, options) end alias :mapreduce :map_reduce # Return the object responsible for writes to the database. This will # always return a collection associated with the Master DB. # # Example: # # collection.writer def master @master ||= Collections::Master.new(Mongoid.master, @name) end # Return the object responsible for reading documents from the database. # This is usually the slave databases, but in their absence the master will # handle the task. # # Example: # # collection.reader def slaves @slaves ||= Collections::Slaves.new(Mongoid.slaves, @name) end protected def master_or_slaves slaves.empty? ? master : slaves end end end