From e888c3f534c6ce9574f1d57e5cc61573a046039e Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Thu, 30 Mar 2023 20:57:21 +0200 Subject: feat(ext/kv): return versionstamp from set/commit (#18512) This commit updates the `Deno.Kv` API to return the new commited versionstamp for the mutated data from `db.set` and `ao.commit`. This is returned in the form of a `Deno.KvCommitResult` object that has a `versionstamp` property. --- ext/kv/01_db.ts | 12 +++++++----- ext/kv/interface.rs | 11 ++++++++++- ext/kv/lib.rs | 4 ++-- ext/kv/sqlite.rs | 14 +++++++++++--- 4 files changed, 30 insertions(+), 11 deletions(-) (limited to 'ext') diff --git a/ext/kv/01_db.ts b/ext/kv/01_db.ts index 70e4c7fca..e0c5335e6 100644 --- a/ext/kv/01_db.ts +++ b/ext/kv/01_db.ts @@ -111,14 +111,15 @@ class Kv { [key, "set", value], ]; - const result = await core.opAsync( + const versionstamp = await core.opAsync( "op_kv_atomic_write", this.#rid, checks, mutations, [], ); - if (!result) throw new TypeError("Failed to set value"); + if (versionstamp === null) throw new TypeError("Failed to set value"); + return { versionstamp }; } async delete(key: Deno.KvKey) { @@ -255,15 +256,16 @@ class AtomicOperation { return this; } - async commit(): Promise { - const result = await core.opAsync( + async commit(): Promise { + const versionstamp = await core.opAsync( "op_kv_atomic_write", this.#rid, this.#checks, this.#mutations, [], // TODO(@losfair): enqueue ); - return result; + if (versionstamp === null) return null; + return { versionstamp }; } then() { diff --git a/ext/kv/interface.rs b/ext/kv/interface.rs index 6e520b9c5..31b7638b4 100644 --- a/ext/kv/interface.rs +++ b/ext/kv/interface.rs @@ -31,7 +31,10 @@ pub trait Database { options: SnapshotReadOptions, ) -> Result, AnyError>; - async fn atomic_write(&self, write: AtomicWrite) -> Result; + async fn atomic_write( + &self, + write: AtomicWrite, + ) -> Result, AnyError>; } /// Options for a snapshot read. @@ -304,3 +307,9 @@ impl MutationKind { } } } + +/// The result of a successful commit of an atomic write operation. +pub struct CommitResult { + /// The new versionstamp of the data that was committed. + pub versionstamp: Versionstamp, +} diff --git a/ext/kv/lib.rs b/ext/kv/lib.rs index 8782fbec6..f17ed55e3 100644 --- a/ext/kv/lib.rs +++ b/ext/kv/lib.rs @@ -519,7 +519,7 @@ async fn op_kv_atomic_write( checks: Vec, mutations: Vec, enqueues: Vec, -) -> Result +) -> Result, AnyError> where DBH: DatabaseHandler + 'static, { @@ -585,7 +585,7 @@ where let result = db.atomic_write(atomic_write).await?; - Ok(result) + Ok(result.map(|res| hex::encode(res.versionstamp))) } // (prefix, start, end) diff --git a/ext/kv/sqlite.rs b/ext/kv/sqlite.rs index 17634127f..63be1281b 100644 --- a/ext/kv/sqlite.rs +++ b/ext/kv/sqlite.rs @@ -17,6 +17,7 @@ use rusqlite::OptionalExtension; use rusqlite::Transaction; use crate::AtomicWrite; +use crate::CommitResult; use crate::Database; use crate::DatabaseHandler; use crate::KvEntry; @@ -216,7 +217,10 @@ impl Database for SqliteDb { Ok(responses) } - async fn atomic_write(&self, write: AtomicWrite) -> Result { + async fn atomic_write( + &self, + write: AtomicWrite, + ) -> Result, AnyError> { let mut db = self.0.borrow_mut(); let tx = db.transaction()?; @@ -228,7 +232,7 @@ impl Database for SqliteDb { .optional()? .map(version_to_versionstamp); if real_versionstamp != check.versionstamp { - return Ok(false); + return Ok(None); } } @@ -273,7 +277,11 @@ impl Database for SqliteDb { tx.commit()?; - Ok(true) + let new_vesionstamp = version_to_versionstamp(version); + + Ok(Some(CommitResult { + versionstamp: new_vesionstamp, + })) } } -- cgit v1.2.3