Files
dev/third_party/pi/packages/session-backends/sqlite-node/src/sqlite/sql.ts
alexion 4def357d09 chore(vendor): import pi 0.85.1
Imported as a linear vendor commit so forge rebases do not replay the upstream root tree.

git-subtree-dir: third_party/pi

git-subtree-split: d981de1229ef899957bbe968bc8dcda02a21f477
2026-09-14 10:48:47 -04:00

67 lines
2.1 KiB
TypeScript

import type { SqliteDatabase, SqliteRunResult } from "./types.ts";
type SqlTemplateValue = unknown | SqlQuery;
/** A parameterized SQLite query produced by {@link sql}. */
export class SqlQuery {
readonly queryText: string;
readonly params: readonly unknown[];
constructor(queryText: string, params: readonly unknown[] = []) {
this.queryText = queryText;
this.params = params;
}
exec(db: SqliteDatabase): void {
if (this.params.length > 0) throw new TypeError("SQLite exec queries cannot have parameters");
db.exec(this.queryText);
}
run(db: SqliteDatabase): SqliteRunResult {
return db.prepare(this.queryText).run(...this.params);
}
get<TRow extends object>(db: SqliteDatabase): TRow | undefined {
return db.prepare(this.queryText).get<TRow>(...this.params);
}
all<TRow extends object>(db: SqliteDatabase): TRow[] {
return db.prepare(this.queryText).all<TRow>(...this.params);
}
iterate<TRow extends object>(db: SqliteDatabase): Iterable<TRow> {
return db.prepare(this.queryText).iterate<TRow>(...this.params);
}
}
/** Builds a parameterized query. Nested queries are inlined; other interpolations become `?` parameters. */
export function sql(strings: TemplateStringsArray, ...values: SqlTemplateValue[]): SqlQuery {
let queryText = strings[0] ?? "";
const params: unknown[] = [];
for (let index = 0; index < values.length; index++) {
const value = values[index];
if (value instanceof SqlQuery) {
queryText += value.queryText;
params.push(...value.params);
} else {
queryText += "?";
params.push(value);
}
queryText += strings[index + 1] ?? "";
}
return new SqlQuery(queryText, params);
}
/** Joins trusted query fragments while preserving their parameter order. */
export function joinSqlFragments(fragments: readonly SqlQuery[], separator: string): SqlQuery {
let queryText = "";
const params: unknown[] = [];
for (let index = 0; index < fragments.length; index++) {
if (index > 0) queryText += separator;
const fragment = fragments[index]!;
queryText += fragment.queryText;
params.push(...fragment.params);
}
return new SqlQuery(queryText, params);
}