def delete(self, key, rev=None): tx = self.db.transaction() try: row = self.get_row(key, for_update=True) if row: if rev is not None and str(row.id) != str(rev): raise common.Conflict(key=key, message="Document update conflict") self.delete_row(row.id) except: tx.rollback() raise else: tx.commit() self.fire_event("store.delete", {"key": key})
def put(self, key, doc): if doc.get("_delete") is True: return self.delete(key, doc.get("_rev")) # conflict check is enabled by default. It can be disabled by passing _rev=None in the document. if "_rev" in doc and doc["_rev"] is None: enable_conflict_check = False else: enable_conflict_check = True doc.pop("_key", None) rev = doc.pop("_rev", None) json_data = simplejson.dumps(doc) tx = self.db.transaction() try: row = self.get_row(key, for_update=True) if row: if enable_conflict_check and str(row.id) != str(rev): raise common.Conflict(key=key, message="Document update conflict") self.delete_index(row.id) # store query results are always order by id column. # It is important to update the id so that the newly modified # records show up first in the results. self.db.query( "UPDATE store SET json=$json_data, id=nextval('store_id_seq') WHERE key=$key", vars=locals(), ) id = self.get_row(key=key).id else: id = self.db.insert("store", key=key, json=json_data) self.add_index(id, key, doc) doc['_key'] = key doc['_rev'] = str(id) except: tx.rollback() raise else: tx.commit() self.fire_event("store.put", {"key": key, "data": doc}) return doc
def _load_records(self, keys): """Returns a dictionary of records for the given keys. The records are queried FOR UPDATE to lock those rows from concurrent updates. Each record is a storage object with (id, key, type, revision, last_modified, data) keys. """ try: rows = self.db.query( "SELECT thing.*, data.data FROM thing, data" + " WHERE thing.key in $keys" + " AND data.thing_id=thing.id AND data.revision = thing.latest_revision" + " FOR UPDATE NOWAIT", vars=locals()) except: raise common.Conflict(keys=keys, reason="Edit conflict detected.") records = dict((r.key, r) for r in rows) for r in records.values(): r.revision = r.latest_revision json = r.data and self.process_json(r.key, r.data) r.data = simplejson.loads(json) return records