00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 """Collection level utilities for Mongo."""
00016 
00017 import warnings
00018 
00019 from bson.code import Code
00020 from bson.son import SON
00021 from pymongo import (helpers,
00022                      message)
00023 from pymongo.cursor import Cursor
00024 from pymongo.errors import InvalidName, InvalidOperation
00025 
00026 _ZERO = "\x00\x00\x00\x00"
00027 
00028 
00029 def _gen_index_name(keys):
00030     """Generate an index name from the set of fields it is over.
00031     """
00032     return u"_".join([u"%s_%s" % item for item in keys])
00033 
00034 
00035 class Collection(object):
00036     """A Mongo collection.
00037     """
00038 
00039     def __init__(self, database, name, options=None, create=False, **kwargs):
00040         """Get / create a Mongo collection.
00041 
00042         Raises :class:`TypeError` if `name` is not an instance of
00043         :class:`basestring`. Raises
00044         :class:`~pymongo.errors.InvalidName` if `name` is not a valid
00045         collection name. Any additional keyword arguments will be used
00046         as options passed to the create command. See
00047         :meth:`~pymongo.database.Database.create_collection` for valid
00048         options.
00049 
00050         If `create` is ``True`` or additional keyword arguments are
00051         present a create command will be sent. Otherwise, a create
00052         command will not be sent and the collection will be created
00053         implicitly on first use.
00054 
00055         :Parameters:
00056           - `database`: the database to get a collection from
00057           - `name`: the name of the collection to get
00058           - `options`: DEPRECATED dictionary of collection options
00059           - `create` (optional): if ``True``, force collection
00060             creation even without options being set
00061           - `**kwargs` (optional): additional keyword arguments will
00062             be passed as options for the create collection command
00063 
00064         .. versionchanged:: 1.5
00065            deprecating `options` in favor of kwargs
00066         .. versionadded:: 1.5
00067            the `create` parameter
00068 
00069         .. mongodoc:: collections
00070         """
00071         if not isinstance(name, basestring):
00072             raise TypeError("name must be an instance of basestring")
00073 
00074         if options is not None:
00075             warnings.warn("the options argument to Collection is deprecated "
00076                           "and will be removed. please use kwargs instead.",
00077                           DeprecationWarning)
00078             if not isinstance(options, dict):
00079                 raise TypeError("options must be an instance of dict")
00080             options.update(kwargs)
00081         elif kwargs:
00082             options = kwargs
00083 
00084         if not name or ".." in name:
00085             raise InvalidName("collection names cannot be empty")
00086         if "$" in name and not (name.startswith("oplog.$main") or
00087                                 name.startswith("$cmd")):
00088             raise InvalidName("collection names must not "
00089                               "contain '$': %r" % name)
00090         if name[0] == "." or name[-1] == ".":
00091             raise InvalidName("collection names must not start "
00092                               "or end with '.': %r" % name)
00093         if "\x00" in name:
00094             raise InvalidName("collection names must not contain the "
00095                               "null character")
00096 
00097         self.__database = database
00098         self.__name = unicode(name)
00099         self.__full_name = u"%s.%s" % (self.__database.name, self.__name)
00100         if create or options is not None:
00101             self.__create(options)
00102 
00103     def __create(self, options):
00104         """Sends a create command with the given options.
00105         """
00106 
00107         
00108         
00109         if options:
00110             if "size" in options:
00111                 options["size"] = float(options["size"])
00112             self.__database.command("create", self.__name, **options)
00113         else:
00114             self.__database.command("create", self.__name)
00115 
00116     def __getattr__(self, name):
00117         """Get a sub-collection of this collection by name.
00118 
00119         Raises InvalidName if an invalid collection name is used.
00120 
00121         :Parameters:
00122           - `name`: the name of the collection to get
00123         """
00124         return Collection(self.__database, u"%s.%s" % (self.__name, name))
00125 
00126     def __getitem__(self, name):
00127         return self.__getattr__(name)
00128 
00129     def __repr__(self):
00130         return "Collection(%r, %r)" % (self.__database, self.__name)
00131 
00132     def __cmp__(self, other):
00133         if isinstance(other, Collection):
00134             return cmp((self.__database, self.__name),
00135                        (other.__database, other.__name))
00136         return NotImplemented
00137 
00138     @property
00139     def full_name(self):
00140         """The full name of this :class:`Collection`.
00141 
00142         The full name is of the form `database_name.collection_name`.
00143 
00144         .. versionchanged:: 1.3
00145            ``full_name`` is now a property rather than a method.
00146         """
00147         return self.__full_name
00148 
00149     @property
00150     def name(self):
00151         """The name of this :class:`Collection`.
00152 
00153         .. versionchanged:: 1.3
00154            ``name`` is now a property rather than a method.
00155         """
00156         return self.__name
00157 
00158     @property
00159     def database(self):
00160         """The :class:`~pymongo.database.Database` that this
00161         :class:`Collection` is a part of.
00162 
00163         .. versionchanged:: 1.3
00164            ``database`` is now a property rather than a method.
00165         """
00166         return self.__database
00167 
00168     def save(self, to_save, manipulate=True, safe=False, **kwargs):
00169         """Save a document in this collection.
00170 
00171         If `to_save` already has an ``"_id"`` then an :meth:`update`
00172         (upsert) operation is performed and any existing document with
00173         that ``"_id"`` is overwritten.  Otherwise an ``"_id"`` will be
00174         added to `to_save` and an :meth:`insert` operation is
00175         performed. Returns the ``"_id"`` of the saved document.
00176 
00177         Raises :class:`TypeError` if `to_save` is not an instance of
00178         :class:`dict`. If `safe` is ``True`` then the save will be
00179         checked for errors, raising
00180         :class:`~pymongo.errors.OperationFailure` if one
00181         occurred. Safe inserts wait for a response from the database,
00182         while normal inserts do not.
00183 
00184         Any additional keyword arguments imply ``safe=True``, and will
00185         be used as options for the resultant `getLastError`
00186         command. For example, to wait for replication to 3 nodes, pass
00187         ``w=3``.
00188 
00189         :Parameters:
00190           - `to_save`: the document to be saved
00191           - `manipulate` (optional): manipulate the document before
00192             saving it?
00193           - `safe` (optional): check that the save succeeded?
00194           - `**kwargs` (optional): any additional arguments imply
00195             ``safe=True``, and will be used as options for the
00196             `getLastError` command
00197 
00198         .. versionadded:: 1.8
00199            Support for passing `getLastError` options as keyword
00200            arguments.
00201 
00202         .. mongodoc:: insert
00203         """
00204         if not isinstance(to_save, dict):
00205             raise TypeError("cannot save object of type %s" % type(to_save))
00206 
00207         if "_id" not in to_save:
00208             return self.insert(to_save, manipulate, safe, **kwargs)
00209         else:
00210             self.update({"_id": to_save["_id"]}, to_save, True,
00211                         manipulate, safe, **kwargs)
00212             return to_save.get("_id", None)
00213 
00214     def insert(self, doc_or_docs,
00215                manipulate=True, safe=False, check_keys=True, **kwargs):
00216         """Insert a document(s) into this collection.
00217 
00218         If `manipulate` is set, the document(s) are manipulated using
00219         any :class:`~pymongo.son_manipulator.SONManipulator` instances
00220         that have been added to this
00221         :class:`~pymongo.database.Database`. Returns the ``"_id"`` of
00222         the inserted document or a list of ``"_id"`` values of the
00223         inserted documents.  If the document(s) does not already
00224         contain an ``"_id"`` one will be added.
00225 
00226         If `safe` is ``True`` then the insert will be checked for
00227         errors, raising :class:`~pymongo.errors.OperationFailure` if
00228         one occurred. Safe inserts wait for a response from the
00229         database, while normal inserts do not.
00230 
00231         Any additional keyword arguments imply ``safe=True``, and
00232         will be used as options for the resultant `getLastError`
00233         command. For example, to wait for replication to 3 nodes, pass
00234         ``w=3``.
00235 
00236         :Parameters:
00237           - `doc_or_docs`: a document or list of documents to be
00238             inserted
00239           - `manipulate` (optional): manipulate the documents before
00240             inserting?
00241           - `safe` (optional): check that the insert succeeded?
00242           - `check_keys` (optional): check if keys start with '$' or
00243             contain '.', raising :class:`~pymongo.errors.InvalidName`
00244             in either case
00245           - `**kwargs` (optional): any additional arguments imply
00246             ``safe=True``, and will be used as options for the
00247             `getLastError` command
00248 
00249         .. versionadded:: 1.8
00250            Support for passing `getLastError` options as keyword
00251            arguments.
00252         .. versionchanged:: 1.1
00253            Bulk insert works with any iterable
00254 
00255         .. mongodoc:: insert
00256         """
00257         docs = doc_or_docs
00258         return_one = False
00259         if isinstance(docs, dict):
00260             return_one = True
00261             docs = [docs]
00262 
00263         if manipulate:
00264             docs = [self.__database._fix_incoming(doc, self) for doc in docs]
00265 
00266         if kwargs:
00267             safe = True
00268         self.__database.connection._send_message(
00269             message.insert(self.__full_name, docs,
00270                            check_keys, safe, kwargs), safe)
00271 
00272         ids = [doc.get("_id", None) for doc in docs]
00273         return return_one and ids[0] or ids
00274 
00275     def update(self, spec, document, upsert=False, manipulate=False,
00276                safe=False, multi=False, **kwargs):
00277         """Update a document(s) in this collection.
00278 
00279         Raises :class:`TypeError` if either `spec` or `document` is
00280         not an instance of ``dict`` or `upsert` is not an instance of
00281         ``bool``. If `safe` is ``True`` then the update will be
00282         checked for errors, raising
00283         :class:`~pymongo.errors.OperationFailure` if one
00284         occurred. Safe updates require a response from the database,
00285         while normal updates do not - thus, setting `safe` to ``True``
00286         will negatively impact performance.
00287 
00288         There are many useful `update modifiers`_ which can be used
00289         when performing updates. For example, here we use the
00290         ``"$set"`` modifier to modify some fields in a matching
00291         document:
00292 
00293         .. doctest::
00294 
00295           >>> db.test.insert({"x": "y", "a": "b"})
00296           ObjectId('...')
00297           >>> list(db.test.find())
00298           [{u'a': u'b', u'x': u'y', u'_id': ObjectId('...')}]
00299           >>> db.test.update({"x": "y"}, {"$set": {"a": "c"}})
00300           >>> list(db.test.find())
00301           [{u'a': u'c', u'x': u'y', u'_id': ObjectId('...')}]
00302 
00303         If `safe` is ``True`` returns the response to the *lastError*
00304         command. Otherwise, returns ``None``.
00305 
00306         Any additional keyword arguments imply ``safe=True``, and will
00307         be used as options for the resultant `getLastError`
00308         command. For example, to wait for replication to 3 nodes, pass
00309         ``w=3``.
00310 
00311         :Parameters:
00312           - `spec`: a ``dict`` or :class:`~bson.son.SON` instance
00313             specifying elements which must be present for a document
00314             to be updated
00315           - `document`: a ``dict`` or :class:`~bson.son.SON`
00316             instance specifying the document to be used for the update
00317             or (in the case of an upsert) insert - see docs on MongoDB
00318             `update modifiers`_
00319           - `upsert` (optional): perform an upsert if ``True``
00320           - `manipulate` (optional): manipulate the document before
00321             updating? If ``True`` all instances of
00322             :mod:`~pymongo.son_manipulator.SONManipulator` added to
00323             this :class:`~pymongo.database.Database` will be applied
00324             to the document before performing the update.
00325           - `safe` (optional): check that the update succeeded?
00326           - `multi` (optional): update all documents that match
00327             `spec`, rather than just the first matching document. The
00328             default value for `multi` is currently ``False``, but this
00329             might eventually change to ``True``. It is recommended
00330             that you specify this argument explicitly for all update
00331             operations in order to prepare your code for that change.
00332           - `**kwargs` (optional): any additional arguments imply
00333             ``safe=True``, and will be used as options for the
00334             `getLastError` command
00335 
00336         .. versionadded:: 1.8
00337            Support for passing `getLastError` options as keyword
00338            arguments.
00339         .. versionchanged:: 1.4
00340            Return the response to *lastError* if `safe` is ``True``.
00341         .. versionadded:: 1.1.1
00342            The `multi` parameter.
00343 
00344         .. _update modifiers: http://www.mongodb.org/display/DOCS/Updating
00345 
00346         .. mongodoc:: update
00347         """
00348         if not isinstance(spec, dict):
00349             raise TypeError("spec must be an instance of dict")
00350         if not isinstance(document, dict):
00351             raise TypeError("document must be an instance of dict")
00352         if not isinstance(upsert, bool):
00353             raise TypeError("upsert must be an instance of bool")
00354 
00355         if upsert and manipulate:
00356             document = self.__database._fix_incoming(document, self)
00357 
00358         if kwargs:
00359             safe = True
00360 
00361         return self.__database.connection._send_message(
00362             message.update(self.__full_name, upsert, multi,
00363                            spec, document, safe, kwargs), safe)
00364 
00365     def drop(self):
00366         """Alias for :meth:`~pymongo.database.Database.drop_collection`.
00367 
00368         The following two calls are equivalent:
00369 
00370           >>> db.foo.drop()
00371           >>> db.drop_collection("foo")
00372 
00373         .. versionadded:: 1.8
00374         """
00375         self.__database.drop_collection(self.__name)
00376 
00377     def remove(self, spec_or_id=None, safe=False, **kwargs):
00378         """Remove a document(s) from this collection.
00379 
00380         .. warning:: Calls to :meth:`remove` should be performed with
00381            care, as removed data cannot be restored.
00382 
00383         If `safe` is ``True`` then the remove operation will be
00384         checked for errors, raising
00385         :class:`~pymongo.errors.OperationFailure` if one
00386         occurred. Safe removes wait for a response from the database,
00387         while normal removes do not.
00388 
00389         If `spec_or_id` is ``None``, all documents in this collection
00390         will be removed. This is not equivalent to calling
00391         :meth:`~pymongo.database.Database.drop_collection`, however,
00392         as indexes will not be removed.
00393 
00394         If `safe` is ``True`` returns the response to the *lastError*
00395         command. Otherwise, returns ``None``.
00396 
00397         Any additional keyword arguments imply ``safe=True``, and will
00398         be used as options for the resultant `getLastError`
00399         command. For example, to wait for replication to 3 nodes, pass
00400         ``w=3``.
00401 
00402         :Parameters:
00403           - `spec_or_id` (optional): a dictionary specifying the
00404             documents to be removed OR any other type specifying the
00405             value of ``"_id"`` for the document to be removed
00406           - `safe` (optional): check that the remove succeeded?
00407           - `**kwargs` (optional): any additional arguments imply
00408             ``safe=True``, and will be used as options for the
00409             `getLastError` command
00410 
00411         .. versionadded:: 1.8
00412            Support for passing `getLastError` options as keyword arguments.
00413         .. versionchanged:: 1.7 Accept any type other than a ``dict``
00414            instance for removal by ``"_id"``, not just
00415            :class:`~bson.objectid.ObjectId` instances.
00416         .. versionchanged:: 1.4
00417            Return the response to *lastError* if `safe` is ``True``.
00418         .. versionchanged:: 1.2
00419            The `spec_or_id` parameter is now optional. If it is
00420            not specified *all* documents in the collection will be
00421            removed.
00422         .. versionadded:: 1.1
00423            The `safe` parameter.
00424 
00425         .. mongodoc:: remove
00426         """
00427         if spec_or_id is None:
00428             spec_or_id = {}
00429         if not isinstance(spec_or_id, dict):
00430             spec_or_id = {"_id": spec_or_id}
00431 
00432         if kwargs:
00433             safe = True
00434 
00435         return self.__database.connection._send_message(
00436             message.delete(self.__full_name, spec_or_id, safe, kwargs), safe)
00437 
00438     def find_one(self, spec_or_id=None, *args, **kwargs):
00439         """Get a single document from the database.
00440 
00441         All arguments to :meth:`find` are also valid arguments for
00442         :meth:`find_one`, although any `limit` argument will be
00443         ignored. Returns a single document, or ``None`` if no matching
00444         document is found.
00445 
00446         :Parameters:
00447 
00448           - `spec_or_id` (optional): a dictionary specifying
00449             the query to be performed OR any other type to be used as
00450             the value for a query for ``"_id"``.
00451 
00452           - `*args` (optional): any additional positional arguments
00453             are the same as the arguments to :meth:`find`.
00454 
00455           - `**kwargs` (optional): any additional keyword arguments
00456             are the same as the arguments to :meth:`find`.
00457 
00458         .. versionchanged:: 1.7
00459            Allow passing any of the arguments that are valid for
00460            :meth:`find`.
00461 
00462         .. versionchanged:: 1.7 Accept any type other than a ``dict``
00463            instance as an ``"_id"`` query, not just
00464            :class:`~bson.objectid.ObjectId` instances.
00465         """
00466         if spec_or_id is not None and not isinstance(spec_or_id, dict):
00467             spec_or_id = {"_id": spec_or_id}
00468 
00469         for result in self.find(spec_or_id, *args, **kwargs).limit(-1):
00470             return result
00471         return None
00472 
00473     def find(self, *args, **kwargs):
00474         """Query the database.
00475 
00476         The `spec` argument is a prototype document that all results
00477         must match. For example:
00478 
00479         >>> db.test.find({"hello": "world"})
00480 
00481         only matches documents that have a key "hello" with value
00482         "world".  Matches can have other keys *in addition* to
00483         "hello". The `fields` argument is used to specify a subset of
00484         fields that should be included in the result documents. By
00485         limiting results to a certain subset of fields you can cut
00486         down on network traffic and decoding time.
00487 
00488         Raises :class:`TypeError` if any of the arguments are of
00489         improper type. Returns an instance of
00490         :class:`~pymongo.cursor.Cursor` corresponding to this query.
00491 
00492         :Parameters:
00493           - `spec` (optional): a SON object specifying elements which
00494             must be present for a document to be included in the
00495             result set
00496           - `fields` (optional): a list of field names that should be
00497             returned in the result set ("_id" will always be
00498             included), or a dict specifying the fields to return
00499           - `skip` (optional): the number of documents to omit (from
00500             the start of the result set) when returning the results
00501           - `limit` (optional): the maximum number of results to
00502             return
00503           - `timeout` (optional): if True, any returned cursor will be
00504             subject to the normal timeout behavior of the mongod
00505             process. Otherwise, the returned cursor will never timeout
00506             at the server. Care should be taken to ensure that cursors
00507             with timeout turned off are properly closed.
00508           - `snapshot` (optional): if True, snapshot mode will be used
00509             for this query. Snapshot mode assures no duplicates are
00510             returned, or objects missed, which were present at both
00511             the start and end of the query's execution. For details,
00512             see the `snapshot documentation
00513             <http://dochub.mongodb.org/core/snapshot>`_.
00514           - `tailable` (optional): the result of this find call will
00515             be a tailable cursor - tailable cursors aren't closed when
00516             the last data is retrieved but are kept open and the
00517             cursors location marks the final document's position. if
00518             more data is received iteration of the cursor will
00519             continue from the last document received. For details, see
00520             the `tailable cursor documentation
00521             <http://www.mongodb.org/display/DOCS/Tailable+Cursors>`_.
00522           - `sort` (optional): a list of (key, direction) pairs
00523             specifying the sort order for this query. See
00524             :meth:`~pymongo.cursor.Cursor.sort` for details.
00525           - `max_scan` (optional): limit the number of documents
00526             examined when performing the query
00527           - `as_class` (optional): class to use for documents in the
00528             query result (default is
00529             :attr:`~pymongo.connection.Connection.document_class`)
00530           - `network_timeout` (optional): specify a timeout to use for
00531             this query, which will override the
00532             :class:`~pymongo.connection.Connection`-level default
00533 
00534         .. note:: The `max_scan` parameter requires server
00535            version **>= 1.5.1**
00536 
00537         .. versionadded:: 1.8
00538            The `network_timeout` parameter.
00539 
00540         .. versionadded:: 1.7
00541            The `sort`, `max_scan` and `as_class` parameters.
00542 
00543         .. versionchanged:: 1.7
00544            The `fields` parameter can now be a dict or any iterable in
00545            addition to a list.
00546 
00547         .. versionadded:: 1.1
00548            The `tailable` parameter.
00549 
00550         .. mongodoc:: find
00551         """
00552         return Cursor(self, *args, **kwargs)
00553 
00554     def count(self):
00555         """Get the number of documents in this collection.
00556 
00557         To get the number of documents matching a specific query use
00558         :meth:`pymongo.cursor.Cursor.count`.
00559         """
00560         return self.find().count()
00561 
00562     def create_index(self, key_or_list, deprecated_unique=None,
00563                      ttl=300, **kwargs):
00564         """Creates an index on this collection.
00565 
00566         Takes either a single key or a list of (key, direction) pairs.
00567         The key(s) must be an instance of :class:`basestring`, and the
00568         directions must be one of (:data:`~pymongo.ASCENDING`,
00569         :data:`~pymongo.DESCENDING`, :data:`~pymongo.GEO2D`). Returns
00570         the name of the created index.
00571 
00572         To create a single key index on the key ``'mike'`` we just use
00573         a string argument:
00574 
00575         >>> my_collection.create_index("mike")
00576 
00577         For a compound index on ``'mike'`` descending and ``'eliot'``
00578         ascending we need to use a list of tuples:
00579 
00580         >>> my_collection.create_index([("mike", pymongo.DESCENDING),
00581         ...                             ("eliot", pymongo.ASCENDING)])
00582 
00583         All optional index creation paramaters should be passed as
00584         keyword arguments to this method. Valid options include:
00585 
00586           - `name`: custom name to use for this index - if none is
00587             given, a name will be generated
00588           - `unique`: should this index guarantee uniqueness?
00589           - `dropDups` or `drop_dups`: should we drop duplicates
00590             during index creation when creating a unique index?
00591           - `min`: minimum value for keys in a :data:`~pymongo.GEO2D`
00592             index
00593           - `max`: maximum value for keys in a :data:`~pymongo.GEO2D`
00594             index
00595 
00596         :Parameters:
00597           - `key_or_list`: a single key or a list of (key, direction)
00598             pairs specifying the index to create
00599           - `deprecated_unique`: DEPRECATED - use `unique` as a kwarg
00600           - `ttl` (optional): time window (in seconds) during which
00601             this index will be recognized by subsequent calls to
00602             :meth:`ensure_index` - see documentation for
00603             :meth:`ensure_index` for details
00604           - `**kwargs` (optional): any additional index creation
00605             options (see the above list) should be passed as keyword
00606             arguments
00607 
00608         .. versionchanged:: 1.5.1
00609            Accept kwargs to support all index creation options.
00610 
00611         .. versionadded:: 1.5
00612            The `name` parameter.
00613 
00614         .. seealso:: :meth:`ensure_index`
00615 
00616         .. mongodoc:: indexes
00617         """
00618         keys = helpers._index_list(key_or_list)
00619         index_doc = helpers._index_document(keys)
00620 
00621         index = {"key": index_doc, "ns": self.__full_name}
00622 
00623         if deprecated_unique is not None:
00624             warnings.warn("using a positional arg to specify unique is "
00625                           "deprecated, please use kwargs",
00626                           DeprecationWarning)
00627             index["unique"] = deprecated_unique
00628 
00629         name = "name" in kwargs and kwargs["name"] or _gen_index_name(keys)
00630         index["name"] = name
00631 
00632         if "drop_dups" in kwargs:
00633             kwargs["dropDups"] = kwargs.pop("drop_dups")
00634 
00635         index.update(kwargs)
00636 
00637         self.__database.system.indexes.insert(index, manipulate=False,
00638                                               check_keys=False,
00639                                               safe=True)
00640 
00641         self.__database.connection._cache_index(self.__database.name,
00642                                                 self.__name, name, ttl)
00643 
00644         return name
00645 
00646     def ensure_index(self, key_or_list, deprecated_unique=None,
00647                      ttl=300, **kwargs):
00648         """Ensures that an index exists on this collection.
00649 
00650         Takes either a single key or a list of (key, direction) pairs.
00651         The key(s) must be an instance of :class:`basestring`, and the
00652         direction(s) must be one of (:data:`~pymongo.ASCENDING`,
00653         :data:`~pymongo.DESCENDING`, :data:`~pymongo.GEO2D`). See
00654         :meth:`create_index` for a detailed example.
00655 
00656         Unlike :meth:`create_index`, which attempts to create an index
00657         unconditionally, :meth:`ensure_index` takes advantage of some
00658         caching within the driver such that it only attempts to create
00659         indexes that might not already exist. When an index is created
00660         (or ensured) by PyMongo it is "remembered" for `ttl`
00661         seconds. Repeated calls to :meth:`ensure_index` within that
00662         time limit will be lightweight - they will not attempt to
00663         actually create the index.
00664 
00665         Care must be taken when the database is being accessed through
00666         multiple connections at once. If an index is created using
00667         PyMongo and then deleted using another connection any call to
00668         :meth:`ensure_index` within the cache window will fail to
00669         re-create the missing index.
00670 
00671         Returns the name of the created index if an index is actually
00672         created. Returns ``None`` if the index already exists.
00673 
00674         All optional index creation paramaters should be passed as
00675         keyword arguments to this method. Valid options include:
00676 
00677           - `name`: custom name to use for this index - if none is
00678             given, a name will be generated
00679           - `unique`: should this index guarantee uniqueness?
00680           - `dropDups` or `drop_dups`: should we drop duplicates
00681             during index creation when creating a unique index?
00682           - `background`: if this index should be created in the
00683             background
00684           - `min`: minimum value for keys in a :data:`~pymongo.GEO2D`
00685             index
00686           - `max`: maximum value for keys in a :data:`~pymongo.GEO2D`
00687             index
00688 
00689         :Parameters:
00690           - `key_or_list`: a single key or a list of (key, direction)
00691             pairs specifying the index to create
00692           - `deprecated_unique`: DEPRECATED - use `unique` as a kwarg
00693           - `ttl` (optional): time window (in seconds) during which
00694             this index will be recognized by subsequent calls to
00695             :meth:`ensure_index`
00696           - `**kwargs` (optional): any additional index creation
00697             options (see the above list) should be passed as keyword
00698             arguments
00699 
00700         .. versionchanged:: 1.5.1
00701            Accept kwargs to support all index creation options.
00702 
00703         .. versionadded:: 1.5
00704            The `name` parameter.
00705 
00706         .. seealso:: :meth:`create_index`
00707         """
00708         if "name" in kwargs:
00709             name = kwargs["name"]
00710         else:
00711             keys = helpers._index_list(key_or_list)
00712             name = kwargs["name"] = _gen_index_name(keys)
00713 
00714         if self.__database.connection._cache_index(self.__database.name,
00715                                                    self.__name, name, ttl):
00716             return self.create_index(key_or_list, deprecated_unique,
00717                                      ttl, **kwargs)
00718         return None
00719 
00720     def drop_indexes(self):
00721         """Drops all indexes on this collection.
00722 
00723         Can be used on non-existant collections or collections with no indexes.
00724         Raises OperationFailure on an error.
00725         """
00726         self.__database.connection._purge_index(self.__database.name,
00727                                                 self.__name)
00728         self.drop_index(u"*")
00729 
00730     def drop_index(self, index_or_name):
00731         """Drops the specified index on this collection.
00732 
00733         Can be used on non-existant collections or collections with no
00734         indexes.  Raises OperationFailure on an error. `index_or_name`
00735         can be either an index name (as returned by `create_index`),
00736         or an index specifier (as passed to `create_index`). An index
00737         specifier should be a list of (key, direction) pairs. Raises
00738         TypeError if index is not an instance of (str, unicode, list).
00739 
00740         .. warning:: if a custom name was used on index creation (by
00741           passing the `name` parameter to :meth:`create_index` or
00742           :meth:`ensure_index`) the index **must** be dropped by name.
00743 
00744         :Parameters:
00745           - `index_or_name`: index (or name of index) to drop
00746         """
00747         name = index_or_name
00748         if isinstance(index_or_name, list):
00749             name = _gen_index_name(index_or_name)
00750 
00751         if not isinstance(name, basestring):
00752             raise TypeError("index_or_name must be an index name or list")
00753 
00754         self.__database.connection._purge_index(self.__database.name,
00755                                                 self.__name, name)
00756         self.__database.command("dropIndexes", self.__name, index=name,
00757                                 allowable_errors=["ns not found"])
00758 
00759     def index_information(self):
00760         """Get information on this collection's indexes.
00761 
00762         Returns a dictionary where the keys are index names (as
00763         returned by create_index()) and the values are dictionaries
00764         containing information about each index. The dictionary is
00765         guaranteed to contain at least a single key, ``"key"`` which
00766         is a list of (key, direction) pairs specifying the index (as
00767         passed to create_index()). It will also contain any other
00768         information in `system.indexes`, except for the ``"ns"`` and
00769         ``"name"`` keys, which are cleaned. Example output might look
00770         like this:
00771 
00772         >>> db.test.ensure_index("x", unique=True)
00773         u'x_1'
00774         >>> db.test.index_information()
00775         {u'_id_': {u'key': [(u'_id', 1)]},
00776          u'x_1': {u'unique': True, u'key': [(u'x', 1)]}}
00777 
00778 
00779         .. versionchanged:: 1.7
00780            The values in the resultant dictionary are now dictionaries
00781            themselves, whose ``"key"`` item contains the list that was
00782            the value in previous versions of PyMongo.
00783         """
00784         raw = self.__database.system.indexes.find({"ns": self.__full_name},
00785                                                   {"ns": 0}, as_class=SON)
00786         info = {}
00787         for index in raw:
00788             index["key"] = index["key"].items()
00789             index = dict(index)
00790             info[index.pop("name")] = index
00791         return info
00792 
00793     def options(self):
00794         """Get the options set on this collection.
00795 
00796         Returns a dictionary of options and their values - see
00797         :meth:`~pymongo.database.Database.create_collection` for more
00798         information on the possible options. Returns an empty
00799         dictionary if the collection has not been created yet.
00800         """
00801         result = self.__database.system.namespaces.find_one(
00802             {"name": self.__full_name})
00803 
00804         if not result:
00805             return {}
00806 
00807         options = result.get("options", {})
00808         if "create" in options:
00809             del options["create"]
00810 
00811         return options
00812 
00813     
00814     
00815     def group(self, key, condition, initial, reduce, finalize=None,
00816               command=True):
00817         """Perform a query similar to an SQL *group by* operation.
00818 
00819         Returns an array of grouped items.
00820 
00821         The `key` parameter can be:
00822 
00823           - ``None`` to use the entire document as a key.
00824           - A :class:`list` of keys (each a :class:`basestring`) to group by.
00825           - A :class:`basestring` or :class:`~bson.code.Code` instance
00826             containing a JavaScript function to be applied to each
00827             document, returning the key to group by.
00828 
00829         :Parameters:
00830           - `key`: fields to group by (see above description)
00831           - `condition`: specification of rows to be
00832             considered (as a :meth:`find` query specification)
00833           - `initial`: initial value of the aggregation counter object
00834           - `reduce`: aggregation function as a JavaScript string
00835           - `finalize`: function to be called on each object in output list.
00836           - `command` (optional): DEPRECATED if ``True``, run the group as a
00837             command instead of in an eval - this option is deprecated and
00838             will be removed in favor of running all groups as commands
00839 
00840         .. versionchanged:: 1.4
00841            The `key` argument can now be ``None`` or a JavaScript function,
00842            in addition to a :class:`list` of keys.
00843         .. versionchanged:: 1.3
00844            The `command` argument now defaults to ``True`` and is deprecated.
00845         """
00846         if not command:
00847             warnings.warn("eval-based groups are deprecated, and the "
00848                           "command option will be removed.",
00849                           DeprecationWarning)
00850 
00851         group = {}
00852         if isinstance(key, basestring):
00853             group["$keyf"] = Code(key)
00854         elif key is not None:
00855             group = {"key": helpers._fields_list_to_dict(key)}
00856         group["ns"] = self.__name
00857         group["$reduce"] = Code(reduce)
00858         group["cond"] = condition
00859         group["initial"] = initial
00860         if finalize is not None:
00861             group["finalize"] = Code(finalize)
00862 
00863         return self.__database.command("group", group)["retval"]
00864 
00865     def rename(self, new_name, **kwargs):
00866         """Rename this collection.
00867 
00868         If operating in auth mode, client must be authorized as an
00869         admin to perform this operation. Raises :class:`TypeError` if
00870         `new_name` is not an instance of :class:`basestring`. Raises
00871         :class:`~pymongo.errors.InvalidName` if `new_name` is not a
00872         valid collection name.
00873 
00874         :Parameters:
00875           - `new_name`: new name for this collection
00876           - `**kwargs` (optional): any additional rename options
00877             should be passed as keyword arguments
00878             (i.e. ``dropTarget=True``)
00879 
00880         .. versionadded:: 1.7
00881            support for accepting keyword arguments for rename options
00882         """
00883         if not isinstance(new_name, basestring):
00884             raise TypeError("new_name must be an instance of basestring")
00885 
00886         if not new_name or ".." in new_name:
00887             raise InvalidName("collection names cannot be empty")
00888         if new_name[0] == "." or new_name[-1] == ".":
00889             raise InvalidName("collecion names must not start or end with '.'")
00890         if "$" in new_name and not new_name.startswith("oplog.$main"):
00891             raise InvalidName("collection names must not contain '$'")
00892 
00893         new_name = "%s.%s" % (self.__database.name, new_name)
00894         self.__database.connection.admin.command("renameCollection",
00895                                                  self.__full_name,
00896                                                  to=new_name, **kwargs)
00897 
00898     def distinct(self, key):
00899         """Get a list of distinct values for `key` among all documents
00900         in this collection.
00901 
00902         Raises :class:`TypeError` if `key` is not an instance of
00903         :class:`basestring`.
00904 
00905         To get the distinct values for a key in the result set of a
00906         query use :meth:`~pymongo.cursor.Cursor.distinct`.
00907 
00908         :Parameters:
00909           - `key`: name of key for which we want to get the distinct values
00910 
00911         .. note:: Requires server version **>= 1.1.0**
00912 
00913         .. versionadded:: 1.1.1
00914         """
00915         return self.find().distinct(key)
00916 
00917     def map_reduce(self, map, reduce, out, merge_output=False,
00918                    reduce_output=False, full_response=False, **kwargs):
00919         """Perform a map/reduce operation on this collection.
00920 
00921         If `full_response` is ``False`` (default) returns a
00922         :class:`~pymongo.collection.Collection` instance containing
00923         the results of the operation. Otherwise, returns the full
00924         response from the server to the `map reduce command`_.
00925 
00926         :Parameters:
00927           - `map`: map function (as a JavaScript string)
00928           - `reduce`: reduce function (as a JavaScript string)
00929           - `out` (required): output collection name
00930           - `merge_output` (optional): Merge output into `out`. If the same
00931             key exists in both the result set and the existing output collection,
00932             the new key will overwrite the existing key
00933           - `reduce_output` (optional): If documents exist for a given key
00934             in the result set and in the existing output collection, then a
00935             reduce operation (using the specified reduce function) will be
00936             performed on the two values and the result will be written to
00937             the output collection
00938           - `full_response` (optional): if ``True``, return full response to
00939             this command - otherwise just return the result collection
00940           - `**kwargs` (optional): additional arguments to the
00941             `map reduce command`_ may be passed as keyword arguments to this
00942             helper method, e.g.::
00943 
00944             >>> db.test.map_reduce(map, reduce, "myresults", limit=2)
00945 
00946         .. note:: Requires server version **>= 1.1.1**
00947 
00948         .. seealso:: :doc:`/examples/map_reduce`
00949 
00950         .. versionadded:: 1.2
00951 
00952         .. _map reduce command: http://www.mongodb.org/display/DOCS/MapReduce
00953 
00954         .. mongodoc:: mapreduce
00955         """
00956         if not isinstance(out, basestring):
00957             raise TypeError("'out' must be an instance of basestring")
00958 
00959         if merge_output and reduce_output:
00960             raise InvalidOperation("Can't do both merge and re-reduce of output.")
00961 
00962         if merge_output:
00963             out_conf = {"merge": out}
00964         elif reduce_output:
00965             out_conf = {"reduce": out}
00966         else:
00967             out_conf = out
00968 
00969         response = self.__database.command("mapreduce", self.__name,
00970                                            map=map, reduce=reduce,
00971                                            out=out_conf, **kwargs)
00972         if full_response:
00973             return response
00974         else:
00975             return self.__database[response["result"]]
00976 
00977     def inline_map_reduce(self, map, reduce, full_response=False, **kwargs):
00978         """Perform an inline map/reduce operation on this collection.
00979 
00980         Perform the map/reduce operation on the server in RAM. A result
00981         collection is not created. The result set is returned as a list
00982         of documents.
00983 
00984         If `full_response` is ``False`` (default) returns the
00985         result documents in a list. Otherwise, returns the full
00986         response from the server to the `map reduce command`_.
00987 
00988         :Parameters:
00989           - `map`: map function (as a JavaScript string)
00990           - `reduce`: reduce function (as a JavaScript string)
00991           - `full_response` (optional): if ``True``, return full response to
00992             this command - otherwise just return the result collection
00993           - `**kwargs` (optional): additional arguments to the
00994             `map reduce command`_ may be passed as keyword arguments to this
00995             helper method, e.g.::
00996 
00997             >>> db.test.inline_map_reduce(map, reduce, limit=2)
00998 
00999         .. note:: Requires server version **>= 1.7.4**
01000 
01001         .. versionadded:: 1.10
01002         """
01003 
01004         response = self.__database.command("mapreduce", self.__name,
01005                                            map=map, reduce=reduce,
01006                                            out={"inline": 1}, **kwargs)
01007 
01008         if full_response:
01009             return response
01010         else:
01011             return response.get("results")
01012 
01013     def find_and_modify(self, query={}, update=None, upsert=False, **kwargs):
01014         """Update and return an object.
01015 
01016         This is a thin wrapper around the findAndModify_ command. The
01017         positional arguments are designed to match the first three arguments
01018         to :meth:`update` however most options should be passed as named
01019         parameters. Either `update` or `remove` arguments are required, all
01020         others are optional.
01021 
01022         Returns either the object before or after modification based on `new`
01023         parameter. If no objects match the `query` and `upsert` is false,
01024         returns ``None``. If upserting and `new` is false, returns ``{}``.
01025 
01026         :Parameters:
01027             - `query`: filter for the update (default ``{}``)
01028             - `sort`: priority if multiple objects match (default ``{}``)
01029             - `update`: see second argument to :meth:`update` (no default)
01030             - `remove`: remove rather than updating (default ``False``)
01031             - `new`: return updated rather than original object
01032               (default ``False``)
01033             - `fields`: see second argument to :meth:`find` (default all)
01034             - `upsert`: insert if object doesn't exist (default ``False``)
01035             - `**kwargs`: any other options the findAndModify_ command
01036               supports can be passed here.
01037 
01038 
01039         .. mongodoc:: findAndModify
01040 
01041         .. _findAndModify: http://dochub.mongodb.org/core/findAndModify
01042 
01043         .. note:: Requires server version **>= 1.3.0**
01044 
01045         .. versionadded:: 1.10
01046         """
01047         if (not update and not kwargs.get('remove', None)):
01048             raise ValueError("Must either update or remove")
01049 
01050         if (update and kwargs.get('remove', None)):
01051             raise ValueError("Can't do both update and remove")
01052 
01053         
01054         if query: kwargs['query'] = query
01055         if update: kwargs['update'] = update
01056         if upsert: kwargs['upsert'] = upsert
01057 
01058         no_obj_error = "No matching object found"
01059 
01060         out = self.__database.command("findAndModify", self.__name,
01061                 allowable_errors=[no_obj_error], **kwargs)
01062 
01063         if not out['ok']:
01064             if out["errmsg"] == no_obj_error:
01065                 return None
01066             else:
01067                 
01068                 raise ValueError("Unexpected Error: %s"%out)
01069 
01070         return out.get('value')
01071 
01072     def __iter__(self):
01073         return self
01074 
01075     def next(self):
01076         raise TypeError("'Collection' object is not iterable")
01077 
01078     def __call__(self, *args, **kwargs):
01079         """This is only here so that some API misusages are easier to debug.
01080         """
01081         if "." not in self.__name:
01082             raise TypeError("'Collection' object is not callable. If you "
01083                             "meant to call the '%s' method on a 'Database' "
01084                             "object it is failing because no such method "
01085                             "exists." %
01086                             self.__name)
01087         raise TypeError("'Collection' object is not callable. If you meant to "
01088                         "call the '%s' method on a 'Collection' object it is "
01089                         "failing because no such method exists." %
01090                         self.__name.split(".")[-1])