Skip to content

Commit 96f9879

Browse files
author
christofer holm
committed
Squashed 'pkg/' content from commit 6870fb5
git-subtree-dir: pkg git-subtree-split: 6870fb5b0ce02ed9b7e4352e9f142c74b8607886
0 parents  commit 96f9879

File tree

4,360 files changed

+450989
-0
lines changed

Some content is hidden

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

4,360 files changed

+450989
-0
lines changed

.github/FUNDING.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# These are supported funding model platforms
2+
3+
github:
4+
patreon:
5+
open_collective: # Replace with a single Open Collective username
6+
ko_fi: # Replace with a single Ko-fi username
7+
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8+
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9+
liberapay: # Replace with a single Liberapay username
10+
issuehunt: # Replace with a single IssueHunt username
11+
otechie: # Replace with a single Otechie username
12+
custom:

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
dist/
2+
build/
3+
.idea/
4+
.tox/
5+
*__pycache__*
6+
*egg-info/

MANIFEST

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# file GENERATED by distutils, do NOT edit
2+
setup.cfg
3+
setup.py
4+
djongo\__init__.py
5+
djongo\base.py
6+
djongo\compiler.py
7+
djongo\cursor.py
8+
djongo\database.py
9+
djongo\features.py
10+
djongo\introspection.py
11+
djongo\operations.py
12+
djongo\schema.py
13+
djongo\models\__init__.py
14+
djongo\models\fields.py
15+
djongo\sql2mongo\__init__.py
16+
djongo\sql2mongo\converters.py
17+
djongo\sql2mongo\operators.py
18+
djongo\sql2mongo\query.py

MANIFEST.in

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
include djongo/dynamic_formsets/static/dynamic_formsets/images/*.*
2+
include djongo/dynamic_formsets/static/dynamic_formsets/js/jquery/*.*
3+
include djongo/dynamic_formsets/static/dynamic_formsets/js/jquery-formset/*.*
4+
include djongo/dynamic_formsets/templates/admin/*.*

djongo/__init__.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# This version of Djongo was made possible by
2+
# the generous contributions from:
3+
#
4+
# * Zachary Sizemore
5+
# * Wayne Van Son
6+
# * Norman Niemer
7+
# * Renz Ladia
8+
# * thestick613
9+
10+
__version__ = '1.3.6'

djongo/admin.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import copy
2+
3+
from django.contrib import admin
4+
from djongo.models import fields
5+
6+
7+
class ModelAdmin(admin.ModelAdmin):
8+
DJONGO_FIELDS = (
9+
fields.ArrayField,
10+
fields.EmbeddedField,
11+
)
12+
13+
def formfield_for_dbfield(self, db_field, request, **kwargs):
14+
if not isinstance(db_field, self.DJONGO_FIELDS):
15+
return admin.ModelAdmin.formfield_for_dbfield(
16+
self, db_field, request, **kwargs)
17+
18+
admin_instance = ModelAdmin(db_field.model_container, admin.site)
19+
kwargs.setdefault('admin', admin_instance)
20+
kwargs.setdefault('request', request)
21+
22+
for klass in db_field.__class__.mro():
23+
if klass in self.formfield_overrides:
24+
kwargs = dict(copy.deepcopy(
25+
self.formfield_overrides[klass]), **kwargs)
26+
27+
return db_field.formfield(**kwargs)

djongo/base.py

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
"""
2+
MongoDB database backend for Django
3+
"""
4+
from collections import OrderedDict
5+
from logging import getLogger
6+
from django.db.backends.base.base import BaseDatabaseWrapper
7+
from django.db.backends.base.client import BaseDatabaseClient
8+
from logging.config import dictConfig
9+
from django.db.utils import Error
10+
from .creation import DatabaseCreation
11+
from . import database as Database
12+
from .cursor import Cursor
13+
from .features import DatabaseFeatures
14+
from .introspection import DatabaseIntrospection
15+
from .operations import DatabaseOperations
16+
from .schema import DatabaseSchemaEditor
17+
18+
logger = getLogger(__name__)
19+
20+
21+
class CachedCollections(set):
22+
23+
def __init__(self, database):
24+
self.db = database
25+
super().__init__()
26+
27+
def __contains__(self, item):
28+
ans = super().__contains__(item)
29+
if ans:
30+
return ans
31+
self.update(self.db.list_collection_names())
32+
return super().__contains__(item)
33+
34+
35+
class DjongoClient:
36+
37+
def __init__(self, database, enforce_schema=True):
38+
self.enforce_schema = enforce_schema
39+
self.cached_collections = CachedCollections(database)
40+
41+
42+
class DatabaseWrapper(BaseDatabaseWrapper):
43+
"""
44+
DatabaseWrapper for MongoDB using SQL replacements.
45+
"""
46+
47+
# This dictionary will map Django model field types to appropriate data
48+
# types to be used in the database.
49+
data_types = {
50+
'AutoField': 'int',
51+
'BigAutoField': 'long',
52+
'BinaryField': 'binData',
53+
'BooleanField': 'bool',
54+
'CharField': 'string',
55+
'CommaSeparatedIntegerField': 'string',
56+
'DateField': 'date',
57+
'DateTimeField': 'date',
58+
'DecimalField': 'decimal',
59+
'DurationField': 'long',
60+
'FileField': 'string',
61+
'FilePathField': 'string',
62+
'FloatField': 'double',
63+
'IntegerField': 'int',
64+
'BigIntegerField': 'long',
65+
'IPAddressField': 'string',
66+
'GenericIPAddressField': 'string',
67+
'NullBooleanField': 'bool',
68+
'OneToOneField': 'int',
69+
'PositiveIntegerField': 'long',
70+
'PositiveSmallIntegerField': 'int',
71+
'SlugField': 'string',
72+
'SmallIntegerField': 'int',
73+
'TextField': 'string',
74+
'TimeField': 'date',
75+
'UUIDField': 'string',
76+
'GenericObjectIdField': 'objectId',
77+
'ObjectIdField': 'objectId',
78+
'EmbeddedField': 'object',
79+
'ArrayField': 'array'
80+
}
81+
82+
data_types_suffix = {
83+
'AutoField': 'AUTOINCREMENT',
84+
'BigAutoField': 'AUTOINCREMENT',
85+
'ObjectIdField': 'AUTOINCREMENT'
86+
}
87+
88+
operators = {
89+
'exact': '= %s',
90+
'iexact': 'iLIKE %s',
91+
'contains': 'LIKE %s',
92+
'icontains': 'iLIKE %s',
93+
'regex': 'REGEXP BINARY %s',
94+
'iregex': 'REGEXP %s',
95+
'gt': '> %s',
96+
'gte': '>= %s',
97+
'lt': '< %s',
98+
'lte': '<= %s',
99+
'startswith': 'LIKE %s',
100+
'endswith': 'LIKE %s',
101+
'istartswith': 'iLIKE %s',
102+
'iendswith': 'iLIKE %s',
103+
}
104+
105+
vendor = 'djongo'
106+
SchemaEditorClass = DatabaseSchemaEditor
107+
Database = Database
108+
109+
client_class = BaseDatabaseClient
110+
creation_class = DatabaseCreation
111+
features_class = DatabaseFeatures
112+
introspection_class = DatabaseIntrospection
113+
ops_class = DatabaseOperations
114+
115+
def __init__(self, *args, **kwargs):
116+
self.client_connection = None
117+
self.djongo_connection = None
118+
super().__init__(*args, **kwargs)
119+
120+
def is_usable(self):
121+
if self.connection is not None:
122+
return True
123+
return False
124+
125+
def get_connection_params(self):
126+
"""
127+
Default method to acquire database connection parameters.
128+
129+
Sets connection parameters to match settings.py, and sets
130+
default values to blank fields.
131+
"""
132+
valid_settings = {
133+
'NAME': 'name',
134+
'ENFORCE_SCHEMA': 'enforce_schema',
135+
}
136+
connection_params = {
137+
'name': 'djongo_test',
138+
'enforce_schema': False
139+
}
140+
for setting_name, kwarg in valid_settings.items():
141+
try:
142+
setting = self.settings_dict[setting_name]
143+
except KeyError:
144+
continue
145+
146+
if setting or setting is False:
147+
connection_params[kwarg] = setting
148+
try:
149+
connection_params.update(self.settings_dict['CLIENT'])
150+
except KeyError:
151+
pass
152+
153+
return connection_params
154+
155+
def get_new_connection(self, connection_params):
156+
"""
157+
Receives a dictionary connection_params to setup
158+
a connection to the database.
159+
160+
Dictionary correct setup is made through the
161+
get_connection_params method.
162+
"""
163+
164+
name = connection_params.pop('name')
165+
es = connection_params.pop('enforce_schema')
166+
167+
connection_params['document_class'] = OrderedDict
168+
# connection_params['tz_aware'] = True
169+
# To prevent leaving unclosed connections behind,
170+
# client_conn must be closed before a new connection
171+
# is created.
172+
if self.client_connection is not None:
173+
self.client_connection.close()
174+
logger.debug('Existing MongoClient connection closed')
175+
176+
self.client_connection = Database.connect(db=name, **connection_params)
177+
logger.debug('New Database connection')
178+
179+
database = self.client_connection[name]
180+
self.djongo_connection = DjongoClient(database, es)
181+
return self.client_connection[name]
182+
183+
def _set_autocommit(self, autocommit):
184+
"""
185+
Default method must be overridden, eventhough not used.
186+
187+
TODO: For future reference, setting two phase commits and rollbacks
188+
might require populating this method.
189+
"""
190+
pass
191+
192+
def init_connection_state(self):
193+
try:
194+
dictConfig(self.settings_dict['LOGGING'])
195+
except KeyError:
196+
pass
197+
198+
def create_cursor(self, name=None):
199+
"""
200+
Returns an active connection cursor to the database.
201+
"""
202+
return Cursor(self.client_connection, self.connection, self.djongo_connection)
203+
204+
def _close(self):
205+
"""
206+
Closes the client connection to the database.
207+
"""
208+
if self.connection is not None:
209+
with self.wrap_database_errors:
210+
self.connection.client.close()
211+
logger.debug('MongoClient connection closed')
212+
213+
def _rollback(self):
214+
raise Error
215+
216+
def _commit(self):
217+
"""
218+
Commit routine
219+
220+
TODO: two phase commits are not supported yet.
221+
"""
222+
pass

djongo/compiler.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
class SQLCompiler:
2+
3+
def __init__(self, query, connection, using):
4+
self.query = query
5+
self.connection = connection
6+
self.using = using

djongo/creation.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import subprocess
2+
import shutil
3+
4+
from django.db.backends.base.creation import BaseDatabaseCreation
5+
6+
7+
class DatabaseCreation(BaseDatabaseCreation):
8+
9+
def _clone_test_db(self, suffix, verbosity, keepdb=False):
10+
source_database_name = self.connection.settings_dict['NAME']
11+
target_database_name = self.get_test_db_clone_settings(suffix)['NAME']
12+
try:
13+
host = self.connection.settings_dict['CLIENT']['host']
14+
except KeyError:
15+
host = None
16+
client = self.connection.client_connection
17+
if not keepdb:
18+
self._destroy_test_db(target_database_name, verbosity)
19+
args = [
20+
'mongodump',
21+
'--quiet',
22+
'--db',
23+
source_database_name
24+
]
25+
if host is not None:
26+
args += ['--host', host]
27+
28+
subprocess.run(args)
29+
args = [
30+
'mongorestore',
31+
f'dump/{source_database_name}',
32+
'--quiet',
33+
'--db',
34+
target_database_name
35+
]
36+
if host is not None:
37+
args += ['--host', host]
38+
39+
subprocess.run(args)
40+
shutil.rmtree('dump')
41+
42+
print('Closing cloned connection')
43+
client.close()

0 commit comments

Comments
 (0)