@vibeorm/sql 5.2.0 → 5.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/ast.d.ts CHANGED
@@ -1172,6 +1172,12 @@ export type AdvisoryLockStatement = {
1172
1172
  readonly wait: "wait" | "nowait";
1173
1173
  readonly key: AdvisoryLockKey;
1174
1174
  };
1175
+ /** An ordered set of transaction-scoped bigint advisory locks. */
1176
+ export type AdvisoryLocksStatement = {
1177
+ readonly kind: "advisoryLocks";
1178
+ readonly keys: readonly bigint[];
1179
+ readonly mode: AdvisoryLockMode;
1180
+ };
1175
1181
  /** The column an advisory try-lock projects its verdict into. */
1176
1182
  export declare const ADVISORY_LOCK_RESULT_COLUMN: string;
1177
1183
  /**
@@ -1290,6 +1296,7 @@ export type ChainStep = {
1290
1296
  * verdict-row outcome (the upsert fold always rolls it back).
1291
1297
  */
1292
1298
  export type ChainResult = {
1299
+ /** Both lists may be empty for a tally-only result: one count row, no model values. */
1293
1300
  readonly rowsFrom: readonly string[];
1294
1301
  readonly columns: readonly string[];
1295
1302
  readonly verdict?: {
@@ -1322,12 +1329,15 @@ export type ChainResult = {
1322
1329
  * `minRows` (EPIC W) makes the veto count-sensitive: the statement fails when
1323
1330
  * `step` returned FEWER rows than that (a multi-row INSERT a trigger shortened).
1324
1331
  * Omitted or 1 = "no row". A positive safe integer, rendered as SQL text.
1332
+ * `exactRows` instead requires equality, including zero. It is a nonnegative
1333
+ * safe integer and cannot combine with `minRows`.
1325
1334
  */
1326
1335
  export type ChainVeto = {
1327
1336
  readonly step: string;
1328
1337
  readonly token: string;
1329
1338
  readonly nonce: string;
1330
1339
  readonly minRows?: number;
1340
+ readonly exactRows?: number;
1331
1341
  };
1332
1342
  /** Count the RETURNING rows of `steps` into the result column `alias`. */
1333
1343
  export type ChainTally = {
@@ -1367,7 +1377,7 @@ export type ChainStatement = {
1367
1377
  readonly steps: readonly ChainStep[];
1368
1378
  readonly result: ChainResult;
1369
1379
  };
1370
- export type SqlStatement = SelectStatement | InsertStatement | UpdateStatement | DeleteStatement | RlsEnableStatement | RlsForceStatement | RlsDisableStatement | RlsNoForceStatement | RlsDropPolicyStatement | RlsPolicyStatement | RlsContextStatement | RlsRoleStatement | AdvisoryLockStatement | ChainStatement;
1380
+ export type SqlStatement = SelectStatement | InsertStatement | UpdateStatement | DeleteStatement | RlsEnableStatement | RlsForceStatement | RlsDisableStatement | RlsNoForceStatement | RlsDropPolicyStatement | RlsPolicyStatement | RlsContextStatement | RlsRoleStatement | AdvisoryLockStatement | AdvisoryLocksStatement | ChainStatement;
1371
1381
  /** Readiness statements remain distinct from application queries. */
1372
1382
  export type RlsReadinessStatement = {
1373
1383
  readonly kind: "rlsReadiness";
package/dist/index.d.ts CHANGED
@@ -40,10 +40,10 @@ export type { ResultDecoder, ResultReadDecoder, ResultParameterEncoder, ResultSc
40
40
  * lives in this package; see the root sql-catalog.md for the reviewable surface.
41
41
  */
42
42
  export { compileExclusion, renderExclusionSetup, renderExclusionDdl, renderExclusionCatalog, renderExclusionProbe } from "./exclusion.ts";
43
- export type { AdvisoryLockKey, AdvisoryLockStatement, AggFn, AggRef, AggSelect, ChainResult, ChainRowSource, ChainStatement, ChainStep, ChainStepStatement, ChainTally, ChainVeto, ColRef, ComparisonOp, DateTruncation, CountSubquery, ScalarSubquery, DeleteStatement, ExcludedRef, InnerJoin, KeyListMember, KeyPage, KeyRows, KeyTableJoin, KeyTableMember, InsertSelectStatement, InsertStatement, ReturningColumn, JsonFilterOp, LateralJoin, LeftJoin, ListSetOperation, OnConflictClause, OnConflictDoNothing, OnConflictUpdate, OrderByAggregate, OrderByColumn, OrderBySubquery, OrderTerm, RowLock, RowNumberProjection, DbNowMarker, JsonParamCell, SelectExpr, SelectStatement, SetOperation, SetOperator, SqlExpr, SqlStatement, StepColumnRef, TableRef, UpdateStatement, } from "./ast.ts";
43
+ export type { AdvisoryLockKey, AdvisoryLockStatement, AdvisoryLocksStatement, AggFn, AggRef, AggSelect, ChainResult, ChainRowSource, ChainStatement, ChainStep, ChainStepStatement, ChainTally, ChainVeto, ColRef, ComparisonOp, DateTruncation, CountSubquery, ScalarSubquery, DeleteStatement, ExcludedRef, InnerJoin, KeyListMember, KeyPage, KeyRows, KeyTableJoin, KeyTableMember, InsertSelectStatement, InsertStatement, ReturningColumn, JsonFilterOp, LateralJoin, LeftJoin, ListSetOperation, OnConflictClause, OnConflictDoNothing, OnConflictUpdate, OrderByAggregate, OrderByColumn, OrderBySubquery, OrderTerm, RowLock, RowNumberProjection, DbNowMarker, JsonParamCell, SelectExpr, SelectStatement, SetOperation, SetOperator, SqlExpr, SqlStatement, StepColumnRef, TableRef, UpdateStatement, } from "./ast.ts";
44
44
  export { ADVISORY_LOCK_RESULT_COLUMN, CHAIN_VETO_PREFIX, CHAIN_VETO_TOKEN_PATTERN, SQL_DEFAULT_CELL, SQL_KEEP_CELL, chainVetoToken, dbNowMarker, excludedRef, isDbNowMarker, isExcludedRef, isJsonParamCell, isListSetOperation, isSetOperation, isSqlDefaultCell, isSqlKeepCell, isStepColumnRef, jsonParamCell, returningColumnName, stepColumnRef, } from "./ast.ts";
45
45
  export type { AdvisoryLockFunctions, AdvisoryLockModeFunctions, RowLockSyntax, EmptyInsertSyntax, SqlDialect, } from "./dialect.ts";
46
- export { ADVISORY_KEY_BOUNDS, describeRowLock, renderAdvisoryLock, renderRowLockClause } from "./locks.ts";
46
+ export { ADVISORY_KEY_BOUNDS, describeRowLock, renderAdvisoryLock, renderAdvisoryLocks, renderRowLockClause } from "./locks.ts";
47
47
  export { JSON_TRANSPORT, projectionOutputName } from "./json-transport.ts";
48
48
  export { postgresDialect } from "./dialects/postgres.ts";
49
49
  export { sqliteDialect } from "./dialects/sqlite.ts";
package/dist/index.js CHANGED
@@ -2990,6 +2990,28 @@ function renderAdvisoryLock(params) {
2990
2990
  returning: "none"
2991
2991
  };
2992
2992
  }
2993
+ function renderAdvisoryLocks(params) {
2994
+ const { dialect, keys, mode } = params;
2995
+ const functions = dialect.advisoryLockFunctions;
2996
+ if (functions === null)
2997
+ throw unsupportedCapability15({ dialect: dialect.name, feature: "advisory locks" });
2998
+ if (mode !== "exclusive" && mode !== "shared")
2999
+ throw internalError({ message: "advisory lock mode must be exclusive or shared" });
3000
+ if (keys.some((key) => typeof key !== "bigint" || key < ADVISORY_KEY_BOUNDS.single.min || key > ADVISORY_KEY_BOUNDS.single.max)) {
3001
+ throw internalError({ message: "advisory lock keys must be signed 64-bit integers" });
3002
+ }
3003
+ const collector = new ParamCollector(dialect);
3004
+ const binding = collector.add(JSON.stringify(keys.map((key) => key.toString())));
3005
+ const fn = (mode === "exclusive" ? functions.exclusive : functions.shared).wait;
3006
+ const table = dialect.quoteIdent({ name: "__vibe_locks" });
3007
+ const key = dialect.quoteIdent({ name: "key" });
3008
+ const order = dialect.quoteIdent({ name: "ordinal" });
3009
+ return {
3010
+ text: `SELECT ${fn}(${table}.${key}${functions.keyCast.single}) FROM jsonb_array_elements_text(${binding}::text::jsonb) WITH ORDINALITY AS ${table}(${key}, ${order}) ORDER BY ${table}.${order}`,
3011
+ values: collector.values,
3012
+ returning: "none"
3013
+ };
3014
+ }
2993
3015
  function assertInt32(params) {
2994
3016
  const { value, part } = params;
2995
3017
  if (!Number.isInteger(value) || value < ADVISORY_KEY_BOUNDS.pair.min || value > ADVISORY_KEY_BOUNDS.pair.max) {
@@ -4111,6 +4133,8 @@ function renderStatement(params) {
4111
4133
  }
4112
4134
  case "select":
4113
4135
  return renderSelect({ dialect, statement, collector });
4136
+ case "advisoryLocks":
4137
+ return renderAdvisoryLocks({ dialect, keys: statement.keys, mode: statement.mode });
4114
4138
  case "advisoryLock":
4115
4139
  return renderAdvisoryLock({ dialect, statement, collector });
4116
4140
  case "insert":
@@ -5427,6 +5451,9 @@ function renderChain(params) {
5427
5451
  defined.add(step.name);
5428
5452
  }
5429
5453
  const result = statement.result;
5454
+ if (result.rowsFrom.length === 0 && result.columns.length === 0 && result.tally !== undefined && result.verdict === undefined) {
5455
+ return { text: `WITH ${steps.join(", ")} SELECT ${renderTallyColumn({ dialect, result, defined, collector })}`, values: collector.values, returning: "none" };
5456
+ }
5430
5457
  if (result.rowsFrom.length === 0 || result.columns.length === 0) {
5431
5458
  throw internalError4({ message: "a chain result needs at least one source step and one column" });
5432
5459
  }
@@ -5525,7 +5552,10 @@ function renderTallyColumn(params) {
5525
5552
  const minRows = veto.minRows ?? 1;
5526
5553
  if (!Number.isSafeInteger(minRows) || minRows < 1)
5527
5554
  throw internalError4({ message: `chain veto "${veto.token}" needs a positive integer minRows` });
5528
- const when = minRows === 1 ? `WHEN NOT EXISTS (SELECT 1 FROM ${step(veto.step)})` : `WHEN ${count(veto.step)} < ${minRows}`;
5555
+ if (veto.exactRows !== undefined && (!Number.isSafeInteger(veto.exactRows) || veto.exactRows < 0 || veto.minRows !== undefined)) {
5556
+ throw internalError4({ message: `chain veto "${veto.token}" needs a nonnegative safe integer exactRows without minRows` });
5557
+ }
5558
+ const when = veto.exactRows !== undefined ? `WHEN ${count(veto.step)} <> ${veto.exactRows}` : minRows === 1 ? `WHEN NOT EXISTS (SELECT 1 FROM ${step(veto.step)})` : `WHEN ${count(veto.step)} < ${minRows}`;
5529
5559
  return `${when} THEN CAST('${CHAIN_VETO_PREFIX}${veto.token}:' || ${collector.add(veto.nonce)} || ':' || ${count(veto.step)} AS integer)`;
5530
5560
  });
5531
5561
  return `CASE ${arms.join(" ")} ELSE ${sum} END AS ${dialect.quoteIdent({ name: tally.alias })}`;
@@ -6309,6 +6339,7 @@ export {
6309
6339
  recordSqlBindingCheck,
6310
6340
  registerSqlHandleCheck,
6311
6341
  renderAdvisoryLock,
6342
+ renderAdvisoryLocks,
6312
6343
  renderCheckProbe,
6313
6344
  renderColumnStateQuery,
6314
6345
  renderConstraintOwnedIndexDrop,
@@ -6414,4 +6445,4 @@ export {
6414
6445
  toPgArrayLiteral
6415
6446
  };
6416
6447
 
6417
- //# debugId=7A09C0BE2E07A46664756E2164756E21
6448
+ //# debugId=A6FF0AC9CFF5903864756E2164756E21