Code

Ticket #17760: 17760.diff

File 17760.diff, 6.0 KB (added by claudep, 2 years ago)

Replace confirm() by cached properties

Line 
1diff --git a/django/contrib/gis/db/backends/spatialite/creation.py b/django/contrib/gis/db/backends/spatialite/creation.py
2index 33b6f95..5c97113 100644
3--- a/django/contrib/gis/db/backends/spatialite/creation.py
4+++ b/django/contrib/gis/db/backends/spatialite/creation.py
5@@ -31,9 +31,6 @@ class SpatiaLiteCreation(DatabaseCreation):
6         self.connection.close()
7         self.connection.settings_dict["NAME"] = test_database_name
8 
9-        # Confirm the feature set of the test database
10-        self.connection.features.confirm()
11-
12         # Need to load the SpatiaLite initialization SQL before running `syncdb`.
13         self.load_spatialite_sql()
14 
15diff --git a/django/db/backends/__init__.py b/django/db/backends/__init__.py
16index 7674f5c..57a550b 100644
17--- a/django/db/backends/__init__.py
18+++ b/django/db/backends/__init__.py
19@@ -399,54 +399,49 @@ class BaseDatabaseFeatures(object):
20     # in the SQL standard.
21     supports_tablespaces = False
22 
23-    # Features that need to be confirmed at runtime
24-    # Cache whether the confirmation has been performed.
25-    _confirmed = False
26-    supports_transactions = None
27-    supports_stddev = None
28-    can_introspect_foreign_keys = None
29+    # Confirm support for introspected foreign keys
30+    # Every database can do this reliably, except MySQL,
31+    # which can't do it for MyISAM tables
32+    can_introspect_foreign_keys = True
33 
34     # Support for the DISTINCT ON clause
35     can_distinct_on_fields = False
36 
37     def __init__(self, connection):
38         self.connection = connection
39+        # Cached properties
40+        self._supports_transactions = None
41+        self._supports_stddev = None
42 
43-    def confirm(self):
44-        "Perform manual checks of any database features that might vary between installs"
45-        self._confirmed = True
46-        self.supports_transactions = self._supports_transactions()
47-        self.supports_stddev = self._supports_stddev()
48-        self.can_introspect_foreign_keys = self._can_introspect_foreign_keys()
49-
50-    def _supports_transactions(self):
51+    @property
52+    def supports_transactions(self):
53         "Confirm support for transactions"
54-        cursor = self.connection.cursor()
55-        cursor.execute('CREATE TABLE ROLLBACK_TEST (X INT)')
56-        self.connection._commit()
57-        cursor.execute('INSERT INTO ROLLBACK_TEST (X) VALUES (8)')
58-        self.connection._rollback()
59-        cursor.execute('SELECT COUNT(X) FROM ROLLBACK_TEST')
60-        count, = cursor.fetchone()
61-        cursor.execute('DROP TABLE ROLLBACK_TEST')
62-        self.connection._commit()
63-        return count == 0
64-
65-    def _supports_stddev(self):
66+        if self._supports_transactions is None:
67+            cursor = self.connection.cursor()
68+            cursor.execute('CREATE TABLE ROLLBACK_TEST (X INT)')
69+            self.connection._commit()
70+            cursor.execute('INSERT INTO ROLLBACK_TEST (X) VALUES (8)')
71+            self.connection._rollback()
72+            cursor.execute('SELECT COUNT(X) FROM ROLLBACK_TEST')
73+            count, = cursor.fetchone()
74+            cursor.execute('DROP TABLE ROLLBACK_TEST')
75+            self.connection._commit()
76+            self._supports_transactions = (count == 0)
77+        return self._supports_transactions
78+
79+    @property
80+    def supports_stddev(self):
81         "Confirm support for STDDEV and related stats functions"
82-        class StdDevPop(object):
83-            sql_function = 'STDDEV_POP'
84-
85-        try:
86-            self.connection.ops.check_aggregate_support(StdDevPop())
87-        except NotImplementedError:
88-            self.supports_stddev = False
89-
90-    def _can_introspect_foreign_keys(self):
91-        "Confirm support for introspected foreign keys"
92-        # Every database can do this reliably, except MySQL,
93-        # which can't do it for MyISAM tables
94-        return True
95+        if self._supports_stddev is None:
96+            class StdDevPop(object):
97+                sql_function = 'STDDEV_POP'
98+
99+            try:
100+                self.connection.ops.check_aggregate_support(StdDevPop())
101+                self._supports_stddev = True
102+            except NotImplementedError:
103+                self._supports_stddev = False
104+        return self._supports_stddev
105 
106 
107 class BaseDatabaseOperations(object):
108diff --git a/django/db/backends/creation.py b/django/db/backends/creation.py
109index 2db0acc..a5ed311 100644
110--- a/django/db/backends/creation.py
111+++ b/django/db/backends/creation.py
112@@ -258,9 +258,6 @@ class BaseDatabaseCreation(object):
113         self.connection.close()
114         self.connection.settings_dict["NAME"] = test_database_name
115 
116-        # Confirm the feature set of the test database
117-        self.connection.features.confirm()
118-
119         # Report syncdb messages at one level lower than that requested.
120         # This ensures we don't get flooded with messages during testing
121         # (unless you really ask to be flooded)
122diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py
123index 830808b..ed5f68a 100644
124--- a/django/db/backends/mysql/base.py
125+++ b/django/db/backends/mysql/base.py
126@@ -153,6 +153,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
127     def __init__(self, connection):
128         super(DatabaseFeatures, self).__init__(connection)
129         self._storage_engine = None
130+        self._can_introspect_foreign_keys = None
131 
132     def _mysql_storage_engine(self):
133         "Internal method used in Django tests. Don't rely on this from your code"
134@@ -169,9 +170,13 @@ class DatabaseFeatures(BaseDatabaseFeatures):
135             self._storage_engine = result[1]
136         return self._storage_engine
137 
138-    def _can_introspect_foreign_keys(self):
139+    @property
140+    def can_introspect_foreign_keys(self):
141         "Confirm support for introspected foreign keys"
142-        return self._mysql_storage_engine() != 'MyISAM'
143+        if self._can_introspect_foreign_keys is None:
144+            self._can_introspect_foreign_keys = (
145+                self._mysql_storage_engine() != 'MyISAM')
146+        return self._can_introspect_foreign_keys
147 
148 class DatabaseOperations(BaseDatabaseOperations):
149     compiler_module = "django.db.backends.mysql.compiler"