def store(self, oid, serial, data, version, transaction):
        if transaction is not self._transaction:
            raise POSException.StorageTransactionError(self, transaction)
        assert not version

        self._lock_acquire()
        try:
            if oid in self._index:
                oserial = self._index[oid]
                if serial != oserial:
                    newdata = self.tryToResolveConflict(
                                            oid, oserial, serial, data)
                    if not newdata:
                        raise POSException.ConflictError(
                                            oid=oid,
                                            serials=(oserial, serial),
                                            data=data)
                    else:
                        data = newdata
            else:
                oserial = serial
            newserial = self._tid
            self._tmp.append((oid, data))
            return serial == oserial and newserial or ResolvedSerial
        finally:
            self._lock_release()
示例#2
0
    def tpc_begin(self, txn, tid=None, status=' '):
        """Storage API: begin a transaction."""
        if self._is_read_only:
            raise POSException.ReadOnlyError()

        try:
            tbuf = txn.data(self)
        except AttributeError:
            # Gaaaa. This is a recovery transaction. Work around this
            # until we can think of something better. XXX
            tb = {}
            txn.data = tb.__getitem__
            txn.set_data = tb.__setitem__
        except KeyError:
            pass
        else:
            if tbuf is not None:
                raise POSException.StorageTransactionError(
                    "Duplicate tpc_begin calls for same transaction")

        txn.set_data(self, TransactionBuffer(self._connection_generation))

        # XXX we'd like to allow multiple transactions at a time at some point,
        # but for now, due to server limitations, TCBOO.
        self._commit_lock.acquire()
        self._tbuf = txn.data(self)

        try:
            self._async('tpc_begin', id(txn), txn.user, txn.description,
                        txn.extension, tid, status)
        except ClientDisconnected:
            self.tpc_end(txn)
            raise
示例#3
0
    def store(self, oid, serial, data, version, transaction):
        if transaction is not self._transaction:
            raise POSException.StorageTransactionError(self, transaction)
        if version:
            # we allow a version to be in use although we don't
            # support versions in the storage.
            LOG.debug('versions in use with TemporaryStorage although Temporary '
                      'Storage doesnt support versions')

        self._lock_acquire()
        try:
            if self._index.has_key(oid):
                oserial=self._index[oid]
                if serial != oserial:
                    newdata = self.tryToResolveConflict(
                        oid, oserial, serial, data)
                    if not newdata:
                        raise POSException.ConflictError(
                            oid=oid,
                            serials=(oserial, serial),
                            data=data)
                    else:
                        data = newdata
            else:
                oserial = serial
            newserial=self._tid
            self._tmp.append((oid, data))
            return serial == oserial and newserial or ResolvedSerial
        finally:
            self._lock_release()
示例#4
0
 def _check_trans(self, trans):
     """Internal helper to check a transaction argument for sanity."""
     if self._is_read_only:
         raise POSException.ReadOnlyError()
     if self._transaction is not trans:
         raise POSException.StorageTransactionError(self._transaction,
                                                    trans)
示例#5
0
文件: util.py 项目: bendavis78/zope
    def store(self, oid, serial, data, version, transaction):
        if transaction is not self._transaction:
            raise POSException.StorageTransactionError(self, transaction)

        if version:
            raise POSException.Unsupported("Versions aren't supported")

        self._lock_acquire()
        try:
            if oid in self._index:
                oserial = self._index[oid][:8]
                if serial != oserial:
                    rdata = self.tryToResolveConflict(oid, oserial, serial,
                                                      data)
                    if rdata is None:
                        raise POSException.ConflictError(oid=oid,
                                                         serials=(oserial,
                                                                  serial),
                                                         data=data)
                    else:
                        data = rdata
            self._tindex[oid] = self._tid + data
        finally:
            self._lock_release()
        return self._tid
示例#6
0
    def commitVersion(self, src, dest, transaction):
        if transaction is not self._transaction:
            raise POSException.StorageTransactionError(self, transaction)

        if not src:
            raise POSException.VersionCommitError("Invalid source version")
        if src == dest:
            raise POSException.VersionCommitError(
                "Can't commit to same version: %s" % repr(src))

        self._lock_acquire()
        try:
            v = self._vindex.get(src)
            if v is None:
                return

            newserial = self._tid
            tindex = self._tindex
            oids = []
            for r in v.values():
                oid, pre, vdata, p, tid = r
                assert vdata is not None
                oids.append(oid)
                if dest:
                    new_vdata = dest, vdata[1]
                else:
                    new_vdata = None
                tindex.append([oid, r, new_vdata, p, self._tid])

            return self._tid, oids

        finally:
            self._lock_release()
示例#7
0
    def abortVersion(self, src, transaction):
        if transaction is not self._transaction:
            raise POSException.StorageTransactionError(self, transaction)
        if not src:
            raise POSException.VersionCommitError("Invalid version")

        self._lock_acquire()
        try:
            v = self._vindex.get(src, None)
            if not v:
                return

            oids = []
            for r in v.values():
                oid, pre, (version, nv), p, tid = r
                oids.append(oid)
                if nv:
                    oid, pre, vdata, p, tid = nv
                    self._tindex.append([oid, r, None, p, self._tid])
                else:
                    # effectively, delete the thing
                    self._tindex.append([oid, r, None, None, self._tid])

            return self._tid, oids

        finally: self._lock_release()
示例#8
0
def checkCurrentSerialInTransaction(self, oid, serial, transaction):
    if transaction is not self._transaction:
        raise POSException.StorageTransactionError(self, transaction)

    committed_tid = self.getTid(oid)
    if committed_tid != serial:
        raise POSException.ReadConflictError(
            oid=oid, serials=(committed_tid, serial))
示例#9
0
 def tpc_vote(self, transaction):
     self._lock_acquire()
     try:
         if transaction is not self._transaction:
             raise POSException.StorageTransactionError(
                 "tpc_vote called with wrong transaction")
         self._vote()
     finally:
         self._lock_release()
示例#10
0
 def store(self, oid, serial, data, v, txn):
     if txn is not self._transaction:
         raise POSException.StorageTransactionError(self, txn)
     assert not v
     if self._cur.get(oid) != serial:
         if not (serial is None or self._cur.get(oid) in [None, z64]):
             raise POSException.ConflictError(
                 oid=oid, serials=(self._cur.get(oid), serial), data=data)
     self._txn.store(oid, data)
     return self._tid
示例#11
0
    def store(self, oid, serial, data, version, transaction):
        if transaction is not self._transaction:
            raise POSException.StorageTransactionError(self, transaction)

        self._lock_acquire()
        try:
            old = self._index.get(oid, None)
            if old is None:
                # Hm, nothing here, check the base version:
                if self._base:
                    try:
                        p, tid = self._base.load(oid, '')
                    except KeyError:
                        pass
                    else:
                        old = oid, None, None, p, tid

            nv=None
            if old:
                oid, pre, vdata, p, tid = old

                if vdata:
                    if vdata[0] != version:
                        raise POSException.VersionLockError(oid)

                    nv=vdata[1]
                else:
                    nv=old

                if serial != tid:
                    raise POSException.ConflictError(
                        oid=oid, serials=(tid, serial), data=data)

            r = [oid, old, version and (version, nv) or None, data, self._tid]
            self._tindex.append(r)

            s=self._tsize
            s=s+72+(data and (16+len(data)) or 4)
            if version: s=s+32+len(version)

            if self._quota is not None and s > self._quota:
                raise POSException.StorageError(
                    '''<b>Quota Exceeded</b><br>
                    The maximum quota for this demonstration storage
                    has been exceeded.<br>Have a nice day.''')

        finally: self._lock_release()
        return self._tid
示例#12
0
    def _check_trans(self, trans, meth):
        """Internal helper to check a transaction argument for sanity."""
        if self._is_read_only:
            raise POSException.ReadOnlyError()

        try:
            buf = trans.data(self)
        except KeyError:
            buf = None

        if buf is None:
            raise POSException.StorageTransactionError(
                "Transaction not committing", meth, trans)

        if buf.connection_generation != self._connection_generation:
            # We were disconnected, so this one is poisoned
            raise ClientDisconnected(meth, 'on a disconnected transaction')

        return buf
示例#13
0
    def store(self, oid, serial, data, version, transaction):
        if transaction is not self._transaction:
            raise POSException.StorageTransactionError(self, transaction)
        assert not version

        with self._lock:
            if oid in self._index:
                oserial = self._index[oid]
                if serial != oserial:
                    newdata = self.tryToResolveConflict(
                        oid, oserial, serial, data)
                    if not newdata:
                        raise POSException.ConflictError(oid=oid,
                                                         serials=(oserial,
                                                                  serial),
                                                         data=data)
                    else:
                        data = newdata
            else:
                oserial = serial
            self._tmp.append((oid, data))
示例#14
0
    def tpc_begin(self, transaction, tid=None, status=' '):
        if self._is_read_only:
            raise POSException.ReadOnlyError()
        self._lock_acquire()
        try:
            if self._transaction is transaction:
                raise POSException.StorageTransactionError(
                    "Duplicate tpc_begin calls for same transaction")
            self._lock_release()
            self._commit_lock_acquire()
            self._lock_acquire()
            self._transaction = transaction
            self._clear_temp()

            user = transaction.user
            desc = transaction.description
            ext = transaction._extension
            if ext:
                ext = cPickle.dumps(ext, 1)
            else:
                ext = ""

            self._ude = user, desc, ext

            if tid is None:
                now = time.time()
                t = TimeStamp(*(time.gmtime(now)[:5] + (now % 60,)))
                self._ts = t = t.laterThan(self._ts)
                self._tid = repr(t)
            else:
                self._ts = TimeStamp(tid)
                self._tid = tid

            self._tstatus = status
            self._begin(self._tid, user, desc, ext)
        finally:
            self._lock_release()
示例#15
0
    def tpc_finish(self, transaction, f=None):
        # It's important that the storage calls the function we pass
        # while it still has its lock.  We don't want another thread
        # to be able to read any updated data until we've had a chance
        # to send an invalidation message to all of the other
        # connections!

        self._lock_acquire()
        try:
            if transaction is not self._transaction:
                raise POSException.StorageTransactionError(
                    "tpc_finish called with wrong transaction")
            try:
                if f is not None:
                    f(self._tid)
                u, d, e = self._ude
                self._finish(self._tid, u, d, e)
                self._clear_temp()
            finally:
                self._ude = None
                self._transaction = None
                self._commit_lock_release()
        finally:
            self._lock_release()
示例#16
0
 def commitVersion(self, src, dest, transaction):
     if transaction is not self._transaction:
         raise POSException.StorageTransactionError(self, transaction)
     return self._tid, []
示例#17
0
    def store(self, oid, h64, data, version, transaction):
        if transaction is not self._transaction:
            raise POSException.StorageTransactionError(self, transaction)

        if version:
            raise POSException.Unsupported, "Versions aren't supported"

        self._lock_acquire()
        try:
            self.conf_resource.access(self)  # Update configuration

            # First detect conflicts.
            # The "h64" argument, if its value is not 0,
            # was previously generated by hash64().
            if h64 == HASH0:
                # Writing a new object.
                is_new = True
            else:
                # Overwriting an old object.  Use the hash to verify
                # that the new data was derived from the old data.
                is_new = False
                event, old_c, old_state, old_hash = self._gwio.load(oid)
                old_h64 = self.hash64(old_hash)
                if h64 != old_h64:
                    h = None
                    if self.debug_conflicts:
                        h = self._loaded_hashes.get(oid)
                    if h is None:
                        h = h64
                        old_hash = old_h64
                    error = ("Storing %s based on old data.  %s != %s." %
                             (repr(oid), repr(h), repr(old_hash)))
                    if self.debug_conflicts:
                        # Expose the error for debugging..
                        raise RuntimeError(error)
                    else:
                        # Use normal ZODB conflict errors.
                        raise POSException.ConflictError(error)

            # Now unpickle and store the data.
            file = StringIO(data)
            u = Unpickler(file)
            classification = u.load()
            state = u.load()
            event, new_hash = self._gwio.store(oid, classification, state,
                                               is_new)
            new_h64 = self.hash64(new_hash)
            if self.debug_conflicts:
                self._loaded_hashes[oid] = new_hash

            # Remember that this OID changed (for scanning)
            tid = self.getTransactionId()
            t = self.changed.get(tid)
            if t is None:
                t = {}
                self.changed[tid] = t
            t[oid] = 1
        finally:
            self._lock_release()

        return new_h64