UNPKG

shelving

Version:

Toolkit for using data in JavaScript.

57 lines (56 loc) 1.98 kB
import { SQLiteProvider } from "../db/provider/SQLiteProvider.js"; import { ValueError } from "../error/ValueError.js"; import { isArray } from "../util/array.js"; import { isPlainObject } from "../util/object.js"; /** * Cloudflare D1 database provider. * * Uses the D1 Worker API for execution and standard SQL from `SQLProvider`. */ export class CloudflareD1Provider extends SQLiteProvider { _db; constructor(db) { super(); this._db = db; } async exec(strings, ...values) { const { query, values: bindings } = _getD1Query(strings, values, this.exec); const result = await this._db .prepare(query) .bind(...bindings) .run(); return result.results ?? []; } } function _getD1Query(strings, values, caller) { let query = strings[0] ?? ""; const bindings = []; for (const [index, value] of values.entries()) { const part = _getD1Part(value, caller); query += part.query; bindings.push(...part.values); query += strings[index + 1] ?? ""; } return { query, values: bindings }; } function _getD1Part(value, caller) { if (_isSQLQuery(value)) return _getD1Query(value.strings, value.values, caller); return { query: "?", values: [_getD1Value(value, caller)] }; } function _getD1Value(value, caller) { if (value === null || typeof value === "boolean" || typeof value === "string" || typeof value === "number") return value; if (isArray(value) || isPlainObject(value)) { try { return JSON.stringify(value); } catch (cause) { throw new ValueError("Cannot convert value to D1 JSON value", { cause, received: value, caller }); } } throw new ValueError("Cannot convert value to D1 binding", { received: value, caller }); } function _isSQLQuery(value) { return typeof value === "object" && !!value && "strings" in value && "values" in value; }