def get(self, oid): """Return the persistent object with oid 'oid'.""" if self.opened is None: raise ConnectionStateError("The database connection is closed") obj = self._cache.get(oid, None) if obj is not None: return obj obj = self._added.get(oid, None) if obj is not None: return obj obj = self._pre_cache.get(oid, None) if obj is not None: return obj p, _ = self._storage.load(oid) obj = self._reader.getGhost(p) # Avoid infiniate loop if obj tries to load its state before # it is added to the cache and it's state refers to it. # (This will typically be the case for non-ghostifyable objects, # like persistent caches.) self._pre_cache[oid] = obj self._cache.new_ghost(oid, obj) self._pre_cache.pop(oid) return obj
def get(self, oid): """Return the persistent object with oid 'oid'.""" if self._opened is None: raise ConnectionStateError("The database connection is closed") obj = self._cache.get(oid, None) if obj is not None: return obj obj = self._added.get(oid, None) if obj is not None: return obj obj = self._pre_cache.get(oid, None) if obj is not None: return obj # This appears to be an MVCC violation because we are loading # the must recent data when perhaps we shouldnt. The key is # that we are only creating a ghost! p, serial = self._storage.load(oid, self._version) obj = self._reader.getGhost(p) # Avoid infiniate loop if obj tries to load its state before # it is added to the cache and it's state refers to it. self._pre_cache[oid] = obj obj._p_oid = oid obj._p_jar = self obj._p_changed = None obj._p_serial = serial self._pre_cache.pop(oid) self._cache[oid] = obj return obj
def close(self, primary=True): """Close the Connection.""" if not self._needs_to_join: # We're currently joined to a transaction. raise ConnectionStateError("Cannot close a connection joined to " "a transaction") if self._cache is not None: self._cache.incrgc() # This is a good time to do some GC # Call the close callbacks. if self.__onCloseCallbacks is not None: callbacks = self.__onCloseCallbacks self.__onCloseCallbacks = None for f in callbacks: try: f() except: # except what? f = getattr(f, 'im_self', f) self._log.exception("Close callback failed for %s", f) self._debug_info = () if self.opened and self.transaction_manager is not None: # transaction_manager could be None if one of the __onCloseCallbacks # closed the DB already, .e.g, ZODB.connection() does this. self.transaction_manager.unregisterSynch(self) am = self._db._activity_monitor if am is not None: am.closedConnection(self) # Drop transaction manager to release resources and help prevent errors self.transaction_manager = None if hasattr(self._storage, 'afterCompletion'): self._storage.afterCompletion() if primary: for connection in self.connections.values(): if connection is not self: connection.close(False) # Return the connection to the pool. if self.opened is not None: self._db._returnToPool(self) # _returnToPool() set self.opened to None. # However, we can't assert that here, because self may # have been reused (by another thread) by the time we # get back here. else: self.opened = None
def add(self, obj): """Add a new object 'obj' to the database and assign it an oid.""" if self.opened is None: raise ConnectionStateError("The database connection is closed") marker = object() oid = getattr(obj, "_p_oid", marker) if oid is marker: raise TypeError( "Only first-class persistent objects may be" " added to a Connection.", obj) elif obj._p_jar is None: self._add(obj, self.new_oid()) elif obj._p_jar is not self: raise InvalidObjectReference(obj, obj._p_jar)
def close(self, primary=True): """Close the Connection.""" if not self._needs_to_join: # We're currently joined to a transaction. raise ConnectionStateError("Cannot close a connection joined to " "a transaction") if self._cache is not None: self._cache.incrgc() # This is a good time to do some GC # Call the close callbacks. if self.__onCloseCallbacks is not None: callbacks = self.__onCloseCallbacks self.__onCloseCallbacks = None for f in callbacks: try: f() except: # except what? f = getattr(f, 'im_self', f) self._log.exception("Close callback failed for %s", f) self._debug_info = () if self.opened: self.transaction_manager.unregisterSynch(self) if primary: for connection in self.connections.values(): if connection is not self: connection.close(False) # Return the connection to the pool. if self.opened is not None: self._db._returnToPool(self) # _returnToPool() set self.opened to None. # However, we can't assert that here, because self may # have been reused (by another thread) by the time we # get back here. else: self.opened = None am = self._db._activity_monitor if am is not None: am.closedConnection(self)
def setstate(self, obj): """Turns the ghost 'obj' into a real object by loading its state from the database.""" oid = obj._p_oid if self._opened is None: msg = ("Shouldn't load state for %s " "when the connection is closed" % oid_repr(oid)) self._log.error(msg) raise ConnectionStateError(msg) try: self._setstate(obj) except ConflictError: raise except: self._log.error("Couldn't load state for %s", oid_repr(oid), exc_info=sys.exc_info()) raise
def get(self, oid): """Return the persistent object with oid 'oid'.""" if self._opened is None: raise ConnectionStateError("The database connection is closed") obj = self._cache.get(oid, None) if obj is not None: return obj obj = self._added.get(oid, None) if obj is not None: return obj p, serial = self._storage.load(oid, self._version) obj = self._reader.getGhost(p) obj._p_oid = oid obj._p_jar = self obj._p_changed = None obj._p_serial = serial self._cache[oid] = obj return obj
def setstate(self, obj): """Load the state for an (ghost) object """ oid = obj._p_oid if self.opened is None: msg = ("Shouldn't load state for %s %s " "when the connection is closed" % (className(obj), oid_repr(oid))) try: raise ConnectionStateError(msg) except: self._log.exception(msg) raise try: p, serial = self._storage.load(oid) self._load_count += 1 self._reader.setGhostState(obj, p) obj._p_serial = serial self._cache.update_object_size_estimation(oid, len(p)) obj._p_estimated_size = len(p) # Blob support if isinstance(obj, Blob): obj._p_blob_uncommitted = None obj._p_blob_committed = self._storage.loadBlob(oid, serial) except ConflictError: raise except: self._log.exception("Couldn't load state for %s %s", className(obj), oid_repr(oid)) raise
def add(self, obj): """Add a new object 'obj' to the database and assign it an oid.""" if self._opened is None: raise ConnectionStateError("The database connection is closed") marker = object() oid = getattr(obj, "_p_oid", marker) if oid is marker: raise TypeError( "Only first-class persistent objects may be" " added to a Connection.", obj) elif obj._p_jar is None: assert obj._p_oid is None oid = obj._p_oid = self._storage.new_oid() obj._p_jar = self if self._added_during_commit is not None: self._added_during_commit.append(obj) self._register(obj) # Add to _added after calling register(), so that _added # can be used as a test for whether the object has been # registered with the transaction. self._added[oid] = obj elif obj._p_jar is not self: raise InvalidObjectReference(obj, obj._p_jar)
def isReadOnly(self): """Returns True if this connection is read only.""" if self.opened is None: raise ConnectionStateError("The database connection is closed") return self._storage.isReadOnly()
def getVersion(self): """Returns the version this connection is attached to.""" if self._storage is None: raise ConnectionStateError("The database connection is closed") return self._version
def raise_(unused_instance): from ZODB.POSException import ConnectionStateError raise ConnectionStateError()