@worker-tools/deno-kv-storage
Version:
An implementation of the StorageArea (1,2,3) interface for Deno with an extensible system for supporting various database backends.
127 lines • 4.15 kB
JavaScript
// deno-lint-ignore-file require-await
import "../_dnt.polyfills.js";
import { DB } from "../deps/deno.land/x/sqlite@v2.5.0/mod.js";
const CREATE = 'CREATE TABLE IF NOT EXISTS [kv-storage] (area TEXT, key TEXT, value TEXT, PRIMARY KEY (area, key))';
const GET = 'SELECT value FROM [kv-storage] WHERE key=:key AND area=:area';
const UPSERT = 'INSERT INTO [kv-storage] (area, key, value) VALUES (:area, :key, :value) ON CONFLICT(area, key) DO UPDATE SET value=:value';
const DELETE = 'DELETE FROM [kv-storage] WHERE key=:key AND area=:area';
const CLEAR = 'DELETE FROM [kv-storage] WHERE area=:area';
const KEYS = 'SELECT key FROM [kv-storage] WHERE area=:area';
const VALUES = 'SELECT value FROM [kv-storage] WHERE area=:area';
const ENTRIES = 'SELECT key, value FROM [kv-storage] WHERE area=:area';
export class SQLiteAdapter {
constructor({ area, url }) {
Object.defineProperty(this, "filename", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "area", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "db", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "memory", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "refs", {
enumerable: true,
configurable: true,
writable: true,
value: 0
});
this.area = area;
const filename = url.substring('sqlite://'.length);
const memory = this.memory = ['', 'memory'].includes(filename !== null && filename !== void 0 ? filename : '');
const db = this.db = new DB(this.filename = memory ? ':memory:' : filename);
[...db.query(CREATE)];
this.keepOpen();
}
keepOpen() {
if (!this.memory)
queueMicrotask(() => {
var _a;
if (this.refs === 0) {
(_a = this.db) === null || _a === void 0 ? void 0 : _a.close();
delete this.db;
}
});
}
query(query, params) {
const db = this.db || (this.db = new DB(this.filename));
const rows = db.query(query, { ...params, area: this.area });
return rows;
}
async get(key) {
var _a;
const res = (_a = this.query(GET, { key }).next().value) === null || _a === void 0 ? void 0 : _a[0];
this.keepOpen();
return res;
}
async set(key, value) {
[...this.query(UPSERT, { key, value })];
this.keepOpen();
}
async delete(key) {
[...this.query(DELETE, { key })];
this.keepOpen();
}
async clear() {
[...this.query(CLEAR)];
this.keepOpen();
}
async *keys() {
try {
this.refs++;
for (const [key] of this.query(KEYS)) {
yield key;
}
}
finally {
this.refs--;
this.keepOpen();
}
}
async *values() {
try {
this.refs++;
for (const [value] of this.query(VALUES)) {
yield value;
}
}
finally {
this.refs--;
this.keepOpen();
}
}
async *entries() {
try {
this.refs++;
for (const [key, value] of this.query(ENTRIES)) {
yield [key, value];
}
}
finally {
this.refs--;
this.keepOpen();
}
}
backingStore() {
var _a;
return (_a = this.db) !== null && _a !== void 0 ? _a : new DB(this.filename);
}
}
// @ts-ignore: ...
(globalThis.deno_storage_area__adapters || (globalThis.deno_storage_area__adapters = new Map())).set('sqlite:', SQLiteAdapter);
//# sourceMappingURL=sqlite.js.map