def _upsert(self, tr, entity, old_entry_future=None): auto_id = self._auto_id(entity) if auto_id: # Avoid mutating the object given. new_entity = entity_pb.EntityProto() new_entity.CopyFrom(entity) entity = new_entity last_element = entity.key().path().element(-1) last_element.set_id(self._scattered_allocator.get_id()) if old_entry_future is None: old_entry = yield self._data_manager.get_latest(tr, entity.key()) else: old_entry = yield old_entry_future # If the datastore chose an ID, don't overwrite existing data. if auto_id and old_entry.present: self._scattered_allocator.invalidate() raise InternalError(u'The datastore chose an existing ID') new_version = next_entity_version(old_entry.version) encoded_entity = entity.Encode() yield self._data_manager.put(tr, entity.key(), new_version, encoded_entity) index_stats = yield self._index_manager.put_entries( tr, old_entry, entity) if old_entry.present: yield self._gc.index_deleted_version(tr, old_entry) new_entry = VersionEntry.from_key(entity.key()) new_entry._encoded_entity = encoded_entity new_entry._decoded_entity = entity new_entry.version = new_version raise gen.Return((old_entry, new_entry, index_stats))
def _delete(self, tr, key, old_entry_future=None): if old_entry_future is None: old_entry = yield self._data_manager.get_latest(tr, key) else: old_entry = yield old_entry_future if not old_entry.present: raise gen.Return((old_entry, None)) new_version = next_entity_version(old_entry.version) yield self._data_manager.put(tr, key, new_version, b'') yield self.index_manager.put_entries(tr, old_entry, new_entity=None) if old_entry.present: yield self._gc.index_deleted_version(tr, old_entry) raise gen.Return((old_entry, new_version))