summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Gaynor <alex.gaynor@gmail.com>2010-06-09 15:31:19 +0000
committerAlex Gaynor <alex.gaynor@gmail.com>2010-06-09 15:31:19 +0000
commit89fb7aa31044bd3d63302b82ab31e893fa0a43a6 (patch)
treeb8c2aeadf310469532c68e49b50a7e8b2b1284fb
parentdefc4948102b01f2048eb05d51358a22183f5790 (diff)
[soc2010/query-refactor] Introced NativeAutoField, also started with some basic MongoDB tests (really just very basic ORM tests), and introduced various APIs into the mongodb backend that were necessary for running unittests.
git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2010/query-refactor@13338 bcc190cf-cafb-0310-a4f2-bffc1f526a37
-rw-r--r--django/contrib/mongodb/base.py19
-rw-r--r--django/contrib/mongodb/creation.py1
-rw-r--r--django/contrib/mongodb/introspection.py6
-rw-r--r--django/core/management/commands/flush.py9
-rw-r--r--django/db/models/fields/__init__.py39
-rw-r--r--tests/regressiontests/mongodb/__init__.py0
-rw-r--r--tests/regressiontests/mongodb/models.py10
-rw-r--r--tests/regressiontests/mongodb/tests.py11
8 files changed, 75 insertions, 20 deletions
diff --git a/django/contrib/mongodb/base.py b/django/contrib/mongodb/base.py
index 825a39787d..e92c6db25f 100644
--- a/django/contrib/mongodb/base.py
+++ b/django/contrib/mongodb/base.py
@@ -1,8 +1,9 @@
from pymongo import Connection
-from django.db.backends import BaseDatabaseWrapper
+from django.db.backends import BaseDatabaseWrapper, BaseDatabaseValidation
from django.db.backends.signals import connection_created
from django.contrib.mongodb.creation import DatabaseCreation
+from django.contrib.mongodb.introspection import DatabaseIntrospection
from django.utils.importlib import import_module
@@ -12,9 +13,11 @@ class DatabaseFeatures(object):
class DatabaseOperations(object):
compiler_module = "django.contrib.mongodb.compiler"
+ sql_ddl = False
- def __init__(self, *args, **kwargs):
+ def __init__(self, connection):
self._cache = {}
+ self.connection = connection
def max_name_length(self):
return 254
@@ -34,13 +37,23 @@ class DatabaseOperations(object):
import_module(self.compiler_module), compiler_name
)
return self._cache[compiler_name]
+
+ def flush(self, only_django=False):
+ if only_django:
+ tables = self.connection.introspection.django_table_names(only_existing=True)
+ else:
+ tables = self.connection.introspection.table_names()
+ for table in tables:
+ self.connection.db.drop_collection(table)
class DatabaseWrapper(BaseDatabaseWrapper):
def __init__(self, *args, **kwargs):
super(DatabaseWrapper, self).__init__(*args, **kwargs)
self.features = DatabaseFeatures()
- self.ops = DatabaseOperations()
+ self.ops = DatabaseOperations(self)
self.creation = DatabaseCreation(self)
+ self.validation = BaseDatabaseValidation(self)
+ self.introspection = DatabaseIntrospection(self)
self._connection = None
@property
diff --git a/django/contrib/mongodb/creation.py b/django/contrib/mongodb/creation.py
index 9102d7f997..ed4a26316b 100644
--- a/django/contrib/mongodb/creation.py
+++ b/django/contrib/mongodb/creation.py
@@ -11,6 +11,7 @@ class DatabaseCreation(object):
else:
test_database_name = TEST_DATABASE_PREFIX + self.connection.settings_dict['NAME']
self.connection.settings_dict["NAME"] = test_database_name
+ self.connection.settings_dict["SUPPORTS_TRANSACTIONS"] = False
return test_database_name
def destroy_test_db(self, old_database_name, verbosity=1):
diff --git a/django/contrib/mongodb/introspection.py b/django/contrib/mongodb/introspection.py
new file mode 100644
index 0000000000..eae5da668a
--- /dev/null
+++ b/django/contrib/mongodb/introspection.py
@@ -0,0 +1,6 @@
+from django.db.backends import BaseDatabaseIntrospection
+
+
+class DatabaseIntrospection(BaseDatabaseIntrospection):
+ def table_names(self):
+ return self.connection.db.collection_names()
diff --git a/django/core/management/commands/flush.py b/django/core/management/commands/flush.py
index 6836fe35ca..94c12490ce 100644
--- a/django/core/management/commands/flush.py
+++ b/django/core/management/commands/flush.py
@@ -35,9 +35,7 @@ class Command(NoArgsCommand):
import_module('.management', app_name)
except ImportError:
pass
-
- sql_list = sql_flush(self.style, connection, only_django=True)
-
+
if interactive:
confirm = raw_input("""You have requested a flush of the database.
This will IRREVERSIBLY DESTROY all data currently in the %r database,
@@ -49,6 +47,11 @@ Are you sure you want to do this?
confirm = 'yes'
if confirm == 'yes':
+ # TODO: HACK, make this more OO.
+ if not getattr(connection.ops, "sql_ddl", True):
+ connection.ops.flush(only_django=True)
+ return
+ sql_list = sql_flush(self.style, connection, only_django=True)
try:
cursor = connection.cursor()
for sql in sql_list:
diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py
index 65b60a0173..0c9b603609 100644
--- a/django/db/models/fields/__init__.py
+++ b/django/db/models/fields/__init__.py
@@ -447,17 +447,32 @@ class Field(object):
"Returns the value of this field in the given model instance."
return getattr(obj, self.attname)
-class AutoField(Field):
+class BaseAutoField(Field):
+ empty_strings_allowed = False
+
+ def __init__(self, *args, **kwargs):
+ assert kwargs.get('primary_key'), "%ss must have primary_key=True." % self.__class__.__name__
+ kwargs['blank'] = True
+ super(BaseAutoField, self).__init__(*args, **kwargs)
+
+ def contribute_to_class(self, cls, name):
+ assert not cls._meta.has_auto_field, "A model can't have more than one AutoField."
+ super(BaseAutoField, self).contribute_to_class(cls, name)
+ cls._meta.has_auto_field = True
+ cls._meta.auto_field = self
+
+ def get_internal_type(self):
+ return "AutoField"
+
+ def formfield(self, **kwargs):
+ return None
+
+class AutoField(BaseAutoField):
description = _("Integer")
- empty_strings_allowed = False
default_error_messages = {
'invalid': _(u'This value must be an integer.'),
}
- def __init__(self, *args, **kwargs):
- assert kwargs.get('primary_key', False) is True, "%ss must have primary_key=True." % self.__class__.__name__
- kwargs['blank'] = True
- Field.__init__(self, *args, **kwargs)
def to_python(self, value):
if value is None:
@@ -475,14 +490,10 @@ class AutoField(Field):
return None
return int(value)
- def contribute_to_class(self, cls, name):
- assert not cls._meta.has_auto_field, "A model can't have more than one AutoField."
- super(AutoField, self).contribute_to_class(cls, name)
- cls._meta.has_auto_field = True
- cls._meta.auto_field = self
-
- def formfield(self, **kwargs):
- return None
+class NativeAutoField(BaseAutoField):
+ # TODO: eventually delegate validation and other such things to the
+ # backends. For now it's enough that this class exists.
+ pass
class BooleanField(Field):
empty_strings_allowed = False
diff --git a/tests/regressiontests/mongodb/__init__.py b/tests/regressiontests/mongodb/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/regressiontests/mongodb/__init__.py
diff --git a/tests/regressiontests/mongodb/models.py b/tests/regressiontests/mongodb/models.py
new file mode 100644
index 0000000000..e07e8f191c
--- /dev/null
+++ b/tests/regressiontests/mongodb/models.py
@@ -0,0 +1,10 @@
+from django.db import models
+
+
+class Artist(models.Model):
+ id = models.NativeAutoField(primary_key=True)
+ name = models.CharField(max_length=255)
+ good = models.BooleanField()
+
+ def __unicode__(self):
+ return self.name
diff --git a/tests/regressiontests/mongodb/tests.py b/tests/regressiontests/mongodb/tests.py
new file mode 100644
index 0000000000..cbf0dcbcd8
--- /dev/null
+++ b/tests/regressiontests/mongodb/tests.py
@@ -0,0 +1,11 @@
+from django.test import TestCase
+
+from models import Artist
+
+
+class MongoTestCase(TestCase):
+ def test_create(self):
+ b = Artist.objects.create(name="Bruce Springsteen", good=True)
+ self.assertTrue(b.pk is not None)
+ self.assertEqual(b.name, "Bruce Springsteen")
+ self.assertTrue(b.good)