Unverified Commit 394c8915 authored by An Nyeong's avatar An Nyeong
Browse files

Fix `set` to prevent chaing `created` field

Use INSERT ... ON CONFLICT ... DO UPDATE instead of INSERT OR REPLACE to
ensure that only the value and expires_at fields are updated when modifying
an existing key. This maintains the original created timestamp while still
allowing TTL updates.

Added test case to verify that created timestamp remains unchanged during
updates while expires_at is properly modified.
parent 80110a1d
Loading
Loading
Loading
Loading
+37 −1
Original line number Diff line number Diff line
@@ -100,7 +100,6 @@ test("SqliteKvStore.set()", async () => {
      SELECT * FROM ${tableName}
      WHERE key = ?
    `).all(JSON.stringify(["foo", "quux"]));
    console.log(result3);
    assert.strictEqual(result3.length, 1);
    assert.deepStrictEqual(JSON.parse(result3[0].key), ["foo", "quux"]);
    assert.strictEqual(JSON.parse(result3[0].value), true);
@@ -246,3 +245,40 @@ test("SqliteKvStore - complex values", async () => {
    await db.close();
  }
});

test("SqliteKvStore.set() - preserves created timestamp on update", async () => {
  const { db, tableName, store } = getStore();
  try {
    await store.set(["timestamp-test"], "initial");
    const initialResult = db.prepare(`
      SELECT created, expires_at FROM ${tableName}
      WHERE key = ?
    `).get(JSON.stringify(["timestamp-test"]));

    const initialCreated = (initialResult as { created: number }).created;
    assert(initialCreated > 0, "Initial created timestamp should be set");
    assert.strictEqual(
      (initialResult as { expires_at: number | null }).expires_at,
      null,
    );

    await delay(100);

    const ttl = Temporal.Duration.from({ seconds: 30 });
    await store.set(["timestamp-test"], "updated", { ttl });

    const updatedResult = db.prepare(`
      SELECT created, expires_at FROM ${tableName}
      WHERE key = ?
    `).get(JSON.stringify(["timestamp-test"]));

    assert.strictEqual(
      (updatedResult as { created: number }).created,
      initialCreated,
      "Created timestamp should remain unchanged after update",
    );
  } finally {
    await store.drop();
    await db.close();
  }
});
+6 −3
Original line number Diff line number Diff line
@@ -102,10 +102,13 @@ export class SqliteKvStore implements KvStore {
      : null;

    this.#db
      .prepare(`
        INSERT OR REPLACE INTO "${this.#tableName}" (key, value, created, expires_at)
      .prepare(
        `INSERT INTO "${this.#tableName}" (key, value, created, expires_at)
        VALUES (?, ?, ?, ?)
      `)
        ON CONFLICT(key) DO UPDATE SET
          value = excluded.value,
          expires_at = excluded.expires_at`,
      )
      .run(encodedKey, encodedValue, now, expiresAt);

    await this.#expire();