Source code for relstorage.adapters.oracle.packundo

##############################################################################
#
# Copyright (c) 2009 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Pack/Undo implementations.
"""
from __future__ import absolute_import

from ..packundo import HistoryFreePackUndo
from ..packundo import HistoryPreservingPackUndo
from .dialect import OracleDialect


def _oracle_fetchmany(self, cursor): # pylint:disable=unused-argument
    # We can't safely fetch many rows at once without
    # getting 'ProgrammingError: LOB variable no longer valid after subsequent fetch'
    # See https://github.com/zodb/relstorage/issues/30
    return cursor



# Oracle fails to notice that pack_object is now filled and chooses
# the wrong execution plan, completely killing this query on large
# RelStorage databases, unless these hints are included.
_oracle_traverse_graph_optimizer_hint = "/*+ FULL(object_ref) FULL(pack_object) */"


[docs] class OracleHistoryPreservingPackUndo(HistoryPreservingPackUndo): dialect = OracleDialect() _script_choose_pack_transaction = """ SELECT MAX(tid) FROM transaction WHERE tid > 0 AND tid <= %(tid)s AND packed = 'N' """ _script_create_temp_pack_visit = None _script_create_temp_undo = None _script_reset_temp_undo = "DELETE FROM temp_undo" _script_find_pack_tid = """ SELECT MAX(keep_tid) FROM pack_object """ _script_transaction_has_data = """ SELECT DISTINCT tid FROM object_state WHERE tid = %(tid)s """ _script_delete_empty_transactions_batch = """ DELETE FROM transaction WHERE packed = %(TRUE)s AND empty = %(TRUE)s AND rownum <= 1000 """ # XXX: This is necessary # (https://github.com/zodb/relstorage/issues/135), but the HP # tests don't fail without it. _fetchmany = _oracle_fetchmany _traverse_graph_optimizer_hint = _oracle_traverse_graph_optimizer_hint
[docs] class OracleHistoryFreePackUndo(HistoryFreePackUndo): dialect = OracleDialect() _script_choose_pack_transaction = """ SELECT MAX(tid) FROM object_state WHERE tid > 0 AND tid <= %(tid)s """ _script_create_temp_pack_visit = None _fetchmany = _oracle_fetchmany _traverse_graph_optimizer_hint = _oracle_traverse_graph_optimizer_hint
def _check_limit(c): for b in c.mro(): for k, v in vars(b).items(): if hasattr(v, 'bind'): v = v.bind(c.dialect) if 'LIMIT ' in str(v): raise TypeError("Forgot to override %s in %s" % (k, c)) _check_limit(OracleHistoryPreservingPackUndo) _check_limit(OracleHistoryFreePackUndo)