def __init__(self, wrapped_obj): # make sure our object is wrapped by containment only try: self.path = '/'.join(wrapped_obj.getPhysicalPath()) except AttributeError: self.path = None # If the path ends with /, it means the object had an empty id. # This means it's not yet added to the container, and so we have # to defer. if self.path is not None and self.path.endswith('/'): raise NotYet(wrapped_obj) self.object = aq_base(wrapped_obj) connection = IConnection(wrapped_obj, None) if not getattr(self.object, '_p_oid', None): if connection is None: raise NotYet(wrapped_obj) connection.add(self.object) try: root = get_root(wrapped_obj) except AttributeError: # If the object is unwrapped we can try to use the Site from the # threadlocal as our acquisition context, hopefully it's not # something odd. root = get_root(getSite()) self.root_oid = root._p_oid self.root_dbname = IConnection(root).db().database_name self.oid = self.object._p_oid self.dbname = connection.db().database_name
def __init__(self, object): if not getattr(object, '_p_oid', None): connection = IConnection(object, None) if connection is None: raise zope.keyreference.interfaces.NotYet(object) connection.add(object) self.object = object
def hash_persistent(obj): oid = obj._p_oid connection = obj._p_jar if oid is None or connection is None: connection = IConnection(obj, None) if connection is None: raise zope.keyreference.interfaces.NotYet(obj) connection.add(obj) oid = obj._p_oid database_name = connection.db().database_name return hash((database_name, oid))
def add_object_to_connection(ob, event): """Pre-add new objects to their persistence connection""" connection = IConnection(ob, None) if None is not connection: connection.add(aq_base(ob))
def to_external_oid(self, default=None, add_to_connection=False, add_to_intids=False, use_cache=True): # Override the signature to *not* document use_cache. """ to_external_oid(self, default=None, add_to_connection=False, add_to_intids=False) -> bytes For a `persistent object <persistent.Persistent>`, returns its `persistent OID <persistent.interfaces.IPersistent._p_oid>` in a parseable external format (see :func:`.from_external_oid`). This format includes the database name (so it works in a ZODB multi-database) and the integer ID from the closest :class:`zope.intid.interfaces.IIntIds` utility. If the object implements a method ``toExternalOID()``, that method will be called and its result (or the *default*) will be returned. This should generally be considered legacy behaviour. If the object has not been saved, and *add_to_connection* is `False` (the default) returns the *default*. :param bool add_to_connection: If the object is persistent but not yet added to a connection, setting this to true will attempt to add it to the nearest connection in its containment tree, thus letting it have an OID. :param bool add_to_intids: If we can obtain an OID for this object, but it does not have an intid, and an intid utility is available, then if this is `True` (not the default) we will register it with the utility. :return: A :class:`bytes` string. """ # TODO: Simplify # pylint:disable=too-many-branches try: return self.toExternalOID() or default except AttributeError: pass if use_cache: # XXX: And yet we still set it always. try: # See comments in to_external_ntiid_oid return getattr(self, '_v_to_external_oid') except AttributeError: pass # because if it was proxied, we should still read the right thing above; # this saves time self = removeAllProxies(self) try: oid = self._p_oid except AttributeError: return default jar = None if not oid: if add_to_connection: try: jar = IConnection(self) except TypeError: return default jar.add(self) oid = self._p_oid else: return default # The object ID is defined to be 8 charecters long. It gets # padded with null chars to get to that length; we strip # those out. Finally, it probably has chars that # aren't legal in UTF or ASCII, so we go to hex and prepend # a flag, '0x' # TODO: Why are we keeping this as a bytes string, not unicode? oid = oid.lstrip(b'\x00') oid = b'0x' + binascii.hexlify(oid) try: jar = jar or self._p_jar except AttributeError: pass if jar: db_name = jar.db().database_name oid = oid + b':' + binascii.hexlify(bytes_(db_name)) intutility = component.queryUtility(IIntIds) if intutility is not None: intid = intutility.queryId(self) if intid is None and add_to_intids: intid = intutility.register(self) if intid is not None: if not jar: oid = oid + b':' # Ensure intid is always the third part oid = oid + b':' + bytes_(to_external_string(intid)) try: setattr(self, str('_v_to_external_oid'), oid) except (AttributeError, TypeError): # pragma: no cover pass return oid