Skip to content

Commit 01e90d6

Browse files
committed
1 parent dfad91a commit 01e90d6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1998
-334
lines changed

CONTRIBUTORS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
* kryton (http://github.com/kryton)
2+
3+
For an up-to-date list of contributors, see
4+
http://github.com/django-mongodb-engine/mongodb-engine/contributors.

django_mongodb_engine/__init__.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
#!/usr/bin/python
22
# -*- coding: utf-8 -*-
33

4-
import logging
5-
logger = logging.getLogger(__name__)
4+
__version__ = (0, 2, 0)
5+
__author__ = "Flavio Percoco Premoli, Alberto Paro, Jonas Haag and contributors"
6+
__contact__ = "[email protected]"
7+
__homepage__ = "http://github.com/django-mongodb-engine/mongodb-engine"
8+
__docformat__ = "restructuredtext"
69

7-
VERSION = (0, 1, 1)
8-
9-
__version__ = ".".join(map(str, VERSION[0:3])) + "".join(VERSION[3:])
10-
__author__ = "Flavio Percoco Premoli"
11-
__contact__ = "[email protected]"
12-
__homepage__ = "http://github.com/FlaPer87/django-mongodb-engine/"
13-
__docformat__ = "restructuredtext"
10+
try:
11+
from django.conf import settings
12+
import _bootstrap
13+
except ImportError:
14+
pass

django_mongodb_engine/_bootstrap.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from django.db import models
2+
3+
def class_prepared_mongodb_signal(sender, *args, **kwargs):
4+
mongo_meta = getattr(sender, 'MongoMeta', None)
5+
if mongo_meta is not None:
6+
for attr, value in mongo_meta.items():
7+
if not attr.startswith('_'):
8+
setattr(model._meta, attr, value)
9+
10+
models.signals.class_prepared.connect(class_prepared_mongodb_signal)

django_mongodb_engine/base.py

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
from django.core.exceptions import ImproperlyConfigured
2+
3+
import pymongo
4+
from .creation import DatabaseCreation
5+
from .client import DatabaseClient
6+
7+
from djangotoolbox.db.base import (
8+
NonrelDatabaseFeatures, NonrelDatabaseWrapper,
9+
NonrelDatabaseClient, NonrelDatabaseValidation,
10+
NonrelDatabaseIntrospection, NonrelDatabaseOperations
11+
)
12+
13+
class ImproperlyConfiguredWarning(Warning):
14+
pass
15+
16+
class DatabaseFeatures(NonrelDatabaseFeatures):
17+
string_based_auto_field = True
18+
19+
20+
class DatabaseOperations(NonrelDatabaseOperations):
21+
compiler_module = __name__.rsplit('.', 1)[0] + '.compiler'
22+
23+
def max_name_length(self):
24+
return 254
25+
26+
def check_aggregate_support(self, aggregate):
27+
from django.db.models.sql.aggregates import Max, Count
28+
if not isinstance(aggregate, (Count)):
29+
raise NotImplementedError("This database does not support %r "
30+
"aggregates" % type(aggregate))
31+
32+
def sql_flush(self, style, tables, sequence_list):
33+
"""
34+
Returns a list of SQL statements that have to be executed to drop
35+
all `tables`. No SQL in MongoDB, so just drop all tables here and
36+
return an empty list.
37+
"""
38+
tables = self.connection.db_connection.collection_names()
39+
for table in tables:
40+
if table.startswith('system.'):
41+
# no do not system collections
42+
continue
43+
self.connection.db_connection.drop_collection(table)
44+
return []
45+
46+
class DatabaseValidation(NonrelDatabaseValidation):
47+
pass
48+
49+
class DatabaseIntrospection(NonrelDatabaseIntrospection):
50+
"""Database Introspection"""
51+
52+
def table_names(self):
53+
""" Show defined models """
54+
return self.connection.db_connection.collection_names()
55+
56+
def sequence_list(self):
57+
# Only required for backends that support ManyToMany relations
58+
pass
59+
60+
class DatabaseWrapper(NonrelDatabaseWrapper):
61+
safe_inserts = False
62+
wait_for_slaves = 0
63+
_connected = False
64+
65+
def __init__(self, *args, **kwargs):
66+
super(DatabaseWrapper, self).__init__(*args, **kwargs)
67+
self.features = DatabaseFeatures(self)
68+
self.ops = DatabaseOperations(self)
69+
self.client = DatabaseClient(self)
70+
self.creation = DatabaseCreation(self)
71+
self.validation = DatabaseValidation(self)
72+
self.introspection = DatabaseIntrospection(self)
73+
74+
def _cursor(self):
75+
self._connect()
76+
return self._connection
77+
78+
@property
79+
def db_connection(self):
80+
"""
81+
Returns the db_connection instance (a :class:`pymongo.database.Database`)
82+
"""
83+
self._connect()
84+
return self._db_connection
85+
86+
def _connect(self):
87+
if not self._connected:
88+
host = self.settings_dict['HOST'] or None
89+
port = self.settings_dict['PORT'] or None
90+
user = self.settings_dict.get('USER', None)
91+
password = self.settings_dict.get('PASSWORD')
92+
self.db_name = self.settings_dict['NAME']
93+
self.safe_inserts = self.settings_dict.get('SAFE_INSERTS', False)
94+
self.wait_for_slaves = self.settings_dict.get('WAIT_FOR_SLAVES', 0)
95+
slave_okay = self.settings_dict.get('SLAVE_OKAY', False)
96+
97+
try:
98+
if host is not None:
99+
if pymongo.version >= '1.8':
100+
assert isinstance(host, (basestring, list)), \
101+
'If set, HOST must be a string or a list of strings'
102+
else:
103+
assert isinstance(host, basestring), 'If set, HOST must be a string'
104+
105+
if port:
106+
if isinstance(host, basestring) and host.startswith('mongodb://'):
107+
# If host starts with mongodb:// the port will be
108+
# ignored so lets make sure it is None
109+
port = None
110+
import warnings
111+
warnings.warn(
112+
"If 'HOST' is a mongodb:// URL, the 'PORT' setting "
113+
"will be ignored", ImproperlyConfiguredWarning
114+
)
115+
else:
116+
try:
117+
port = int(port)
118+
except ValueError:
119+
raise ImproperlyConfigured('If set, PORT must be an integer')
120+
121+
assert isinstance(self.safe_inserts, bool), 'If set, SAFE_INSERTS must be True or False'
122+
assert isinstance(self.wait_for_slaves, int), 'If set, WAIT_FOR_SLAVES must be an integer'
123+
except AssertionError, e:
124+
raise ImproperlyConfigured(e)
125+
126+
self._connection = pymongo.Connection(host=host, port=port, slave_okay=slave_okay)
127+
128+
if user and password:
129+
auth = self._connection[self.db_name].authenticate(user, password)
130+
if not auth:
131+
raise ImproperlyConfigured("Username and/or password for "
132+
"the MongoDB are not correct")
133+
134+
self._db_connection = self._connection[self.db_name]
135+
136+
from .serializer import TransformDjango
137+
self._db_connection.add_son_manipulator(TransformDjango())
138+
# We're done!
139+
self._connected = True
140+
141+
# TODO: signal! (see Alex' backend)

django_mongodb_engine/client.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from django.db.backends import BaseDatabaseClient
2+
3+
class DatabaseClient(BaseDatabaseClient):
4+
executable_name = 'mongo'

0 commit comments

Comments
 (0)