somethingelse~
somethingelse~13mo ago

Deno KV equivalent of 'returning'

hello, in sqlite there is a way to get the new value set on an upsert like so insert into counters (name, counter) values (?, 0) on conflict (name) do update set counter = counter + 1 returning counter; is there a way an equivalent on KV? At the moment what I'm looking at is looping with a get and then try set or retry.
1 Reply
Deno AI Helper
Deno AI Helper13mo ago
In Deno KV, there isn't a direct equivalent to the 'returning' clause in SQL. The documentation does not provide a way to return the new value directly after an update or insert operation in a single atomic transaction. However, you can achieve similar functionality by performing a get operation after the set operation. Here's an example:
const key = ["counter", "name"];
let counter;

// Start a loop to handle potential conflicts
while (true) {
// Get the current counter value
const record = await kv.get(key);
counter = record.value;

// Try to update the counter
const ok = await kv.atomic()
.check(record) // Ensure the counter hasn't changed
.set(key, counter + 1) // Increment the counter
.commit();

// If the update was successful, break the loop
if (ok) {
break;
}
}

// Get the new counter value
const newRecord = await kv.get(key);
console.log("New counter value is: ", newRecord.value);
const key = ["counter", "name"];
let counter;

// Start a loop to handle potential conflicts
while (true) {
// Get the current counter value
const record = await kv.get(key);
counter = record.value;

// Try to update the counter
const ok = await kv.atomic()
.check(record) // Ensure the counter hasn't changed
.set(key, counter + 1) // Increment the counter
.commit();

// If the update was successful, break the loop
if (ok) {
break;
}
}

// Get the new counter value
const newRecord = await kv.get(key);
console.log("New counter value is: ", newRecord.value);
In this example, we're using an optimistic locking strategy. We first get the current counter value, then try to increment it. If another process has updated the counter in the meantime, the check operation will fail, and we'll retry the whole process. Once the update is successful, we get the new counter value. Please note that this approach involves two separate operations (set and get), and the counter value could potentially change between these operations if it's being updated concurrently by another process. If you need to ensure that the counter value doesn't change between the set and get operations, you would need to implement additional synchronization logic.