Commits

shaib committed eb02828

Correct issue #60 (http://code.google.com/p/django-mssql/issues/detail?id=60)
by changing the cursor type for commands that retrieve data. We use a Static
cursor instead of the default Fast-Forward cursor; this allows other
operations to be performed while the cursor is consumed.

Comments (0)

Files changed (1)

sqlserver_ado/dbapi.py

         self.return_value = None
 
         try:
-            recordset = self.cmd.Execute()
-            self.rowcount = recordset[1]
-            self._description_from_recordset(recordset[0])
+            if self._command_has_resuls():
+                recordset = self._execute_with_results()
+            else:
+                recordset = self._execute_no_results()
+            self._description_from_recordset(recordset)
         except Exception, e:
             _message = ""
             if hasattr(e, 'args'): _message += str(e.args)+"\n"
             klass = self.connection._suggest_error_class()
             self._raiseCursorError(klass, _message)
 
+    def _command_has_resuls(self):
+        if self.cmd.CommandType == adCmdText:
+            text = self.cmd.CommandText
+            text = text.strip().lower()
+            return text.startswith('select')
+        else:
+            # The other types are stored procedure and table; both have results
+            return True
+        
+    def _execute_with_results(self):
+        # Open from a Recordset for a static cursor so other commands can run while results are consumed
+        recordset = win32com.client.Dispatch("ADODB.Recordset")
+        recordset.CursorType = adOpenStatic
+        recordset.Open(self.cmd)
+        #print "The recordset we got has cursortype:", recordset.CursorType
+        self.rowcount = -1 #recordset.RecordCount probably too inefficient -- see MSDN for ADO Recordset.RecordCount
+        return recordset
+
+    def _execute_no_results(self):
+        recordset, rowcount = self.cmd.Execute()
+        self.rowcount = rowcount
+        return recordset
 
     def callproc(self, procname, parameters=None):
         """Call a stored database procedure with the given name.