mongo-ruby-driver/lib/mongo/collection.rb

185 lines
6.1 KiB
Ruby
Raw Normal View History

2008-12-17 16:49:06 +00:00
# --
2009-01-06 15:51:01 +00:00
# Copyright (C) 2008-2009 10gen Inc.
2008-11-22 01:00:51 +00:00
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License, version 3, as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
# for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
2008-12-17 16:49:06 +00:00
# ++
2008-11-22 01:00:51 +00:00
require 'mongo/query'
module XGen
module Mongo
module Driver
2008-12-17 16:43:08 +00:00
# A named collection of records in a database.
2008-11-22 01:00:51 +00:00
class Collection
attr_reader :db, :name, :hint
2008-11-22 01:00:51 +00:00
def initialize(db, name)
2009-02-05 21:37:35 +00:00
@db, @name = db, name
@hint = nil
2008-11-22 01:00:51 +00:00
end
# Set hint fields to use and return +self+. hint may be a single field
# name, array of field names, or a hash (preferably an OrderedHash).
# May be +nil+.
def hint=(hint)
@hint = normalize_hint_fields(hint)
2009-01-13 20:51:41 +00:00
self
end
2008-12-17 16:43:08 +00:00
# Return records that match a +selector+ hash. See Mongo docs for
# details.
#
# Options:
2008-12-17 16:43:08 +00:00
# :fields :: Array of collection field names; only those will be returned (plus _id if defined)
# :offset :: Start at this record when returning records
# :limit :: Maximum number of records to return
# :sort :: Either hash of field names as keys and 1/-1 as values; 1 ==
# ascending, -1 == descending, or array of field names (all
# assumed to be sorted in ascending order).
# :hint :: See #hint. This option overrides the collection-wide value.
def find(selector={}, options={})
fields = options.delete(:fields)
2008-11-22 01:00:51 +00:00
fields = nil if fields && fields.empty?
offset = options.delete(:offset) || 0
limit = options.delete(:limit) || 0
sort = options.delete(:sort)
hint = options.delete(:hint)
if hint
hint = normalize_hint_fields(hint)
else
hint = @hint # assumed to be normalized already
end
raise RuntimeError, "Unknown options [#{options.inspect}]" unless options.empty?
@db.query(self, Query.new(selector, fields, offset, limit, sort, hint))
2008-11-22 01:00:51 +00:00
end
2009-02-09 14:46:30 +00:00
# Find the first record that matches +selector+. See #find.
def find_first(selector={}, options={})
cursor = find(selector, options)
obj = cursor.next_object
cursor.close
obj
end
2009-01-07 14:45:56 +00:00
# Insert +objects+, which are hashes. "<<" is aliased to this method.
# Returns either the single inserted object or a new array containing
# +objects+. The object(s) may have been modified by the database's PK
# factory, if it has one.
2008-11-22 01:00:51 +00:00
def insert(*objects)
objects = objects.first if objects.size == 1 && objects.first.is_a?(Array)
res = @db.insert_into_db(@name, objects)
res.size > 1 ? res : res.first
2008-11-22 01:00:51 +00:00
end
2008-12-08 20:04:07 +00:00
alias_method :<<, :insert
2008-11-22 01:00:51 +00:00
2008-12-17 16:43:08 +00:00
# Remove the records that match +selector+.
2008-11-22 01:00:51 +00:00
def remove(selector={})
@db.remove_from_db(@name, selector)
end
2008-12-17 16:43:08 +00:00
# Remove all records.
2008-11-22 01:00:51 +00:00
def clear
remove({})
end
2008-12-17 16:43:08 +00:00
# Update records that match +selector+ by applying +obj+ as an update.
# If no match, inserts (???).
2008-11-22 01:00:51 +00:00
def repsert(selector, obj)
@db.repsert_in_db(@name, selector, obj)
end
2008-12-17 16:43:08 +00:00
# Update records that match +selector+ by applying +obj+ as an update.
2008-11-22 01:00:51 +00:00
def replace(selector, obj)
@db.replace_in_db(@name, selector, obj)
end
2008-12-17 16:43:08 +00:00
# Update records that match +selector+ by applying +obj+ as an update.
# Both +selector+ and +modifier_obj+ are required.
def modify(selector, modifier_obj)
raise "no object" unless modifier_obj
2008-11-22 01:00:51 +00:00
raise "no selector" unless selector
2008-12-17 16:43:08 +00:00
@db.modify_in_db(@name, selector, modifier_obj)
2008-11-22 01:00:51 +00:00
end
2008-12-17 16:43:08 +00:00
# Create a new index named +index_name+. +fields+ should be an array
# of field names.
2008-11-22 01:00:51 +00:00
def create_index(name, *fields)
2009-02-05 19:24:20 +00:00
fields = *fields if fields.kind_of?(Array) && fields.length == 1
2008-11-22 01:00:51 +00:00
@db.create_index(@name, name, fields)
end
2008-12-17 16:43:08 +00:00
# Drop index +name+.
2008-11-22 01:00:51 +00:00
def drop_index(name)
@db.drop_index(@name, name)
end
2008-12-17 16:43:08 +00:00
# Drop all indexes.
2008-11-22 01:00:51 +00:00
def drop_indexes
# just need to call drop indexes with no args; will drop them all
@db.drop_index(@name, '*')
2008-11-22 01:00:51 +00:00
end
# Drop the entire collection. USE WITH CAUTION.
def drop
@db.drop_collection(@name)
end
2008-12-17 16:43:08 +00:00
# Return an array of hashes, one for each index. Each hash contains:
#
# :name :: Index name
#
# :keys :: Hash whose keys are the names of the fields that make up
# the key and values are integers.
#
# :ns :: Namespace; same as this collection's name.
2008-11-22 01:00:51 +00:00
def index_information
@db.index_information(@name)
end
2008-12-17 18:52:10 +00:00
# Return a hash containing options that apply to this collection.
# 'create' will be the collection name. For the other possible keys
# and values, see DB#create_collection.
def options
@db.collections_info(@name).next_object()['options']
end
2008-12-17 16:43:08 +00:00
# Return the number of records that match +selector+. If +selector+ is
# +nil+ or an empty hash, returns the count of all records.
2008-11-22 01:00:51 +00:00
def count(selector={})
@db.count(@name, selector || {})
end
protected
def normalize_hint_fields(hint)
case hint
when String
{hint => 1}
when Hash
hint
when nil
nil
else
h = OrderedHash.new
hint.to_a.each { |k| h[k] = 1 }
h
end
end
2008-11-22 01:00:51 +00:00
end
end
end
end