Ejemplo n.º 1
0
 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})
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
    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