@fedify/sqlite 1.8.1-pr.318.1225
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +20 -0
- package/README.md +38 -0
- package/adapter.ts +44 -0
- package/deno.json +27 -0
- package/dist/_virtual/rolldown_runtime.js +30 -0
- package/dist/adapter.d.ts +48 -0
- package/dist/kv.d.ts +72 -0
- package/dist/kv.js +183 -0
- package/dist/mod.d.ts +3 -0
- package/dist/mod.js +6 -0
- package/dist/node_modules/.pnpm/@js-temporal_polyfill@0.5.1/node_modules/@js-temporal/polyfill/dist/index.esm.js +5795 -0
- package/dist/node_modules/.pnpm/jsbi@4.3.2/node_modules/jsbi/dist/jsbi-cjs.js +1139 -0
- package/dist/sqlite.bun.d.ts +24 -0
- package/dist/sqlite.bun.js +39 -0
- package/dist/sqlite.node.d.ts +24 -0
- package/dist/sqlite.node.js +41 -0
- package/kv.test.ts +312 -0
- package/kv.ts +278 -0
- package/mod.ts +5 -0
- package/package.json +69 -0
- package/sqlite.bun.ts +45 -0
- package/sqlite.node.ts +48 -0
- package/tsdown.config.ts +13 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Temporal } from "@js-temporal/polyfill";
|
|
2
|
+
import { SqliteDatabaseAdapter, SqliteStatementAdapter } from "./adapter.js";
|
|
3
|
+
import { Database, Statement } from "bun:sqlite";
|
|
4
|
+
|
|
5
|
+
//#region sqlite.bun.d.ts
|
|
6
|
+
declare class SqliteDatabase implements SqliteDatabaseAdapter {
|
|
7
|
+
private readonly db;
|
|
8
|
+
constructor(db: Database);
|
|
9
|
+
prepare(sql: string): SqliteStatementAdapter;
|
|
10
|
+
exec(sql: string): void;
|
|
11
|
+
close(): void;
|
|
12
|
+
}
|
|
13
|
+
declare class SqliteStatement implements SqliteStatementAdapter {
|
|
14
|
+
private readonly stmt;
|
|
15
|
+
constructor(stmt: Statement);
|
|
16
|
+
run(...params: unknown[]): {
|
|
17
|
+
changes: number;
|
|
18
|
+
lastInsertRowid: number;
|
|
19
|
+
};
|
|
20
|
+
get(...params: unknown[]): unknown | undefined;
|
|
21
|
+
all(...params: unknown[]): unknown[];
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
export { Database as PlatformDatabase, Statement as PlatformStatement, SqliteDatabase, SqliteStatement };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
|
|
2
|
+
import { Temporal } from "@js-temporal/polyfill";
|
|
3
|
+
|
|
4
|
+
import { Database } from "bun:sqlite";
|
|
5
|
+
|
|
6
|
+
//#region sqlite.bun.ts
|
|
7
|
+
var SqliteDatabase = class {
|
|
8
|
+
constructor(db) {
|
|
9
|
+
this.db = db;
|
|
10
|
+
}
|
|
11
|
+
prepare(sql) {
|
|
12
|
+
return new SqliteStatement(this.db.query(sql));
|
|
13
|
+
}
|
|
14
|
+
exec(sql) {
|
|
15
|
+
this.db.exec(sql);
|
|
16
|
+
}
|
|
17
|
+
close() {
|
|
18
|
+
this.db.close(false);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
var SqliteStatement = class {
|
|
22
|
+
constructor(stmt) {
|
|
23
|
+
this.stmt = stmt;
|
|
24
|
+
}
|
|
25
|
+
run(...params) {
|
|
26
|
+
return this.stmt.run(...params);
|
|
27
|
+
}
|
|
28
|
+
get(...params) {
|
|
29
|
+
const result = this.stmt.get(...params);
|
|
30
|
+
if (result === null) return void 0;
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
33
|
+
all(...params) {
|
|
34
|
+
return this.stmt.all(...params);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
//#endregion
|
|
39
|
+
export { Database as PlatformDatabase, SqliteDatabase, SqliteStatement };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Temporal } from "@js-temporal/polyfill";
|
|
2
|
+
import { SqliteDatabaseAdapter, SqliteStatementAdapter } from "./adapter.js";
|
|
3
|
+
import { DatabaseSync, StatementSync } from "node:sqlite";
|
|
4
|
+
|
|
5
|
+
//#region sqlite.node.d.ts
|
|
6
|
+
declare class SqliteDatabase implements SqliteDatabaseAdapter {
|
|
7
|
+
private readonly db;
|
|
8
|
+
constructor(db: DatabaseSync);
|
|
9
|
+
prepare(sql: string): SqliteStatementAdapter;
|
|
10
|
+
exec(sql: string): void;
|
|
11
|
+
close(): void;
|
|
12
|
+
}
|
|
13
|
+
declare class SqliteStatement implements SqliteStatementAdapter {
|
|
14
|
+
private readonly stmt;
|
|
15
|
+
constructor(stmt: StatementSync);
|
|
16
|
+
run(...params: unknown[]): {
|
|
17
|
+
changes: number;
|
|
18
|
+
lastInsertRowid: number;
|
|
19
|
+
};
|
|
20
|
+
get(...params: unknown[]): unknown | undefined;
|
|
21
|
+
all(...params: unknown[]): unknown[];
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
export { DatabaseSync as PlatformDatabase, StatementSync as PlatformStatement, SqliteDatabase, SqliteStatement };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
|
|
2
|
+
import { Temporal } from "@js-temporal/polyfill";
|
|
3
|
+
|
|
4
|
+
import { DatabaseSync } from "node:sqlite";
|
|
5
|
+
|
|
6
|
+
//#region sqlite.node.ts
|
|
7
|
+
var SqliteDatabase = class {
|
|
8
|
+
constructor(db) {
|
|
9
|
+
this.db = db;
|
|
10
|
+
}
|
|
11
|
+
prepare(sql) {
|
|
12
|
+
return new SqliteStatement(this.db.prepare(sql));
|
|
13
|
+
}
|
|
14
|
+
exec(sql) {
|
|
15
|
+
this.db.exec(sql);
|
|
16
|
+
}
|
|
17
|
+
close() {
|
|
18
|
+
this.db.close();
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
var SqliteStatement = class {
|
|
22
|
+
constructor(stmt) {
|
|
23
|
+
this.stmt = stmt;
|
|
24
|
+
}
|
|
25
|
+
run(...params) {
|
|
26
|
+
const result = this.stmt.run(...params);
|
|
27
|
+
return {
|
|
28
|
+
changes: Number(result.changes),
|
|
29
|
+
lastInsertRowid: Number(result.lastInsertRowid)
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
get(...params) {
|
|
33
|
+
return this.stmt.get(...params);
|
|
34
|
+
}
|
|
35
|
+
all(...params) {
|
|
36
|
+
return this.stmt.all(...params);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
//#endregion
|
|
41
|
+
export { DatabaseSync as PlatformDatabase, SqliteDatabase, SqliteStatement };
|
package/kv.test.ts
ADDED
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
import { PlatformDatabase } from "#sqlite";
|
|
2
|
+
import * as temporal from "@js-temporal/polyfill";
|
|
3
|
+
import { delay } from "@std/async/delay";
|
|
4
|
+
import assert from "node:assert/strict";
|
|
5
|
+
import { test } from "node:test";
|
|
6
|
+
import { SqliteKvStore } from "./kv.ts";
|
|
7
|
+
|
|
8
|
+
let Temporal: typeof temporal.Temporal;
|
|
9
|
+
if ("Temporal" in globalThis) {
|
|
10
|
+
Temporal = globalThis.Temporal;
|
|
11
|
+
} else {
|
|
12
|
+
Temporal = temporal.Temporal;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function getStore(): {
|
|
16
|
+
db: PlatformDatabase;
|
|
17
|
+
tableName: string;
|
|
18
|
+
store: SqliteKvStore;
|
|
19
|
+
} {
|
|
20
|
+
const db = new PlatformDatabase(":memory:");
|
|
21
|
+
const tableName = `fedify_kv_test_${Math.random().toString(36).slice(5)}`;
|
|
22
|
+
return {
|
|
23
|
+
db,
|
|
24
|
+
tableName,
|
|
25
|
+
store: new SqliteKvStore(db, { tableName }),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
test("SqliteKvStore.initialize()", async () => {
|
|
30
|
+
const { db, tableName, store } = getStore();
|
|
31
|
+
try {
|
|
32
|
+
await store.initialize();
|
|
33
|
+
const result = await db.prepare(`
|
|
34
|
+
SELECT name FROM sqlite_master
|
|
35
|
+
WHERE type='table' AND name=?
|
|
36
|
+
`).get(tableName);
|
|
37
|
+
assert(result !== undefined);
|
|
38
|
+
} finally {
|
|
39
|
+
await store.drop();
|
|
40
|
+
await db.close();
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test("SqliteKvStore.get()", async () => {
|
|
45
|
+
const { db, tableName, store } = getStore();
|
|
46
|
+
try {
|
|
47
|
+
await store.initialize();
|
|
48
|
+
const now = Temporal.Now.instant().epochMilliseconds;
|
|
49
|
+
db.prepare(`
|
|
50
|
+
INSERT INTO ${tableName} (key, value, created)
|
|
51
|
+
VALUES (?, ?, ?)
|
|
52
|
+
`).run(JSON.stringify(["foo", "bar"]), JSON.stringify(["foobar"]), now);
|
|
53
|
+
assert.deepStrictEqual(await store.get(["foo", "bar"]), ["foobar"]);
|
|
54
|
+
|
|
55
|
+
db.prepare(`
|
|
56
|
+
INSERT INTO ${tableName} (key, value, expires, created)
|
|
57
|
+
VALUES (?, ?, ?, ?)
|
|
58
|
+
`).run(
|
|
59
|
+
JSON.stringify(["foo", "bar", "ttl"]),
|
|
60
|
+
JSON.stringify(["foobar"]),
|
|
61
|
+
now + 500,
|
|
62
|
+
Temporal.Now.instant().epochMilliseconds,
|
|
63
|
+
);
|
|
64
|
+
await delay(500);
|
|
65
|
+
assert.strictEqual(await store.get(["foo", "bar", "ttl"]), undefined);
|
|
66
|
+
} finally {
|
|
67
|
+
await store.drop();
|
|
68
|
+
await db.close();
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
test("SqliteKvStore.set()", async () => {
|
|
73
|
+
const { db, tableName, store } = getStore();
|
|
74
|
+
try {
|
|
75
|
+
await store.set(["foo", "baz"], "baz");
|
|
76
|
+
|
|
77
|
+
const result = db.prepare(`
|
|
78
|
+
SELECT * FROM ${tableName}
|
|
79
|
+
WHERE key = ?
|
|
80
|
+
`).all(JSON.stringify(["foo", "baz"])) as {
|
|
81
|
+
key: string;
|
|
82
|
+
value: string;
|
|
83
|
+
created: number;
|
|
84
|
+
expires: number | null;
|
|
85
|
+
}[];
|
|
86
|
+
|
|
87
|
+
assert.strictEqual(result.length, 1);
|
|
88
|
+
assert.deepStrictEqual(JSON.parse(result[0].key), ["foo", "baz"]);
|
|
89
|
+
assert.strictEqual(JSON.parse(result[0].value), "baz");
|
|
90
|
+
assert.strictEqual(result[0].expires, null);
|
|
91
|
+
|
|
92
|
+
await store.set(["foo", "qux"], "qux", {
|
|
93
|
+
ttl: Temporal.Duration.from({ days: 1 }),
|
|
94
|
+
});
|
|
95
|
+
const result2 = db.prepare(`
|
|
96
|
+
SELECT * FROM ${tableName}
|
|
97
|
+
WHERE key = ?
|
|
98
|
+
`).all(JSON.stringify(["foo", "qux"])) as {
|
|
99
|
+
key: string;
|
|
100
|
+
value: string;
|
|
101
|
+
created: number;
|
|
102
|
+
expires: number | null;
|
|
103
|
+
}[];
|
|
104
|
+
assert.strictEqual(result2.length, 1);
|
|
105
|
+
assert.deepStrictEqual(JSON.parse(result2[0].key), ["foo", "qux"]);
|
|
106
|
+
assert.strictEqual(JSON.parse(result2[0].value), "qux");
|
|
107
|
+
assert(
|
|
108
|
+
result2[0].expires && result2[0].expires >= result2[0].created + 86400000,
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
await store.set(["foo", "quux"], true);
|
|
112
|
+
const result3 = db.prepare(`
|
|
113
|
+
SELECT * FROM ${tableName}
|
|
114
|
+
WHERE key = ?
|
|
115
|
+
`).all(JSON.stringify(["foo", "quux"])) as {
|
|
116
|
+
key: string;
|
|
117
|
+
value: string;
|
|
118
|
+
created: number;
|
|
119
|
+
expires: number | null;
|
|
120
|
+
}[];
|
|
121
|
+
assert.strictEqual(result3.length, 1);
|
|
122
|
+
assert.deepStrictEqual(JSON.parse(result3[0].key), ["foo", "quux"]);
|
|
123
|
+
assert.strictEqual(JSON.parse(result3[0].value), true);
|
|
124
|
+
assert.strictEqual(result3[0].expires, null);
|
|
125
|
+
} finally {
|
|
126
|
+
await store.drop();
|
|
127
|
+
await db.close();
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
test("SqliteKvStore.set() - upsert functionality", async () => {
|
|
132
|
+
const { db, tableName, store } = getStore();
|
|
133
|
+
try {
|
|
134
|
+
await store.set(["upsert"], "initial");
|
|
135
|
+
assert.strictEqual(await store.get(["upsert"]), "initial");
|
|
136
|
+
await store.set(["upsert"], "updated");
|
|
137
|
+
assert.strictEqual(await store.get(["upsert"]), "updated");
|
|
138
|
+
const result = db.prepare(`
|
|
139
|
+
SELECT COUNT(*) as count FROM ${tableName} WHERE key = ?
|
|
140
|
+
`).get(JSON.stringify(["upsert"]));
|
|
141
|
+
assert.strictEqual((result as { count: number }).count, 1);
|
|
142
|
+
} finally {
|
|
143
|
+
await store.drop();
|
|
144
|
+
await db.close();
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
test("SqliteKvStore.delete()", async () => {
|
|
149
|
+
const { db, tableName, store } = getStore();
|
|
150
|
+
try {
|
|
151
|
+
await store.delete(["foo", "qux"]);
|
|
152
|
+
const result = db.prepare(`
|
|
153
|
+
SELECT * FROM ${tableName}
|
|
154
|
+
WHERE key = ?
|
|
155
|
+
`).all(JSON.stringify(["foo", "qux"]));
|
|
156
|
+
assert.strictEqual(result.length, 0);
|
|
157
|
+
|
|
158
|
+
db.prepare(`
|
|
159
|
+
INSERT INTO ${tableName} (key, value, created)
|
|
160
|
+
VALUES (?, ?, ?)
|
|
161
|
+
`).run(
|
|
162
|
+
JSON.stringify(["foo", "qux"]),
|
|
163
|
+
JSON.stringify(["qux"]),
|
|
164
|
+
Temporal.Now.instant().epochMilliseconds,
|
|
165
|
+
);
|
|
166
|
+
await store.delete(["foo", "qux"]);
|
|
167
|
+
const result2 = db.prepare(`
|
|
168
|
+
SELECT * FROM ${tableName}
|
|
169
|
+
WHERE key = ?
|
|
170
|
+
`).all(JSON.stringify(["foo", "qux"]));
|
|
171
|
+
assert.strictEqual(result2.length, 0);
|
|
172
|
+
} finally {
|
|
173
|
+
await store.drop();
|
|
174
|
+
await db.close();
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
test("SqliteKvStore.drop()", async () => {
|
|
179
|
+
const { db, tableName, store } = getStore();
|
|
180
|
+
try {
|
|
181
|
+
await store.drop();
|
|
182
|
+
const result = await db.prepare(`
|
|
183
|
+
SELECT name FROM sqlite_master
|
|
184
|
+
WHERE type='table' AND name=?
|
|
185
|
+
`).get(tableName);
|
|
186
|
+
// Bun returns null, Node returns undefined
|
|
187
|
+
assert(result === undefined || result === null);
|
|
188
|
+
} finally {
|
|
189
|
+
await db.close();
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
test("SqliteKvStore.cas()", async () => {
|
|
194
|
+
const { db, store } = getStore();
|
|
195
|
+
try {
|
|
196
|
+
await store.set(["foo", "bar"], "foobar");
|
|
197
|
+
assert.strictEqual(await store.cas(["foo", "bar"], "bar", "baz"), false);
|
|
198
|
+
assert.strictEqual(await store.get(["foo", "bar"]), "foobar");
|
|
199
|
+
assert.strictEqual(await store.cas(["foo", "bar"], "foobar", "baz"), true);
|
|
200
|
+
assert.strictEqual(await store.get(["foo", "bar"]), "baz");
|
|
201
|
+
await store.delete(["foo", "bar"]);
|
|
202
|
+
assert.strictEqual(await store.cas(["foo", "bar"], "foobar", "baz"), false);
|
|
203
|
+
assert.strictEqual(await store.get(["foo", "bar"]), undefined);
|
|
204
|
+
assert.strictEqual(await store.cas(["foo", "bar"], undefined, "baz"), true);
|
|
205
|
+
assert.strictEqual(await store.get(["foo", "bar"]), "baz");
|
|
206
|
+
assert.strictEqual(await store.cas(["foo", "bar"], "baz", undefined), true);
|
|
207
|
+
assert.strictEqual(await store.get(["foo", "bar"]), undefined);
|
|
208
|
+
} finally {
|
|
209
|
+
await store.drop();
|
|
210
|
+
await db.close();
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
test("SqliteKvStore - complex values", async () => {
|
|
215
|
+
const { db, store } = getStore();
|
|
216
|
+
try {
|
|
217
|
+
await store.set(["complex"], {
|
|
218
|
+
nested: {
|
|
219
|
+
value: "test",
|
|
220
|
+
},
|
|
221
|
+
});
|
|
222
|
+
assert.deepStrictEqual(await store.get(["complex"]), {
|
|
223
|
+
nested: {
|
|
224
|
+
value: "test",
|
|
225
|
+
},
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
await store.set(["undefined"], undefined);
|
|
229
|
+
assert.strictEqual(await store.get(["undefined"]), undefined);
|
|
230
|
+
assert.strictEqual(await store.cas(["undefined"], undefined, "baz"), true);
|
|
231
|
+
assert.strictEqual(await store.get(["undefined"]), "baz");
|
|
232
|
+
|
|
233
|
+
await store.set(["null"], null);
|
|
234
|
+
assert.strictEqual(await store.get(["null"]), null);
|
|
235
|
+
assert.strictEqual(await store.cas(["null"], null, "baz"), true);
|
|
236
|
+
assert.strictEqual(await store.get(["null"]), "baz");
|
|
237
|
+
|
|
238
|
+
await store.set(["empty string"], "");
|
|
239
|
+
assert.strictEqual(await store.get(["empty string"]), "");
|
|
240
|
+
assert.strictEqual(await store.cas(["empty string"], "", "baz"), true);
|
|
241
|
+
assert.strictEqual(await store.get(["empty string"]), "baz");
|
|
242
|
+
|
|
243
|
+
await store.set(["array"], [1, 2, 3]);
|
|
244
|
+
assert.deepStrictEqual(await store.get(["array"]), [1, 2, 3]);
|
|
245
|
+
assert.strictEqual(
|
|
246
|
+
await store.cas(["array"], [1, 2, 3], [1, 2, 3, 4]),
|
|
247
|
+
true,
|
|
248
|
+
);
|
|
249
|
+
assert.deepStrictEqual(await store.get(["array"]), [1, 2, 3, 4]);
|
|
250
|
+
|
|
251
|
+
await store.set(["object"], { a: 1, b: 2 });
|
|
252
|
+
assert.deepStrictEqual(await store.get(["object"]), { b: 2, a: 1 });
|
|
253
|
+
assert.strictEqual(
|
|
254
|
+
await store.cas(["object"], { a: 1, b: 2 }, { a: 1, b: 2, c: 3 }),
|
|
255
|
+
true,
|
|
256
|
+
);
|
|
257
|
+
assert.deepStrictEqual(await store.get(["object"]), { a: 1, b: 2, c: 3 });
|
|
258
|
+
|
|
259
|
+
await store.set(["falsy", "false"], false);
|
|
260
|
+
assert.strictEqual(await store.get(["falsy", "false"]), false);
|
|
261
|
+
assert.strictEqual(await store.cas(["falsy", "false"], false, true), true);
|
|
262
|
+
assert.strictEqual(await store.get(["falsy", "false"]), true);
|
|
263
|
+
|
|
264
|
+
await store.set(["falsy", "0"], 0);
|
|
265
|
+
assert.strictEqual(await store.get(["falsy", "0"]), 0);
|
|
266
|
+
assert.strictEqual(await store.cas(["falsy", "0"], 0, 1), true);
|
|
267
|
+
assert.strictEqual(await store.get(["falsy", "0"]), 1);
|
|
268
|
+
} finally {
|
|
269
|
+
await store.drop();
|
|
270
|
+
await db.close();
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
test("SqliteKvStore.set() - preserves created timestamp on update", async () => {
|
|
275
|
+
const { db, tableName, store } = getStore();
|
|
276
|
+
try {
|
|
277
|
+
await store.set(["timestamp-test"], "initial");
|
|
278
|
+
const initialResult = db.prepare(`
|
|
279
|
+
SELECT created, expires FROM ${tableName}
|
|
280
|
+
WHERE key = ?
|
|
281
|
+
`).get(JSON.stringify(["timestamp-test"]));
|
|
282
|
+
|
|
283
|
+
const initialCreated = (initialResult as { created: number }).created;
|
|
284
|
+
assert(
|
|
285
|
+
initialCreated !== undefined,
|
|
286
|
+
"Initial created timestamp should be set",
|
|
287
|
+
);
|
|
288
|
+
assert.strictEqual(
|
|
289
|
+
(initialResult as { expires: number | null }).expires,
|
|
290
|
+
null,
|
|
291
|
+
);
|
|
292
|
+
|
|
293
|
+
await delay(100);
|
|
294
|
+
|
|
295
|
+
const ttl = Temporal.Duration.from({ seconds: 30 });
|
|
296
|
+
await store.set(["timestamp-test"], "updated", { ttl });
|
|
297
|
+
|
|
298
|
+
const updatedResult = db.prepare(`
|
|
299
|
+
SELECT created, expires FROM ${tableName}
|
|
300
|
+
WHERE key = ?
|
|
301
|
+
`).get(JSON.stringify(["timestamp-test"]));
|
|
302
|
+
|
|
303
|
+
assert.strictEqual(
|
|
304
|
+
(updatedResult as { created: number }).created,
|
|
305
|
+
initialCreated,
|
|
306
|
+
"Created timestamp should remain unchanged after update",
|
|
307
|
+
);
|
|
308
|
+
} finally {
|
|
309
|
+
await store.drop();
|
|
310
|
+
await db.close();
|
|
311
|
+
}
|
|
312
|
+
});
|