UNPKG

@cran/pg.q

Version:

Cranberry Postgres Queue

64 lines (63 loc) 2.31 kB
import format from "pg-format"; export function createQueryNames(names) { const queryNames = { table: "queue", field_id: "id", field_attempts: "attempts", field_payload: "payload", ...names, }; if (!queryNames.order) { queryNames.order = ([ `${queryNames.field_attempts} asc`, `${queryNames.field_id} asc`, ]).join(","); } queryNames.order = queryNames.order.split(",") .map(function mapOrder(order) { const match = (/^(.+?)\s*(asc|desc)?$/u).exec(order.trim().toLowerCase()); if (null === match) { throw new Error(`Invalid order statement "${order}"`); } return format("%1$I %2$s", match[1], match[2] || "asc"); }).join(","); return queryNames; } function createQualifiedTableName({ schema, table, }) { return schema ? format("%1$I.%2$I", schema, table) : format("%1$I", table); } function createQueryGetNext(names, target) { const formatter = [ "update %1$s set %3$I = %3$I + 1 where %2$I = (", "select %2$I from %1$s where %3$I < 3", // and %5$I = %6$L "order by %4$s for no key update skip locked limit 1", ") returning %2$I as id", ]; const args = [ createQualifiedTableName(names), names.field_id, names.field_attempts, names.order, ]; if (names.field_target || target) { formatter.splice(2, 0, "and %5$I = %6$L"); args.push(names.field_target || "target", target || "default"); } return format(formatter.join(" "), ...args); } export function createQueries(names, target) { const rule = ([ "z", ...(names.schema?.split(/[^\w]/gu) || []), ...(names.table.split(/[^\w]/gu)), ]).join("_"); const qualifiedTableName = createQualifiedTableName(names); return { next: createQueryGetNext(names, target), deq: format("delete from %1$s where %2$I = $1 returning %3$I as payload", ...([qualifiedTableName, names.field_id, names.field_payload,])), setup: format("create or replace rule %2$I as on insert to %1$s do also notify %2$I", ...([qualifiedTableName, rule,])), listen: format("listen %1$I", rule), unlisten: format("unlisten %1$I", rule), }; }