33from django .db .backends .base .creation import BaseDatabaseCreation
44from django .core .exceptions import ImproperlyConfigured
55from django .utils .asyncio import async_unsafe
6+ from django .utils .functional import cached_property
7+ from django .db .utils import DatabaseErrorWrapper
8+ from django .db .backends .utils import debug_transaction
69
710from .introspection import DatabaseIntrospection
811from .features import DatabaseFeatures
1215from .creation import DatabaseCreation
1316from .validation import DatabaseValidation
1417
15- import intersystems_iris as Database
16-
17-
18- Database .Warning = type ("StandardError" , (object ,), {})
19- Database .Error = type ("StandardError" , (object ,), {})
20-
21- Database .InterfaceError = type ("Error" , (object ,), {})
22-
23- Database .DatabaseError = type ("Error" , (object ,), {})
24- Database .DataError = type ("DatabaseError" , (object ,), {})
25- Database .OperationalError = type ("DatabaseError" , (object ,), {})
26- Database .IntegrityError = type ("DatabaseError" , (object ,), {})
27- Database .InternalError = type ("DatabaseError" , (object ,), {})
28- Database .ProgrammingError = type ("DatabaseError" , (object ,), {})
29- Database .NotSupportedError = type ("DatabaseError" , (object ,), {})
18+ import intersystems_iris .dbapi ._DBAPI as Database
3019
3120
3221def ignore (* args , ** kwargs ):
@@ -41,8 +30,8 @@ class DatabaseWrapper(BaseDatabaseWrapper):
4130 display_name = 'InterSystems IRIS'
4231
4332 data_types = {
44- 'AutoField' : 'INTEGER AUTO_INCREMENT ' ,
45- 'BigAutoField' : 'BIGINT AUTO_INCREMENT ' ,
33+ 'AutoField' : 'IDENTITY ' ,
34+ 'BigAutoField' : 'IDENTITY ' ,
4635 'BinaryField' : 'LONG BINARY' ,
4736 'BooleanField' : 'BIT' ,
4837 'CharField' : 'VARCHAR(%(max_length)s)' ,
@@ -63,7 +52,7 @@ class DatabaseWrapper(BaseDatabaseWrapper):
6352 'PositiveIntegerField' : 'INTEGER' ,
6453 'PositiveSmallIntegerField' : 'SMALLINT' ,
6554 'SlugField' : 'VARCHAR(%(max_length)s)' ,
66- 'SmallAutoField' : 'SMALLINT AUTO_INCREMENT ' ,
55+ 'SmallAutoField' : 'IDENTITY ' ,
6756 'SmallIntegerField' : 'SMALLINT' ,
6857 'TextField' : 'TEXT' ,
6958 'TimeField' : 'TIME(6)' ,
@@ -81,20 +70,31 @@ class DatabaseWrapper(BaseDatabaseWrapper):
8170 'gte' : '>= %s' ,
8271 'lt' : '< %s' ,
8372 'lte' : '<= %s' ,
84- 'startswith' : "%%%%STARTSWITH %s" ,
73+ 'startswith' : "LIKE %s ESCAPE ' \\ ' " ,
8574 'endswith' : "LIKE %s ESCAPE '\\ '" ,
86- 'istartswith' : "%%%%STARTSWITH %s" ,
75+ 'istartswith' : "LIKE %s ESCAPE ' \\ ' " ,
8776 'iendswith' : "LIKE %s ESCAPE '\\ '" ,
77+ }
78+
79+ pattern_esc = r"REPLACE(REPLACE(REPLACE({}, '\', '\\'), '%%', '\%%'), '_', '\_')"
80+ pattern_ops = {
81+ "contains" : "LIKE '%%' || {} || '%%'" ,
82+ "icontains" : "LIKE '%%' || UPPER({}) || '%%'" ,
83+ "startswith" : "LIKE {} || '%%'" ,
84+ "istartswith" : "LIKE UPPER({}) || '%%'" ,
85+ "endswith" : "LIKE '%%' || {}" ,
86+ "iendswith" : "LIKE '%%' || UPPER({})" ,
8887
8988 }
89+
9090 Database = Database
9191
92- _commit = ignore
93- _rollback = ignore
94- _savepoint = ignore
95- _savepoint_commit = ignore
96- _savepoint_rollback = ignore
97- _set_autocommit = ignore
92+ # _commit = ignore
93+ # _rollback = ignore
94+ # _savepoint = ignore
95+ # _savepoint_commit = ignore
96+ # _savepoint_rollback = ignore
97+ # _set_autocommit = ignore
9898
9999 SchemaEditorClass = DatabaseSchemaEditor
100100
@@ -105,6 +105,7 @@ class DatabaseWrapper(BaseDatabaseWrapper):
105105 ops_class = DatabaseOperations
106106 validation_class = DatabaseValidation
107107
108+ _disable_constraint_checking = False
108109
109110 def get_connection_params (self ):
110111 settings_dict = self .settings_dict
@@ -134,10 +135,10 @@ def get_connection_params(self):
134135 conn_params ['hostname' ] = settings_dict ['HOST' ]
135136 if settings_dict ['PORT' ]:
136137 conn_params ['port' ] = settings_dict ['PORT' ]
137- if settings_dict ['NAME' ]:
138- conn_params ['namespace' ] = settings_dict ['NAME' ]
139138 if 'NAMESPACE' in settings_dict :
140139 conn_params ['namespace' ] = settings_dict ['NAMESPACE' ]
140+ if settings_dict ['NAME' ]:
141+ conn_params ['namespace' ] = settings_dict ['NAME' ]
141142
142143 if (
143144 not conn_params ['hostname' ] or
@@ -158,16 +159,21 @@ def get_connection_params(self):
158159 "Please supply the USER and PASSWORD"
159160 )
160161
162+ conn_params ['application_name' ] = 'django'
163+ conn_params ["autoCommit" ] = self .autocommit
161164 return conn_params
162165
163166 @async_unsafe
164167 def get_new_connection (self , conn_params ):
165168 return Database .connect (** conn_params )
166169
167- def init_connection_state (self ):
168- cursor = self .connection .cursor ()
169- # cursor.callproc('%SYSTEM_SQL.Util_SetOption', ['SELECTMODE', 1])
170- # cursor.callproc('%SYSTEM.SQL_SetSelectMode', [1])
170+ def _close (self ):
171+ if self .connection is not None :
172+ # Automatically rollbacks anyway
173+ # self.in_atomic_block = False
174+ # self.needs_rollback = False
175+ with self .wrap_database_errors :
176+ return self .connection .close ()
171177
172178 @async_unsafe
173179 def create_cursor (self , name = None ):
@@ -182,3 +188,29 @@ def is_usable(self):
182188 return False
183189 else :
184190 return True
191+
192+ @cached_property
193+ def wrap_database_errors (self ):
194+ """
195+ Context manager and decorator that re-throws backend-specific database
196+ exceptions using Django's common wrappers.
197+ """
198+ return DatabaseErrorWrapper (self )
199+
200+ def _set_autocommit (self , autocommit ):
201+ with self .wrap_database_errors :
202+ self .connection .setAutoCommit (autocommit )
203+
204+ def disable_constraint_checking (self ):
205+ self ._disable_constraint_checking = True
206+ return True
207+
208+ def enable_constraint_checking (self ):
209+ self ._disable_constraint_checking = False
210+
211+ @async_unsafe
212+ def savepoint_commit (self , sid ):
213+ """
214+ IRIS does not have `RELEASE SAVEPOINT`
215+ so, just ignore it
216+ """
0 commit comments