Commits

adamv  committed ed6495c

Preliminary fixes along the lines of issue 13.

  • Participants
  • Parent commits 07e04ef

Comments (0)

Files changed (2)

File src/sqlserver_ado/adodb_django.py

 ##2 = Threads may share the module and connections.
 ##3 = Threads may share the module, connections and cursors.
 
-paramstyle = 'qmark'
-# String constant stating the type of parameter marker formatting expected by the interface.
-# 'qmark' = Question mark style, e.g. '...WHERE name=?'
+# The underlying ADO library expects parameters as '?', but this wrapper 
+# expects '%s' parameters. This wrapper takes care of the conversion.
+paramstyle = 'format'
 
 version = __doc__.split('-',2)[0]
 
 # 3... = Really really on for real
 verbose = False
 
-defaultIsolationLevel = adXactReadCommitted
 #  Set defaultIsolationLevel on module level before creating the connection.
 #   It may be one of "adXact..." consts.
 #   if you simply "import adodbapi", you'll say:
 #   "adodbapi.adodbapi.defaultIsolationLevel=adodbapi.adodbapi.adXactBrowse", for example
+defaultIsolationLevel = adXactReadCommitted
 
-defaultCursorLocation = adUseServer
 #  Set defaultCursorLocation on module level before creating the connection.
 #   It may be one of the "adUse..." consts.
+defaultCursorLocation = adUseServer
 
 
 def standardErrorHandler(connection,cursor,errorclass,errorvalue):
             self.rs.Close()
             self.rs = None
 
-    def _executeHelper(self,operation,isStoredProcedureCall,parameters=None):
+    def _executeHelper(self, operation, isStoredProcedureCall, parameters=None):
         if self.conn is None:
             self._raiseCursorError(Error,None)
             return
             self.cmd = win32com.client.Dispatch("ADODB.Command")
             self.cmd.ActiveConnection = self.conn.adoConn
             self.cmd.CommandTimeout = self.conn.adoConn.CommandTimeout
-            self.cmd.CommandText=operation
-            
+
             if isStoredProcedureCall:
                 self.cmd.CommandType = adCmdStoredProc
             else:
                 self.cmd.CommandType = adCmdText
 
+            parameter_replacements = list()
+            param_values = list()
+            
             if parameters is not None:
                 for i,elem in enumerate(parameters):
-                    name = 'p%i' % i
-                    adotype = pyTypeToADOType(elem)
-                    p = self.cmd.CreateParameter(name,adotype) # Name, Type, Direction, Size, Value
-                    if isStoredProcedureCall:
-                        p.Direction = adParamUnknown
-                    self.cmd.Parameters.Append(p)
+                    if elem is None:
+                        parameter_replacements.append('NULL')
+                    else:
+                        parameter_replacements.append('?')
+                        param_values.append(elem)
+                        name = 'p%i' % i
+                        adotype = pyTypeToADOType(elem)
+                        p = self.cmd.CreateParameter(name,adotype) # Name, Type, Direction, Size, Value
+                        if isStoredProcedureCall:
+                            p.Direction = adParamUnknown
+                        self.cmd.Parameters.Append(p)
                     
                 if verbose > 2:
                    _log_parameters(self.cmd.Parameters)
                    
                 returnValueIndex = _findReturnValueIndex(isStoredProcedureCall, self.cmd.Parameters)            
                 
-                for elem in parameters:
+                for elem in param_values:
                     parmIndx+=1
                     
                     # skip over the return value parameter (adParamReturnValue) if any
                     if p.Size == 0: p.Size = -1
 
                     if verbose > 2:
-                        print 'Parameter %d type %s stored as: %s' % (parmIndx,adTypeNames.get(p.Type, 'unknown'),repr(p.Value))
+                        print 'Parameter %d type %s stored as: %s' % (
+                            parmIndx, 
+                            adTypeNames.get(p.Type, 'unknown'), 
+                            repr(p.Value))
 
             convertedAllParameters = True
 
-            # Execute the SQL
+            if parameters is not None:
+                operation = operation % tuple(parameter_replacements)
+
+            self.cmd.CommandText = operation
             adoRetVal = self.cmd.Execute()
 
         except (Exception), e:
 	datetime.date: adDate,
 	datetime.datetime: adDate,
 	datetime.time: adDate,
-	
-	# This is causing problems when "adEmpty", as that's not a SQL command parameter type.
-	# So, fake a type that's more or less convertable.
-	# (Alternate approach would be to replace ? in query with literal NULLs...)
-	type(None): adBSTR,
 }
 
 class VariantConversionMap(object):

File src/sqlserver_ado/base.py

 DatabaseError = Database.DatabaseError
 IntegrityError = Database.IntegrityError
 
-# We need to use a special Cursor class because adodbapi expects question-mark
-# param style, but Django expects "%s". This cursor converts question marks to
-# format-string style.
+
 class CursorWrapper(Database.Cursor):
     def __init__(self, connection):
         Database.Cursor.__init__(self,connection)
     def _executeHelper(self, operation, isStoredProcedureCall, parameters=None):
         sql = operation # So we can see the original and modified SQL in a traceback
 
-        # Convert parameter style from "%s" to qmark
-        if parameters:
-            sql = sql % tuple("?" * len(parameters))
-
         # Look for LIMIT/OFFSET in the SQL
         limit, offset = self._limit_re.search(sql).groups()
         sql = self._limit_re.sub('', sql)