2
# -*- coding: utf-8 -*-
3
# Copyright (c) 2009-2011, Nicolas Clairon
5
# Redistribution and use in source and binary forms, with or without
6
# modification, are permitted provided that the following conditions are met:
8
# * Redistributions of source code must retain the above copyright
9
# notice, this list of conditions and the following disclaimer.
10
# * Redistributions in binary form must reproduce the above copyright
11
# notice, this list of conditions and the following disclaimer in the
12
# documentation and/or other materials provided with the distribution.
13
# * Neither the name of the University of California, Berkeley nor the
14
# names of its contributors may be used to endorse or promote products
15
# derived from this software without specific prior written permission.
17
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
18
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20
# DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
21
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
from pymongo.collection import Collection as PymongoCollection
29
from mongo_exceptions import MultipleResultsFound
30
from cursor import Cursor
32
from warnings import warn
34
class Collection(PymongoCollection):
36
def __init__(self, *args, **kwargs):
38
self._collections = {}
39
super(Collection, self).__init__(*args, **kwargs)
40
self._registered_documents = self.database.connection._registered_documents
42
def __getattr__(self, key):
43
if key in self._registered_documents:
44
if not key in self._documents:
45
self._documents[key] = self._registered_documents[key](collection=self)
46
if self._documents[key].indexes:
47
warn('%s: Be careful, index generation is not automatic anymore.'
48
'You have to generate your index youself' % self._documents[key]._obj_class.__name__,
50
#self._documents[key].generate_index(self)
51
return self._documents[key]
53
newkey = u"%s.%s" % (self.name, key)
54
if not newkey in self._collections:
55
self._collections[newkey] = Collection(self.database, newkey)
56
return self._collections[newkey]
58
def __call__(self, *args, **kwargs):
59
if "." not in self.__name:
60
raise TypeError("'Collection' object is not callable. If you "
61
"meant to call the '%s' method on a 'Database' "
62
"object it is failing because no such method "
65
name = self.__name.split(".")[-1]
66
raise TypeError("'Collection' object is not callable. "
67
"If you meant to call the '%s' method on a 'Collection' "
68
"object it is failing because no such method exists.\n"
69
"If '%s' is a Document then you may have forgotten to "
70
"register it to the connection." % (name, name))
72
def find(self, *args, **kwargs):
73
return Cursor(self, *args, **kwargs)
74
find.__doc__ = PymongoCollection.find.__doc__ + """
76
- `wrap` (optional): a class object used to wrap
77
documents in the query result
80
def get_from_id(self, id):
82
return the document wich has the id
84
return self.find_one({"_id":id})
86
def one(self, *args, **kwargs):
87
bson_obj = self.find(*args, **kwargs)
88
count = bson_obj.count()
90
raise MultipleResultsFound("%s results found" % count)
92
return bson_obj.next()
94
def find_random(self):
96
return one random document from the collection
101
num = random.randint(0, max-1)
102
return self.find().skip(num).next()