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
|
|
|
#
|
2009-02-15 13:24:14 +00:00
|
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
# you may not use this file except in compliance with the License.
|
|
|
|
# You may obtain a copy of the License at
|
2008-11-22 01:00:51 +00:00
|
|
|
#
|
2009-02-15 13:24:14 +00:00
|
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
2008-11-22 01:00:51 +00:00
|
|
|
#
|
2009-02-15 13:24:14 +00:00
|
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
# See the License for the specific language governing permissions and
|
|
|
|
# limitations under the License.
|
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
|
|
|
|
|
2009-01-29 12:15:59 +00:00
|
|
|
attr_reader :db, :name, :hint
|
2009-01-13 20:38:46 +00:00
|
|
|
|
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
|
|
|
|
|
2009-01-30 19:35:22 +00:00
|
|
|
# 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+.
|
2009-01-29 12:15:59 +00:00
|
|
|
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.
|
|
|
|
#
|
2008-12-08 21:47:52 +00:00
|
|
|
# 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).
|
2009-01-29 12:15:59 +00:00
|
|
|
# :hint :: See #hint. This option overrides the collection-wide value.
|
2008-12-08 21:47:52 +00:00
|
|
|
def find(selector={}, options={})
|
|
|
|
fields = options.delete(:fields)
|
2008-11-22 01:00:51 +00:00
|
|
|
fields = nil if fields && fields.empty?
|
2009-01-07 00:14:45 +00:00
|
|
|
offset = options.delete(:offset) || 0
|
|
|
|
limit = options.delete(:limit) || 0
|
|
|
|
sort = options.delete(:sort)
|
2009-01-29 12:15:59 +00:00
|
|
|
hint = options.delete(:hint)
|
|
|
|
if hint
|
|
|
|
hint = normalize_hint_fields(hint)
|
|
|
|
else
|
2009-01-30 19:35:22 +00:00
|
|
|
hint = @hint # assumed to be normalized already
|
2009-01-29 12:15:59 +00:00
|
|
|
end
|
2009-01-07 00:14:45 +00:00
|
|
|
raise RuntimeError, "Unknown options [#{options.inspect}]" unless options.empty?
|
2009-01-29 12:15:59 +00:00
|
|
|
@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={})
|
2009-02-10 18:08:15 +00:00
|
|
|
h = options.dup
|
|
|
|
h[:limit] = 1
|
|
|
|
cursor = find(selector, h)
|
2009-02-26 17:06:03 +00:00
|
|
|
cursor.next_object # don't need to explicitly close b/c of limit
|
2009-02-09 14:46:30 +00:00
|
|
|
end
|
|
|
|
|
2009-01-07 14:45:56 +00:00
|
|
|
# Insert +objects+, which are hashes. "<<" is aliased to this method.
|
2009-01-16 21:10:52 +00:00
|
|
|
# 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)
|
2008-12-05 00:10:00 +00:00
|
|
|
objects = objects.first if objects.size == 1 && objects.first.is_a?(Array)
|
2008-12-08 21:41:52 +00:00
|
|
|
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
|
|
|
|
|
2009-02-26 17:06:03 +00:00
|
|
|
# Create a new index. +field_or_spec+
|
|
|
|
# should be either a single field name or a Array of [field name,
|
|
|
|
# direction] pairs. Directions should be specified as
|
|
|
|
# XGen::Mongo::ASCENDING or XGen::Mongo::DESCENDING.
|
|
|
|
def create_index(field_or_spec)
|
|
|
|
@db.create_index(@name, field_or_spec)
|
2008-11-22 01:00:51 +00:00
|
|
|
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
|
2008-12-08 16:38:42 +00:00
|
|
|
# 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
|
|
|
|
|
2009-01-15 16:25:23 +00:00
|
|
|
# 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
|
|
|
|
|
2009-01-29 12:15:59 +00:00
|
|
|
protected
|
|
|
|
|
|
|
|
def normalize_hint_fields(hint)
|
|
|
|
case hint
|
|
|
|
when String
|
2009-01-30 19:35:22 +00:00
|
|
|
{hint => 1}
|
2009-01-29 12:15:59 +00:00
|
|
|
when Hash
|
2009-01-30 19:35:22 +00:00
|
|
|
hint
|
2009-01-29 12:15:59 +00:00
|
|
|
when nil
|
|
|
|
nil
|
|
|
|
else
|
2009-01-30 19:35:22 +00:00
|
|
|
h = OrderedHash.new
|
|
|
|
hint.to_a.each { |k| h[k] = 1 }
|
|
|
|
h
|
2009-01-29 12:15:59 +00:00
|
|
|
end
|
|
|
|
end
|
2008-11-22 01:00:51 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|