def _getCleanFilename(self, oid, tid): return os.path.join( self._getBlobPath(), "%s-%s%s" % ( utils.oid_repr(oid), utils.tid_repr(tid), SAVEPOINT_SUFFIX, ))
def objpool_add(self, actual_conn, actual_obj, traceback): """ Add an object and connection to the pool """ # Get connections pool poid = actual_obj._p_oid if poid in self.obj_pool.keys(): connections_pool = self.obj_pool[poid] else: connections_pool = {} self.appendLog("objpool_add, added: %s, %s" % (actual_obj, tid_repr(poid)), level=logging.DEBUG) self.obj_pool[poid] = connections_pool # The object is already been edit in ... if connections_pool.keys(): if actual_conn in connections_pool.keys(): # ... this connection if not self.FIRST_CHANGE_ONLY: self.appendLog(MSG_OBJ_CONTINUE_EDITING, level=logging.DEBUG, connection=actual_conn, obj=actual_obj) tb_info = self.frm(MSG_OBJ_CONTINUE_EDITING) connections_pool[actual_conn] += "\n%s traceback:\n%s" % (tb_info, traceback) return True else: # ... another connection self.appendLog(MSG_OBJ_ALREADY_EDITED, level=logging.DEBUG, connection=actual_conn, obj=actual_obj) tb_info = self.frm(MSG_OBJ_ALREADY_EDITED, connection=actual_conn, obj=actual_obj) connections_pool[actual_conn] = "%s traceback:\n%s" % (tb_info , traceback) return True else: # The object start to is already been edit in .. self.appendLog(MSG_OBJ_EDITING, level=logging.DEBUG, connection=actual_conn, obj=actual_obj) tb_info = self.frm(MSG_OBJ_EDITING, connection=actual_conn, obj=actual_obj) connections_pool[actual_conn] = "%s traceback:\n%s" % (tb_info , traceback) return True
def sanitize_cache(self): """ Remove the obj_pool if no more references """ # Remove connections from pool for poid, connections_pool in self.obj_pool.items(): conn_todel = [] for conn in connections_pool: registered_obj_oids = [o._p_oid for o in conn._registered_objects] if poid not in registered_obj_oids: conn_todel.append(conn) # Removed objects for conn in conn_todel: self.appendLog("sanitize_cache, Removed connection: %s" % conn, level=logging.DEBUG) self.obj_pool[poid].pop(conn) # find objects with no information obj_todel = [] for poid, connections_pool in self.obj_pool.items(): if not connections_pool: obj_todel.append(poid) # Removed objects for poid in obj_todel: self.appendLog("sanitize_cache, Removed object: %s" % tid_repr(poid), level=logging.DEBUG) self.obj_pool.pop(poid)
def report(self): """Show all msgs, grouped by oid and sub-grouped by tid.""" msgs = self.msgs oids = self.oids oid2name = self.oid2name # First determine which oids weren't seen at all, and synthesize msgs # for them. NOT_SEEN = "this oid was not defined (no data record for it found)" for oid in oids: if oid not in oid2name: msgs.append((oid, None, NOT_SEEN)) msgs.sort() # oids are primary key, tids secondary current_oid = current_tid = None for oid, tid, msg in msgs: if oid != current_oid: nrev = oids[oid] revision = "revision" + (nrev != 1 and 's' or '') name = oid2name.get(oid, "<unknown>") print "oid", oid_repr(oid), name, nrev, revision current_oid = oid current_tid = None if msg is NOT_SEEN: assert tid is None print " ", msg continue if tid != current_tid: current_tid = tid status, user, description, pos = self.tid2info[tid] print " tid %s offset=%d %s" % (tid_repr(tid), pos, TimeStamp(tid)) print " tid user=%r" % shorten(user) print " tid description=%r" % shorten(description) print " ", msg
def getBlobFilePath(self, oid, tid): """Given an oid and a tid, return the full filename of the 'committed' blob file related to that oid and tid. """ oid_path = self.oid_to_path(oid) filename = "%s%s" % (utils.tid_repr(tid), BLOB_SUFFIX) return os.path.join(oid_path, filename)
def getBlobFilename(self, oid, tid): """Given an oid and a tid, return the full filename of the 'committed' blob file related to that oid and tid. """ oid_path = self.getPathForOID(oid) # TIDs are numbers and sometimes passed around as integers. For our # computations we rely on the 64-bit packed string representation if isinstance(tid, int): tid = utils.p64(tid) filename = "%s%s" % (utils.tid_repr(tid), BLOB_SUFFIX) return os.path.join(oid_path, filename)
def lastChange(self, tid=None): if self._history is None: self._load() if tid in self._by_tid: # optimization return tid # sadly ZODB has no API for get revision at or before tid, so # we have to find the exact tid for record in self._history: # we assume records are ordered by tid, newest to oldest if tid is None or record['tid'] <= tid: return record['tid'] raise KeyError('%r did not exist in or before transaction %r' % (self._obj, tid_repr(tid)))
def testCall(self): request = TestRequest() view = self._zodbInfoView(self.root, request) self.assertEqual(view(), '') self.assertEqual(view.latest, True) tid = ZodbObjectState(self.root).tid request = TestRequest(form={'tid': tid_repr(tid)}) view = self._zodbInfoView(self.root, request) self.assertEqual(view.latest, False) oid = self.root._p_oid request = TestRequest(form={'oid': oid_repr(oid)}) request.annotations['ZODB.interfaces.IConnection'] = self.root._p_jar view = self._zodbInfoView(None, request)
def testCall(self): request = TestRequest() view = self._zodbInfoView(self.root, request) self.assertEquals(view(), '') self.assertEquals(view.latest, True) tid = ZodbObjectState(self.root).tid request = TestRequest(form={'tid': tid_repr(tid)}) view = self._zodbInfoView(self.root, request) self.assertEquals(view.latest, False) oid = self.root._p_oid request = TestRequest(form={'oid': oid_repr(oid)}) request.annotations['ZODB.interfaces.IConnection'] = self.root._p_jar view = self._zodbInfoView(None, request)
def blob_mkstemp(self, oid, tid): """Given an oid and a tid, return a temporary file descriptor and a related filename. The file is guaranteed to exist on the same partition as committed data, which is important for being able to rename the file without a copy operation. The directory in which the file will be placed, which is the return value of self.getPathForOID(oid), must exist before this method may be called successfully. """ oidpath = self.getPathForOID(oid) fd, name = tempfile.mkstemp(suffix='.tmp', prefix=utils.tid_repr(tid), dir=oidpath) return fd, name
def lastChange(self, tid=None): if self._history is None: self._load() if tid in self._by_tid: # optimization return tid # sadly ZODB has no API for get revision at or before tid, so # we have to find the exact tid for record in self._history: # we assume records are ordered by tid, newest to oldest if tid is None or record['tid'] <= tid: return record['tid'] if tid is None: # It means there is just no history, so the object is broken. raise POSKeyError(self._obj._p_oid) raise HistoryMissingError( '%r did not exist in or before transaction %r' % (self._obj, tid_repr(tid)))
def frm(self, msg, thread=None, connection=None, obj=None, traceback=None): """ Format the message to the log. """ msg_h = ["time: %s" % time.strftime('%H:%M:%S')] if thread: msg_h.append("thread: %s" % thread.get_ident()) if connection: msg_h.append("connection: %s" % connection) if obj: oid = obj._p_oid oid_str = tid_repr(oid) msg_h.append("object._p_oid: %s" % oid_str) msg_h.append("object.to_string: %s" % obj) msg = "[%s]: %s" % (", ".join(msg_h), msg) if traceback: msg += ">>>>>>>>\n%s\n<<<<<<<<" % traceback return msg
def report(self): """Show all msgs, grouped by oid and sub-grouped by tid.""" msgs = self.msgs oids = self.oids oid2name = self.oid2name # First determine which oids weren't seen at all, and synthesize msgs # for them. NOT_SEEN = "this oid was not defined (no data record for it found)" for oid in oids: if oid not in oid2name: msgs.append( (oid, None, NOT_SEEN) ) msgs.sort() # oids are primary key, tids secondary current_oid = current_tid = None for oid, tid, msg in msgs: if oid != current_oid: nrev = oids[oid] revision = "revision" + (nrev != 1 and 's' or '') name = oid2name.get(oid, "<unknown>") print "oid", oid_repr(oid), name, nrev, revision current_oid = oid current_tid = None if msg is NOT_SEEN: assert tid is None print " ", msg continue if tid != current_tid: current_tid = tid status, user, description, pos = self.tid2info[tid] print " tid %s offset=%d %s" % (tid_repr(tid), pos, TimeStamp(tid)) print " tid user=%r" % shorten(user) print " tid description=%r" % shorten(description) print " ", msg
def _getCleanFilename(self, oid, tid): return os.path.join( self._getBlobPath(), "%s-%s%s" % (utils.oid_repr(oid), utils.tid_repr(tid), SAVEPOINT_SUFFIX,) )
def _tidToTimestamp(self, tid): if isinstance(tid, bytes) and len(tid) == 8: return str(TimeStamp(tid)) return tid_repr(tid)