Write Queries
db
is assumed to be the state variable storing the WeaveDB SDK object. For reference, see Initialize WeaveDB
Also, it is expected that collection_name
refers to the string value that contains the name of your collection, and doc_id
refers to the string value that contains the unique identifier of a document from the collection.
The differences between set
, upsert
, and update
are:
set
- ifdoc_id
exists in the collection, it will override the entire document, deleting all previous properties or it will add a new document ifdoc_id
does not exist.update
- ifdoc_id
exists in the collection, it will merge the new data with the existing document or the query will fail if the assigneddoc_id
does not exist.upsert
- ifdoc_id
exists in the collection, it will merge the new data with the existing document or it will add a new document ifdoc_id
does not exist.
add
To add a new document:
await db.add({ age: 20, name: "Bob" }, collection_name)
The doc id will be randomly yet deterministically assigned.
set
await db.set({ age: 20, name: "Bob" }, collection_name, doc_id)
This will reset the whole document if the doc_id
already exists.
upsert
Upsert will merge the new data with an existing doc or will set a new doc if it does not already exist:
await db.upsert({ age: 20, name: "Bob" }, collection_name, doc_id)
update
Update a document from the collection
await db.update({ age: 25 }, collection_name, doc_id)
This will fail if the doc_id
does not exist.
The following is a list of special operations. WeaveDB has shortcuts for common operations that are only available with the SDK and not with the web console terminal at the moment.
Delete a field
await db.update({ age: db.del() }, collection_name, doc_id)
Increase a field
await db.update({ age: db.inc(5) }, collection_name, doc_id)
Decrease a field
await db.update({ age: db.inc(-5) }, collection_name, doc_id)
Array union
await db.update({ chars: db.union([ "a", "b", "c", "d" ]) }, collection_name, doc_id)
Array remove
await db.update({ chars: db.remove([ "b", "c" ]) }, collection_name, doc_id)
Set block timestamp
await db.update({ date: db.ts() }, collection_name, doc_id)
Set signer Ethereum address
signer
will always be lowercase if it's an EVM wallet address. WeaveDB contract converts everything to lowercase to use them internally.
In regard to Arweave wallet addresses, the case will be retained, because it's RSA hashes and the case matters.
await db.update({ address: db.signer() }, collection_name, doc_id)
delete
Delete a doc
await db.delete(collection_name, doc_id)
batch
An atomic batch is a feature that allows you to perform multiple read and write operations as a single, atomic unit.
Atomic means that all the operations within the batch are either fully completed or completely aborted. If any of the write operations fail, none of the changes will be applied to the database, ensuring data integrity.
await db.batch([
["set", { name: "Bob" }, "people", "Bob"],
["upsert", { name: "Alice" }, "people", "Alice"],
["delete", "John"]
])
You can use batch only if all the queries are by the same signer. If you have multiple signers, use bundle.
Admin queries can be batch-executed as well:
await db.batch([
["setSchema", schema, "people"],
["setRules", rules, "people"],
["addOwner", "0xABC"]
], { ar : admin_arweave_wallet })
bundle
Bundle multiple queries from multiple signers
const query1 = await db.sign("set", {name: "Bob"}, "people", "Bob", {evm: wallet1})
const query2 = await db.sign("set", {name: "Alice"}, "people", "Alice", {ii: wallet2})
const query3 = await db.sign("set", {name: "Beth"}, "people", "Beth", {ar: wallet3})
await db.bundle([query1, query2, query3], {ar: bundler_wallet})
sign
Sign a query without sending a transaction:
await db.sign("set", {name: "Bob", age: 20}, collection_name, doc_id)
relay
Relay a query:
const param = await db.sign("set", {name: "Bob"}, collection_name, doc_id)
const extra = { age: 20 }
await db.relay("jobID", param, extra, {evm: relayer_wallet})