KV API
Useful helper functions can be found in the kinode_process_lib
.
More discussion of databases in Kinode can be found here.
Creating/Opening a database
#![allow(unused)] fn main() { use kinode_process_lib::kv; let kv = kv::open(our.package_id(), "birthdays")?; // You can now pass this KV struct as a reference to other functions }
Set
#![allow(unused)] fn main() { let key = b"hello"; let value= b"world"; let returnvalue = kv.set(&key, &value, None)?; // The third argument None is for tx_id. // You can group sets and deletes and commit them later. }
Get
#![allow(unused)] fn main() { let key = b"hello"; let returnvalue = kv.get(&key)?; }
Delete
#![allow(unused)] fn main() { let key = b"hello"; kv.delete(&key, None)?; }
Transactions
#![allow(unused)] fn main() { let tx_id = kv.begin_tx()?; let key = b"hello"; let key2 = b"deleteme"; let value= b"value"; kv.set(&key, &value, Some(tx_id))?; kv.delete(&key, Some(tx_id))?; kv.commit_tx(tx_id)?; }
API
#![allow(unused)] fn main() { /// Actions are sent to a specific key value database. `db` is the name, /// `package_id` is the [`PackageId`] that created the database. Capabilities /// are checked: you can access another process's database if it has given /// you the read and/or write capability to do so. #[derive(Clone, Debug, Serialize, Deserialize)] pub struct KvRequest { pub package_id: PackageId, pub db: String, pub action: KvAction, } /// IPC Action format representing operations that can be performed on the /// key-value runtime module. These actions are included in a [`KvRequest`] /// sent to the `kv:distro:sys` runtime module. #[derive(Clone, Debug, Serialize, Deserialize)] pub enum KvAction { /// Opens an existing key-value database or creates a new one if it doesn't exist. /// Requires `package_id` in [`KvRequest`] to match the package ID of the sender. /// The sender will own the database and can remove it with [`KvAction::RemoveDb`]. /// /// A successful open will respond with [`KvResponse::Ok`]. Any error will be /// contained in the [`KvResponse::Err`] variant. Open, /// Permanently deletes the entire key-value database. /// Requires `package_id` in [`KvRequest`] to match the package ID of the sender. /// Only the owner can remove the database. /// /// A successful remove will respond with [`KvResponse::Ok`]. Any error will be /// contained in the [`KvResponse::Err`] variant. RemoveDb, /// Sets a value for the specified key in the database. /// /// # Parameters /// * `key` - The key as a byte vector /// * `tx_id` - Optional transaction ID if this operation is part of a transaction /// * blob: [`Vec<u8>`] - Byte vector to store for the key /// /// Using this action requires the sender to have the write capability /// for the database. /// /// A successful set will respond with [`KvResponse::Ok`]. Any error will be /// contained in the [`KvResponse::Err`] variant. Set { key: Vec<u8>, tx_id: Option<u64> }, /// Deletes a key-value pair from the database. /// /// # Parameters /// * `key` - The key to delete as a byte vector /// * `tx_id` - Optional transaction ID if this operation is part of a transaction /// /// Using this action requires the sender to have the write capability /// for the database. /// /// A successful delete will respond with [`KvResponse::Ok`]. Any error will be /// contained in the [`KvResponse::Err`] variant. Delete { key: Vec<u8>, tx_id: Option<u64> }, /// Retrieves the value associated with the specified key. /// /// # Parameters /// * The key to look up as a byte vector /// /// Using this action requires the sender to have the read capability /// for the database. /// /// A successful get will respond with [`KvResponse::Get`], where the response blob /// contains the value associated with the key if any. Any error will be /// contained in the [`KvResponse::Err`] variant. Get(Vec<u8>), /// Begins a new transaction for atomic operations. /// /// Sending this will prompt a [`KvResponse::BeginTx`] response with the /// transaction ID. Any error will be contained in the [`KvResponse::Err`] variant. BeginTx, /// Commits all operations in the specified transaction. /// /// # Parameters /// * `tx_id` - The ID of the transaction to commit /// /// A successful commit will respond with [`KvResponse::Ok`]. Any error will be /// contained in the [`KvResponse::Err`] variant. Commit { tx_id: u64 }, } #[derive(Clone, Debug, Serialize, Deserialize)] pub enum KvResponse { /// Indicates successful completion of an operation. /// Sent in response to actions Open, RemoveDb, Set, Delete, and Commit. Ok, /// Returns the transaction ID for a newly created transaction. /// /// # Fields /// * `tx_id` - The ID of the newly created transaction BeginTx { tx_id: u64 }, /// Returns the value for the key that was retrieved from the database. /// /// # Parameters /// * The retrieved key as a byte vector /// * blob: [`Vec<u8>`] - Byte vector associated with the key Get(Vec<u8>), /// Indicates an error occurred during the operation. Err(KvError), } #[derive(Clone, Debug, Serialize, Deserialize, Error)] pub enum KvError { #[error("db [{0}, {1}] does not exist")] NoDb(PackageId, String), #[error("key not found")] KeyNotFound, #[error("no transaction {0} found")] NoTx(u64), #[error("no write capability for requested DB")] NoWriteCap, #[error("no read capability for requested DB")] NoReadCap, #[error("request to open or remove DB with mismatching package ID")] MismatchingPackageId, #[error("failed to generate capability for new DB")] AddCapFailed, #[error("kv got a malformed request that either failed to deserialize or was missing a required blob")] MalformedRequest, #[error("RocksDB internal error: {0}")] RocksDBError(String), #[error("IO error: {0}")] IOError(String), } /// The JSON parameters contained in all capabilities issued by `kv:distro:sys`. /// /// # Fields /// * `kind` - The kind of capability, either [`KvCapabilityKind::Read`] or [`KvCapabilityKind::Write`] /// * `db_key` - The database key, a tuple of the [`PackageId`] that created the database and the database name #[derive(Clone, Debug, Serialize, Deserialize)] pub struct KvCapabilityParams { pub kind: KvCapabilityKind, pub db_key: (PackageId, String), } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "lowercase")] pub enum KvCapabilityKind { Read, Write, } }