UNPKG

@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.

123 lines 4.05 kB
// deno-lint-ignore-file no-explicit-any import "../_dnt.polyfills.js"; import { Client } from "../deps/deno.land/x/postgres@v0.15.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=$2 AND area=$1'; const UPSERT = 'INSERT INTO kv_storage (area, key, value) VALUES ($1, $2, $3) ON CONFLICT(area, key) DO UPDATE SET value=$3'; const DELETE = 'DELETE FROM kv_storage WHERE key=$2 AND area=$1'; const CLEAR = 'DELETE FROM kv_storage WHERE area=$1'; const KEYS = 'SELECT key FROM kv_storage WHERE area=$1'; const VALUES = 'SELECT value FROM kv_storage WHERE area=$1'; const ENTRIES = 'SELECT key, value FROM kv_storage WHERE area=$1'; export class PostgresAdapter { constructor({ area, url }) { Object.defineProperty(this, "area", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "url", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "init", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "client", { enumerable: true, configurable: true, writable: true, value: void 0 }); this.area = area; this.url = url; this.init = (async () => { const client = this.client = new Client(url); await client.connect(); // https://stackoverflow.com/questions/26150758/suppressing-notice-relation-exists-when-using-create-if-not-exists await client.queryArray(`SET client_min_messages = warning`); await client.queryArray(CREATE); this.keepOpen(); })(); } keepOpen() { queueMicrotask(() => { var _a; if ((_a = this.client) === null || _a === void 0 ? void 0 : _a.connected) this.client.end(); delete this.client; }); } async query(query, { key, value } = {}) { await this.init; const client = this.client || (this.client = new Client(this.url)); if (!client.connected) await client.connect(); const ret = (await client.queryArray({ text: query, args: [this.area, ...key ? [key] : [], ...value ? [value] : []], })).rows; this.keepOpen(); return ret; } async get(key) { var _a; const res = (_a = (await this.query(GET, { key }))[0]) === null || _a === void 0 ? void 0 : _a[0]; this.keepOpen(); return res; } async set(key, value) { await this.query(UPSERT, { key, value }); this.keepOpen(); } async delete(key) { await this.query(DELETE, { key }); this.keepOpen(); } async clear() { await this.query(CLEAR); this.keepOpen(); } async *keys() { try { for (const [key] of await this.query(KEYS)) { yield key; } } finally { this.keepOpen(); } } async *values() { try { for (const [value] of await this.query(VALUES)) { yield value; } } finally { this.keepOpen(); } } async *entries() { try { for (const [key, value] of await this.query(ENTRIES)) { yield [key, value]; } } finally { this.keepOpen(); } } backingStore() { return new Client(this.url); } } // @ts-ignore: ... (globalThis.deno_storage_area__adapters || (globalThis.deno_storage_area__adapters = new Map())).set('postgres:', PostgresAdapter); //# sourceMappingURL=postgres.js.map