Add queue tables, quote SQL identifiers (v1.3.0)

- isQueue table option adds queue columns and a (status, available_at)
  index; BunSQLite.queue exposes add, claim, complete, fail and
  release_stale with atomic claims
- Set busy_timeout on connections so workers in separate processes wait
  instead of failing with SQLITE_BUSY
- Quote table and column names with backticks in generated SQL, so
  reserved words (to, order, group) work and unknown columns error
  instead of matching as string literals
- Tests for queue ops, multi-process claims and reserved-word names

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-10-18 16:29:14 +01:00
co-authored by Claude Opus 5.5
parent 07807cb19d
commit 938a1da71d
45 changed files with 1524 additions and 115 deletions
+4 -4
View File
@@ -1,5 +1,5 @@
import init from "../functions/init";
import { sqlIdent, sqlQuoteIdent } from "../utils/sql-safe";
import { sqlName } from "../utils/sql-safe";
export default async function ({ sql: passed_sql, table, data }) {
let sql = passed_sql;
const { dbSchema } = init();
@@ -9,7 +9,7 @@ export default async function ({ sql: passed_sql, table, data }) {
const set_sql_arr = Object.keys(Array.isArray(data) ? data[0] : data)
.filter((field) => field !== "updated_at")
.map((field) => {
const column = sqlIdent(field, "column name");
const column = sqlName(field, "column name");
return `${column} = excluded.${column}`;
});
set_sql_arr.push(`updated_at = ${now}`);
@@ -19,13 +19,13 @@ export default async function ({ sql: passed_sql, table, data }) {
const field = unique_fields[i];
if (!field?.fieldName)
continue;
sql += ` ON CONFLICT(${sqlQuoteIdent(field.fieldName)}) DO UPDATE SET ${set_sql}`;
sql += ` ON CONFLICT(${sqlName(field.fieldName, "column name")}) DO UPDATE SET ${set_sql}`;
}
if (table_schema.uniqueConstraints?.[0]) {
for (let i = 0; i < table_schema.uniqueConstraints.length; i++) {
const constraint = table_schema.uniqueConstraints[i];
const columns = constraint?.constraintTableFields
?.map((c) => sqlQuoteIdent(String(c.value)))
?.map((c) => sqlName(c.value, "column name"))
?.join(", ");
if (!columns)
continue;