def __init__(self, dbConnection):
     # this is to skip __del__ in case of an exception in this __init__
     self._obsolete = True
     self._dbConnection = dbConnection
     self._connection = dbConnection.getConnection()
     self._dbConnection._setAutoCommit(self._connection, 0)
     self.cache = CacheSet(cache=dbConnection.doCache)
     self._deletedCache = {}
     self._obsolete = False
 def __init__(self,
              name=None,
              debug=False,
              debugOutput=False,
              cache=True,
              style=None,
              autoCommit=True,
              debugThreading=False,
              registry=None,
              logger=None,
              loglevel=None):
     self.name = name
     self.debug = Boolean(debug)
     self.debugOutput = Boolean(debugOutput)
     self.debugThreading = Boolean(debugThreading)
     self.debugWriter = makeDebugWriter(self, logger, loglevel)
     self.doCache = Boolean(cache)
     self.cache = CacheSet(cache=self.doCache)
     self.style = style
     self._connectionNumbers = {}
     self._connectionCount = 1
     self.autoCommit = Boolean(autoCommit)
     self.registry = registry or None
     classregistry.registry(self.registry).addCallback(self.soClassAdded)
     registerConnectionInstance(self)
     atexit.register(_closeConnection, weakref.ref(self))
Beispiel #3
0
 def __init__(self, dbConnection):
     self._obsolete = False
     self._dbConnection = dbConnection
     self._connection = dbConnection.getConnection()
     self._dbConnection._setAutoCommit(self._connection, 0)
     self.cache = CacheSet(cache=dbConnection.doCache)
     self._deletedCache = {}
 def __init__(self, dbConnection):
     # this is to skip __del__ in case of an exception in this __init__
     self._obsolete = True
     self._dbConnection = dbConnection
     self._connection = dbConnection.getConnection()
     self._dbConnection._setAutoCommit(self._connection, 0)
     self.cache = CacheSet(cache=dbConnection.doCache)
     self._deletedCache = {}
     self._obsolete = False
class Transaction(object):
    def __init__(self, dbConnection):
        # this is to skip __del__ in case of an exception in this __init__
        self._obsolete = True
        self._dbConnection = dbConnection
        self._connection = dbConnection.getConnection()
        self._dbConnection._setAutoCommit(self._connection, 0)
        self.cache = CacheSet(cache=dbConnection.doCache)
        self._deletedCache = {}
        self._obsolete = False

    def assertActive(self):
        assert not self._obsolete, "This transaction has already gone through ROLLBACK; begin another transaction"

    def query(self, s):
        self.assertActive()
        return self._dbConnection._query(self._connection, s)

    def queryAll(self, s):
        self.assertActive()
        return self._dbConnection._queryAll(self._connection, s)

    def queryOne(self, s):
        self.assertActive()
        return self._dbConnection._queryOne(self._connection, s)

    def queryInsertID(self, soInstance, id, names, values):
        self.assertActive()
        return self._dbConnection._queryInsertID(self._connection, soInstance,
                                                 id, names, values)

    def iterSelect(self, select):
        self.assertActive()
        # We can't keep the cursor open with results in a transaction,
        # because we might want to use the connection while we're
        # still iterating through the results.
        # @@: But would it be okay for psycopg, with threadsafety
        # level 2?
        return iter(
            list(
                select.IterationClass(self,
                                      self._connection,
                                      select,
                                      keepConnection=True)))

    def _SO_delete(self, inst):
        cls = inst.__class__.__name__
        if not cls in self._deletedCache:
            self._deletedCache[cls] = []
        self._deletedCache[cls].append(inst.id)
        meth = new.instancemethod(self._dbConnection._SO_delete.im_func, self,
                                  self.__class__)
        return meth(inst)

    def commit(self, close=False):
        if self._obsolete:
            # @@: is it okay to get extraneous commits?
            return
        if self._dbConnection.debug:
            self._dbConnection.printDebug(self._connection, '', 'COMMIT')
        self._connection.commit()
        subCaches = [(sub[0], sub[1].allIDs())
                     for sub in self.cache.allSubCachesByClassNames().items()]
        subCaches.extend([(x[0], x[1]) for x in self._deletedCache.items()])
        for cls, ids in subCaches:
            for id in ids:
                inst = self._dbConnection.cache.tryGetByName(id, cls)
                if inst is not None:
                    inst.expire()
        if close:
            self._makeObsolete()

    def rollback(self):
        if self._obsolete:
            # @@: is it okay to get extraneous rollbacks?
            return
        if self._dbConnection.debug:
            self._dbConnection.printDebug(self._connection, '', 'ROLLBACK')
        subCaches = [(sub, sub.allIDs()) for sub in self.cache.allSubCaches()]
        self._connection.rollback()

        for subCache, ids in subCaches:
            for id in ids:
                inst = subCache.tryGet(id)
                if inst is not None:
                    inst.expire()
        self._makeObsolete()

    def __getattr__(self, attr):
        """
        If nothing else works, let the parent connection handle it.
        Except with this transaction as 'self'.  Poor man's
        acquisition?  Bad programming?  Okay, maybe.
        """
        self.assertActive()
        attr = getattr(self._dbConnection, attr)
        try:
            func = attr.im_func
        except AttributeError:
            if isinstance(attr, ConnWrapper):
                return ConnWrapper(attr._soClass, self)
            else:
                return attr
        else:
            meth = new.instancemethod(func, self, self.__class__)
            return meth

    def _makeObsolete(self):
        self._obsolete = True
        if self._dbConnection.autoCommit:
            self._dbConnection._setAutoCommit(self._connection, 1)
        self._dbConnection.releaseConnection(self._connection, explicit=True)
        self._connection = None
        self._deletedCache = {}

    def begin(self):
        # @@: Should we do this, or should begin() be a no-op when we're
        # not already obsolete?
        assert self._obsolete, "You cannot begin a new transaction session without rolling back this one"
        self._obsolete = False
        self._connection = self._dbConnection.getConnection()
        self._dbConnection._setAutoCommit(self._connection, 0)

    def __del__(self):
        if self._obsolete:
            return
        self.rollback()

    def close(self):
        raise TypeError(
            'You cannot just close transaction - you should either call rollback(), commit() or commit(close=True) to close the underlying connection.'
        )
class Transaction(object):

    def __init__(self, dbConnection):
        # this is to skip __del__ in case of an exception in this __init__
        self._obsolete = True
        self._dbConnection = dbConnection
        self._connection = dbConnection.getConnection()
        self._dbConnection._setAutoCommit(self._connection, 0)
        self.cache = CacheSet(cache=dbConnection.doCache)
        self._deletedCache = {}
        self._obsolete = False

    def assertActive(self):
        assert not self._obsolete, "This transaction has already gone through ROLLBACK; begin another transaction"

    def query(self, s):
        self.assertActive()
        return self._dbConnection._query(self._connection, s)

    def queryAll(self, s):
        self.assertActive()
        return self._dbConnection._queryAll(self._connection, s)

    def queryOne(self, s):
        self.assertActive()
        return self._dbConnection._queryOne(self._connection, s)

    def queryInsertID(self, soInstance, id, names, values):
        self.assertActive()
        return self._dbConnection._queryInsertID(
            self._connection, soInstance, id, names, values)

    def iterSelect(self, select):
        self.assertActive()
        # We can't keep the cursor open with results in a transaction,
        # because we might want to use the connection while we're
        # still iterating through the results.
        # @@: But would it be okay for psycopg, with threadsafety
        # level 2?
        return iter(list(select.IterationClass(self, self._connection,
                                   select, keepConnection=True)))

    def _SO_delete(self, inst):
        cls = inst.__class__.__name__
        if not cls in self._deletedCache:
            self._deletedCache[cls] = []
        self._deletedCache[cls].append(inst.id)
        meth = new.instancemethod(self._dbConnection._SO_delete.im_func, self, self.__class__)
        return meth(inst)

    def commit(self, close=False):
        if self._obsolete:
            # @@: is it okay to get extraneous commits?
            return
        if self._dbConnection.debug:
            self._dbConnection.printDebug(self._connection, '', 'COMMIT')
        self._connection.commit()
        subCaches = [(sub[0], sub[1].allIDs()) for sub in self.cache.allSubCachesByClassNames().items()]
        subCaches.extend([(x[0], x[1]) for x in self._deletedCache.items()])
        for cls, ids in subCaches:
            for id in ids:
                inst = self._dbConnection.cache.tryGetByName(id, cls)
                if inst is not None:
                    inst.expire()
        if close:
            self._makeObsolete()

    def rollback(self):
        if self._obsolete:
            # @@: is it okay to get extraneous rollbacks?
            return
        if self._dbConnection.debug:
            self._dbConnection.printDebug(self._connection, '', 'ROLLBACK')
        subCaches = [(sub, sub.allIDs()) for sub in self.cache.allSubCaches()]
        self._connection.rollback()

        for subCache, ids in subCaches:
            for id in ids:
                inst = subCache.tryGet(id)
                if inst is not None:
                    inst.expire()
        self._makeObsolete()

    def __getattr__(self, attr):
        """
        If nothing else works, let the parent connection handle it.
        Except with this transaction as 'self'.  Poor man's
        acquisition?  Bad programming?  Okay, maybe.
        """
        self.assertActive()
        attr = getattr(self._dbConnection, attr)
        try:
            func = attr.im_func
        except AttributeError:
            if isinstance(attr, ConnWrapper):
                return ConnWrapper(attr._soClass, self)
            else:
                return attr
        else:
            meth = new.instancemethod(func, self, self.__class__)
            return meth

    def _makeObsolete(self):
        self._obsolete = True
        if self._dbConnection.autoCommit:
            self._dbConnection._setAutoCommit(self._connection, 1)
        self._dbConnection.releaseConnection(self._connection,
                                             explicit=True)
        self._connection = None
        self._deletedCache = {}

    def begin(self):
        # @@: Should we do this, or should begin() be a no-op when we're
        # not already obsolete?
        assert self._obsolete, "You cannot begin a new transaction session without rolling back this one"
        self._obsolete = False
        self._connection = self._dbConnection.getConnection()
        self._dbConnection._setAutoCommit(self._connection, 0)

    def __del__(self):
        if self._obsolete:
            return
        self.rollback()

    def close(self):
        raise TypeError('You cannot just close transaction - you should either call rollback(), commit() or commit(close=True) to close the underlying connection.')
Beispiel #7
0
class Transaction(object):

    def __init__(self, dbConnection):
        self._dbConnection = dbConnection
        self._connection = dbConnection.getConnection()
        self._dbConnection._setAutoCommit(self._connection, 0)
        self.cache = CacheSet(cache=dbConnection.doCache)
        self._obsolete = False

    def assertActive(self):
        assert not self._obsolete, "This transaction has already gone through COMMIT/ROLLBACK; create another transaction"

    def query(self, s):
        self.assertActive()
        return self._dbConnection._query(self._connection, s)

    def queryAll(self, s):
        self.assertActive()
        return self._dbConnection._queryAll(self._connection, s)

    def queryOne(self, s):
        self.assertActive()
        return self._dbConnection._queryOne(self._connection, s)

    def queryInsertID(self, soInstance, id, names, values):
        self.assertActive()
        return self._dbConnection._queryInsertID(
            self._connection, soInstance, id, names, values)

    def iterSelect(self, select):
        self.assertActive()
        # We can't keep the cursor open with results in a transaction,
        # because we might want to use the connection while we're
        # still iterating through the results.
        # @@: But would it be okay for psycopg, with threadsafety
        # level 2?
        return iter(list(Iteration(self, self._connection,
                                   select, keepConnection=True)))

    def commit(self):
        if self._obsolete:
            # @@: is it okay to get extraneous commits?
            return
        if self._dbConnection.debug:
            self._dbConnection.printDebug(self._connection, '', 'COMMIT')
        self._connection.commit()

    def rollback(self):
        if self._obsolete:
            # @@: is it okay to get extraneous rollbacks?
            return
        if self._dbConnection.debug:
            self._dbConnection.printDebug(self._connection, '', 'ROLLBACK')
        subCaches = [(sub, sub.allIDs()) for sub in self.cache.allSubCaches()]
        self._connection.rollback()

        for subCache, ids in subCaches:
            for id in ids:
                inst = subCache.tryGet(id)
                if inst is not None:
                    inst.expire()
        self._makeObsolete()

    def __getattr__(self, attr):
        """
        If nothing else works, let the parent connection handle it.
        Except with this transaction as 'self'.  Poor man's
        acquisition?  Bad programming?  Okay, maybe.
        """
        self.assertActive()
        attr = getattr(self._dbConnection, attr)
        try:
            func = attr.im_func
        except AttributeError:
            return attr
        else:
            meth = new.instancemethod(func, self, self.__class__)
            return meth

    def _makeObsolete(self):
        self._obsolete = True
        self._dbConnection.releaseConnection(self._connection,
                                             explicit=True)
        self._connection = None

    def begin(self):
        # @@: Should we do this, or should begin() be a no-op when we're
        # not already obsolete?
        assert self._obsolete, "You cannot begin a new transaction session without committing or rolling back the transaction"
        self._obsolete = False
        self._connection = self._dbConnection.getConnection()

    def __del__(self):
        if self._obsolete:
            return
        self.rollback()