lakutata
Version:
An IoC-based universal application framework.
143 lines (136 loc) • 4.59 kB
JavaScript
/* Build Date: Mon Jan 05 2026 23:52:23 GMT+0800 (China Standard Time) */
import t from "events";
import { promisify as e } from "util";
import "buffer";
import s from "sqlite3";
var i = t => {
const e = String(t).replace(/[^a-zA-Z0-9_]/g, "");
if (e.length === 0) {
throw new Error("Invalid table name: must contain alphanumeric characters");
}
return /^[a-zA-Z]/.test(e) ? e : `_${e}`;
};
var n = class extends t {
ttlSupport;
opts;
namespace;
close;
query;
constructor(t) {
super();
this.ttlSupport = false;
let n = {
dialect: "sqlite",
uri: "sqlite://:memory:"
};
if (typeof t === "string") {
n.uri = t;
} else {
n = {
...n,
...t
};
}
n.db = n.uri.replace(/^sqlite:\/\//, "");
n.connect = async () => new Promise((t, e) => {
const i = new s.Database(n.db, s => {
if (s) {
e(s);
} else {
if (n.busyTimeout) {
i.configure("busyTimeout", n.busyTimeout);
}
t(i);
}
});
}).then(t => ({
query: e(t.all).bind(t),
close: e(t.close).bind(t)
}));
this.opts = {
table: "keyv",
keySize: 255,
...n
};
this.opts.table = i(this.opts.table);
const a = Number(this.opts.keySize);
if (!Number.isFinite(a) || a <= 0 || a > 65535) {
throw new Error("Invalid keySize: must be a positive number between 1 and 65535");
}
const r = `CREATE TABLE IF NOT EXISTS ${this.opts.table}(key VARCHAR(${a}) PRIMARY KEY, value TEXT )`;
const o = this.opts.connect().then(async t => t.query(r).then(() => t)).catch(t => this.emit("error", t));
this.query = async (t, ...e) => o.then(async s => s.query(t, ...e));
this.close = async () => o.then(t => t.close());
}
async get(t) {
const e = `SELECT * FROM ${this.opts.table} WHERE key = ?`;
const s = await this.query(e, t);
const i = s[0];
if (i === void 0) {
return void 0;
}
return i.value;
}
async getMany(t) {
const e = `SELECT * FROM ${this.opts.table} WHERE key IN (SELECT value FROM json_each(?))`;
const s = await this.query(e, JSON.stringify(t));
return t.map(t => {
const e = s.find(e => e.key === t);
return e ? e.value : void 0;
});
}
async set(t, e) {
const s = `INSERT INTO ${this.opts.table} (key, value)\n\t\t\tVALUES(?, ?) \n\t\t\tON CONFLICT(key) \n\t\t\tDO UPDATE SET value=excluded.value;`;
return this.query(s, t, e);
}
async delete(t) {
const e = `SELECT * FROM ${this.opts.table} WHERE key = ?`;
const s = `DELETE FROM ${this.opts.table} WHERE key = ?`;
const i = await this.query(e, t);
const n = i[0];
if (n === void 0) {
return false;
}
await this.query(s, t);
return true;
}
async deleteMany(t) {
const e = `DELETE FROM ${this.opts.table} WHERE key IN (SELECT value FROM json_each(?))`;
const s = await this.getMany(t);
if (s.every(t => t === void 0)) {
return false;
}
await this.query(e, JSON.stringify(t));
return true;
}
async clear() {
const t = `DELETE FROM ${this.opts.table} WHERE key LIKE ?`;
await this.query(t, this.namespace ? `${this.namespace}:%` : "%");
}
async* iterator(t) {
const e = Number.parseInt(this.opts.iterationLimit, 10) || 10;
async function* s(i, n, a) {
const r = `SELECT * FROM ${n.table} WHERE key LIKE ? LIMIT ? OFFSET ?`;
const o = await a(r, [ `${t ? t + ":" : ""}%`, e, i ]);
const c = [ ...o ];
if (c.length === 0) {
return;
}
for (const t of c) {
i += 1;
yield [ t.key, t.value ];
}
yield* s(i, n, a);
}
yield* s(0, this.opts, this.query);
}
async has(t) {
const e = `SELECT EXISTS ( SELECT * FROM ${this.opts.table} WHERE key = ? )`;
const s = await this.query(e, t);
return Object.values(s[0])[0] === 1;
}
async disconnect() {
await this.close();
}
};
export { n as KeyvSqlite };