def fetch_id(self, storable): """ Fetch an ID for this object, if possible. "Predict" the id for this storable. If GUIDs are being used, this method will fetch a new GUID, set it, and return that ID immediately (assuming that this object will ultimately be saved with that ID). If GUIDs are not being used, this method will return 0 if this is an unsaved object. It's not possible to use "predictive" IDs in that case. @see: L{IFactory.fetch_id()} @param storable: the object whose ID you wish to fetch @type storable: L{storable.Storable} @returns: the item's id, or 0 @rtype: int @raises LookupError: if no factory has been registered for this Storable's table """ id = storable.get_id() if(id == 0): table = storable.get_table() if not(self.has_factory(table)): raise LookupError('There is no factory registered for the table `%s`' % table) factory = self.get_factory(table) use_locks = (not bool(self.req)) or self.req.app.config.get('use_db_locks', True) new_id = factory.get_id(use_locks=use_locks) storable.set_id(new_id, set_old=False) return new_id return id
def _save(self, storable, factory): """ Internal function that is responsible for doing the actual saving. """ if not(storable.is_dirty()): return False table = storable.get_table() data = storable.get_data() locks_allowed = (not bool(self.req)) or self.req.app.config.get('use_db_locks', True) use_locks = False primary_key = factory.get_primary_key() if(storable.is_new()): if(factory.uses_guids()): data[primary_key] = self.fetch_id(storable) elif(locks_allowed): use_locks = True self.pool.runOperation('LOCK TABLES `%s` WRITE' % table) else: raise RuntimeError("Broken program logic is trying to lock an unlockable database.") query = sql.build_insert(table, data) else: query = sql.build_update(table, data, {primary_key:storable.get_id()}) self.log(query) try: self.pool.runOperation(query) if not(factory.uses_guids()): if not(storable.get_id()): rows = self.pool.runQuery('SELECT MAX(%s) AS `id` FROM `%s`' % (primary_key, table)) new_id = rows[0]['id'] storable.set_id(new_id) finally: if(use_locks): self.pool.runOperation('UNLOCK TABLES') storable.clean() storable.set_new(False) storable.set_factory(factory) return True