Ticket #16614: support-server-side-cursors.patch

File support-server-side-cursors.patch, 6.7 KB (added by toofishes, 4 years ago)
  • django/db/models/sql/compiler.py

     
    696696        # are released.
    697697        if self.query.select_for_update and transaction.is_managed(self.using):
    698698            transaction.set_dirty(self.using)
    699         for rows in self.execute_sql(MULTI):
     699        for rows in self.execute_sql(MULTI, True):
    700700            for row in rows:
    701701                if resolve_columns:
    702702                    if fields is None:
     
    727727
    728728                yield row
    729729
    730     def execute_sql(self, result_type=MULTI):
     730    def execute_sql(self, result_type=MULTI, iterating=False):
    731731        """
    732732        Run the query against the database and returns the result(s). The
    733733        return value is a single data item if result_type is SINGLE, or an
     
    750750            else:
    751751                return
    752752
    753         cursor = self.connection.cursor()
     753        cursor = self.connection.cursor(iterating)
    754754        cursor.execute(sql, params)
    755755
    756756        if not result_type:
  • django/db/backends/sqlite3/base.py

     
    186186        self.introspection = DatabaseIntrospection(self)
    187187        self.validation = BaseDatabaseValidation(self)
    188188
    189     def _cursor(self):
     189    def _cursor(self, iterating=False):
    190190        if self.connection is None:
    191191            settings_dict = self.settings_dict
    192192            if not settings_dict['NAME']:
  • django/db/backends/mysql/base.py

     
    303303                self.connection = None
    304304        return False
    305305
    306     def _cursor(self):
     306    def _cursor(self, iterating=False):
    307307        if not self._valid_connection():
    308308            kwargs = {
    309309                'conv': django_conversions,
     
    331331            self.connection.encoders[SafeUnicode] = self.connection.encoders[unicode]
    332332            self.connection.encoders[SafeString] = self.connection.encoders[str]
    333333            connection_created.send(sender=self.__class__, connection=self)
    334         cursor = CursorWrapper(self.connection.cursor())
    335         return cursor
     334        if iterating:
     335            cursor = self.connection.cursor(cursorclass=Database.cursors.SSCursor)
     336        else:
     337            cursor = self.connection.cursor()
     338        return CursorWrapper(cursor)
    336339
    337340    def _rollback(self):
    338341        try:
  • django/db/backends/oracle/base.py

     
    452452        return "%s/%s@%s" % (settings_dict['USER'],
    453453                             settings_dict['PASSWORD'], dsn)
    454454
    455     def _cursor(self):
     455    def _cursor(self, iterating=False):
    456456        cursor = None
    457457        if not self._valid_connection():
    458458            conn_string = convert_unicode(self._connect_string())
  • django/db/backends/__init__.py

     
    273273            self.connection.close()
    274274            self.connection = None
    275275
    276     def cursor(self):
     276    def cursor(self, iterating=False):
    277277        if (self.use_debug_cursor or
    278278            (self.use_debug_cursor is None and settings.DEBUG)):
    279             cursor = self.make_debug_cursor(self._cursor())
     279            cursor = self.make_debug_cursor(self._cursor(iterating))
    280280        else:
    281             cursor = util.CursorWrapper(self._cursor(), self)
     281            cursor = util.CursorWrapper(self._cursor(iterating), self)
    282282        return cursor
    283283
    284284    def make_debug_cursor(self, cursor):
  • django/db/backends/postgresql_psycopg2/base.py

     
    105105        self.introspection = DatabaseIntrospection(self)
    106106        self.validation = BaseDatabaseValidation(self)
    107107        self._pg_version = None
     108        self._cursor_prefix = 'namedcursor'
     109        self._cursor_counter = 0
    108110
    109111    def check_constraints(self, table_names=None):
    110112        """
    111113        To check constraints, we set constraints to immediate. Then, when, we're done we must ensure they
    112114        are returned to deferred.
    113115        """
    114         self.cursor().execute('SET CONSTRAINTS ALL IMMEDIATE')
    115         self.cursor().execute('SET CONSTRAINTS ALL DEFERRED')
     116        cursor = self.cursor()
     117        cursor.execute('SET CONSTRAINTS ALL IMMEDIATE')
     118        cursor.execute('SET CONSTRAINTS ALL DEFERRED')
    116119
    117120    def _get_pg_version(self):
    118121        if self._pg_version is None:
     
    120123        return self._pg_version
    121124    pg_version = property(_get_pg_version)
    122125
    123     def _cursor(self):
    124         new_connection = False
     126    def _generate_cursor_name(self):
     127        self._cursor_counter += 1
     128        return '%s-%d' % (self._cursor_prefix, self._cursor_counter)
     129
     130    def _cursor(self, iterating=False):
    125131        set_tz = False
    126132        settings_dict = self.settings_dict
    127133        if self.connection is None:
    128             new_connection = True
    129134            set_tz = settings_dict.get('TIME_ZONE')
    130135            if settings_dict['NAME'] == '':
    131136                from django.core.exceptions import ImproperlyConfigured
     
    148153            self.connection.set_client_encoding('UTF8')
    149154            self.connection.set_isolation_level(self.isolation_level)
    150155            connection_created.send(sender=self.__class__, connection=self)
    151         cursor = self.connection.cursor()
    152         cursor.tzinfo_factory = None
    153         if new_connection:
    154156            if set_tz:
    155                 cursor.execute("SET TIME ZONE %s", [settings_dict['TIME_ZONE']])
     157                # use a throwaway cursor for this SET; if we are creating a
     158                # named cursor later this would cause problems otherwise
     159                self.connection.cursor().execute("SET TIME ZONE %s", [settings_dict['TIME_ZONE']])
    156160            self._get_pg_version()
     161        if iterating:
     162            cursor = self.connection.cursor(name=self._generate_cursor_name())
     163        else:
     164            cursor = self.connection.cursor()
     165        cursor.tzinfo_factory = None
    157166        return CursorWrapper(cursor)
    158167
    159168    def _enter_transaction_management(self, managed):
Back to Top