Anonymous avatar Anonymous committed d90c4d5

- Removing CursorWrapper, since all SQL munging now happens in the custom query class.
- runsql.cmd now lets you pick which SQL Server instance to run against.

Comments (0)

Files changed (6)

source/sqlserver_ado/base.py

 IntegrityError = Database.IntegrityError
 
 
-class CursorWrapper(Database.Cursor):
-    def __init__(self, connection):
-        Database.Cursor.__init__(self,connection)
-        self._re_limit_offset = re.compile(r'(?:LIMIT\s+(\d+))?\s*(?:OFFSET\s+(\d+))?$')
-        self._re_order_limit_offset = re.compile(r'(?:ORDER BY\s+(.+?))?\s*(?:LIMIT\s+(\d+))?\s*(?:OFFSET\s+(\d+))?$')
-        
-    def _mangle_order_limit_offset(self, sql, order, limit, offset):
-        limit = int(limit)
-        offset = int(offset)
-        
-        # Lop off the ORDER BY ... LIMIT ... OFFSET ...
-        sql_without_ORDER = self._re_order_limit_offset.sub('',sql)
-        # Lop off the initial "SELECT"
-        inner_sql = sql_without_ORDER.split(None, 1)[1]
-        
-        low = offset + 1
-        high = low + limit
-        
-        final_sql = """SELECT * FROM ( SELECT ROW_NUMBER() OVER ( ORDER BY %(ordering)s) as my_row_number, %(rest)s) as QQQ where my_row_number between %(low)s and %(high)s""" %\
-        {
-            'rest': inner_sql,
-            'ordering': order,
-            'low': low,
-            'high': high,
-        }
-        
-        return final_sql
-        
-    def _mangle_limit(self, sql, limit):
-        # Turn strings to ints
-        limit = int(limit)
-        
-        # Lop off any LIMIT... from the query
-        sql_without_limit = self._re_limit_offset.sub('', sql)
-        
-        # Cut into ['SELECT', '...rest of query...']
-        sql_parts = sql_without_limit.split(None, 1)
-        
-        return (' TOP %s ' % limit).join(sql_parts)
-
-
-    def _mangle_sql(self, sql):
-        order, limit, offset = self._re_order_limit_offset.search(sql).groups()
-        
-        if offset is None:
-            if limit is not None:
-                return self._mangle_limit(sql, limit)
-            else:
-                return sql
-        
-        # Otherwise we have an OFFSET
-        if order is None:
-            order = ""
-            #raise Exception("Offset without ORDER BY not supported (need to add the ID internally)")
-                
-        return self._mangle_order_limit_offset(sql, order, limit, offset)
-
-
-    def _executeHelper(self, operation, isStoredProcedureCall, parameters=None):
-        sql = operation #self._mangle_sql(operation)
-        Database.Cursor._executeHelper(self, sql, isStoredProcedureCall, parameters)
-
-
 class DatabaseFeatures(BaseDatabaseFeatures):
     supports_tablespaces = True
     uses_custom_query_class = True
                 (datasource, settings.DATABASE_NAME, auth_string)
                 
             self.connection = Database.connect(conn_string)
-        return CursorWrapper(self.connection)
+        return Database.Cursor(self.connection)

source/sqlserver_ado/query.py

 
 
         def _mangle_order_limit_offset(self, sql, order, limit, offset):
-            limit = int(limit)
-            offset = int(offset)
-            
             # Lop off the ORDER BY ... LIMIT ... OFFSET ...
             sql_without_ORDER = self._re_order_limit_offset.sub('',sql)
             # Lop off the initial "SELECT"
             return final_sql
             
         def _mangle_limit(self, sql, limit):
-            # Turn strings to ints
-            limit = int(limit)
-            
             # Lop off any LIMIT... from the query
             sql_without_limit = self._re_limit_offset.sub('', sql)
             
             sql_parts = sql_without_limit.split(None, 1)
             
             return (' TOP %s ' % limit).join(sql_parts)
-    
-    
+
+
         def _mangle_sql(self, sql):
             self._re_limit_offset = \
                 re.compile(r'(?:LIMIT\s+(\d+))?\s*(?:OFFSET\s+(\d+))?$')
             
             if offset is None:
                 if limit is not None:
-                    return self._mangle_limit(sql, limit)
+                    return self._mangle_limit(sql, int(limit))
                 else:
                     return sql
             
                 meta = self.get_meta()
                 order = meta.pk.attname+" ASC"
                     
-            return self._mangle_order_limit_offset(sql, order, limit, offset)
+            return self._mangle_order_limit_offset(sql, order, int(limit), int(offset))
     
                 
         def resolve_columns(self, row, fields=()):
                 return super(SqlServerQuery, self).as_sql(with_limits, with_col_aliases)
 
             raw_sql, fields = super(SqlServerQuery, self).as_sql(with_limits, with_col_aliases)
-            mangled_sql = self._mangle_sql(raw_sql)
-            return mangled_sql, fields
+            return self._mangle_sql(raw_sql), fields
 
 
         def _insert_as_sql(self, *args, **kwargs):
-sqlcmd.exe -S localhost\ss2005 -E -V11 -i %1
+@echo off
+REM USAGE:
+REM runsql.cmd sql-script-file [local-sqlserver-instance]
+REM SQLINSTANCE can be set to the instance to use as an
+REM   environmental variable as well
+
+pushd & setlocal
+
+if {%SQLINSTANCE%}=={} set SQLINSTANCE=%2
+if {%SQLINSTANCE%}=={} set SQLINSTANCE=ss2005
+sqlcmd.exe -S localhost\%SQLINSTANCE% -E -V11 -i %1
+
+endlocal & popd
+
+:END
+exit /b %ERRORLEVEL%

tests/test_limit_offset/myapp/models.py

     class Meta:
         db_table = u'Products'
         
+    def __repr__(self):
+        return "<Product %s: %s/%s (%s)" % (self.productid, self.name, self.color, self.notes)
+        
     def __unicode__(self):
-        return "<Product %s: %s/%s (%s)" % (self.productid, self.name, self.color, self.notes)
+        return u"<Product %s: %s/%s (%s)" % (self.productid, self.name, self.color, self.notes)

tests/test_limit_offset/settings.py

 )
 
 INSTALLED_APPS = (
-    'django.contrib.auth',
-    'django.contrib.contenttypes',
-    'django.contrib.sessions',
-    'django.contrib.sites',
-    
     'myapp',
 )

tests/test_limit_offset/testing.py

+# To load fixtures:
+#  manage.py loaddata data.json
+# From the command line, do "manage.py shell" and then "import testing"
+# None of these should error out (assuming you've loaded the fixtures.)
+
+from myapp.models import *
+p = Products.objects
+
+print p.all()
+print p.all()[:3]
+print p.all()[2:4]
+
+print p.order_by('name')
+print p.order_by('name')[:3]
+print p.order_by('name')[2:4]
+
+print "done"
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.