kern-orm 0.7.0 → 0.8.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/{database-B7Kf5Q9X.mjs → driver-error-Dx5R83Rp.mjs} +88 -1
- package/dist/{index-CLKi9gZL.d.mts → index-B1aH5Ht0.d.mts} +64 -6
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +2 -2
- package/dist/testing.d.mts +1 -3
- package/dist/testing.mjs +125 -13
- package/dist/types.d.mts +1 -1
- package/package.json +1 -7
|
@@ -4920,4 +4920,91 @@ function createDatabase({ driver, test }) {
|
|
|
4920
4920
|
function createLockStatement(key) {
|
|
4921
4921
|
return createStatement("SELECT pg_advisory_xact_lock(hashtextextended($1, 0))", [key]);
|
|
4922
4922
|
}
|
|
4923
|
-
|
|
4923
|
+
// src/execution/driver-error.ts
|
|
4924
|
+
/** Marks an instance of `QueryError` of any copy of kern-orm, which `instanceof QueryError` of another copy recognizes. */
|
|
4925
|
+
const queryErrorBrand = /* @__PURE__ */ Symbol.for("kern-orm.QueryError");
|
|
4926
|
+
/** Marks an instance of `ConnectionError` of any copy of kern-orm. */
|
|
4927
|
+
const connectionErrorBrand = /* @__PURE__ */ Symbol.for("kern-orm.ConnectionError");
|
|
4928
|
+
/**
|
|
4929
|
+
* Tells whether `value` is an instance of `errorClass`: by the brand of any copy of kern-orm for `errorClass` itself, and by the prototype chain for its subclasses.
|
|
4930
|
+
*
|
|
4931
|
+
* An application can load several copies of kern-orm, such as one of a driver, and an error of one copy is then an instance of the class of another.
|
|
4932
|
+
*/
|
|
4933
|
+
function isInstance(errorClass, root, brand, value) {
|
|
4934
|
+
if (errorClass !== root) return Function.prototype[Symbol.hasInstance].call(errorClass, value);
|
|
4935
|
+
return typeof value === "object" && value !== null && value[brand] === true;
|
|
4936
|
+
}
|
|
4937
|
+
/** Sets the brand of `error`, which is not enumerable, so that it does not show among the fields of the error. */
|
|
4938
|
+
function setBrand(error, brand) {
|
|
4939
|
+
Object.defineProperty(error, brand, { value: true });
|
|
4940
|
+
}
|
|
4941
|
+
/**
|
|
4942
|
+
* Error of a statement that PostgreSQL rejected, such as for a violated constraint; the connection of the statement stays usable.
|
|
4943
|
+
*
|
|
4944
|
+
* A driver whose client gives the severity of an error only in the language of the server, such as node-postgres, tells such an error by its SQLSTATE when the server translates its messages.
|
|
4945
|
+
* An error that ends the session with a code that a statement also gets, such as `40001` of a conflict with recovery on a replica, then rejects with `QueryError`, and the next statement on the connection with `ConnectionError`.
|
|
4946
|
+
*/
|
|
4947
|
+
var QueryError = class QueryError extends Error {
|
|
4948
|
+
name = "QueryError";
|
|
4949
|
+
/** SQLSTATE of the error, such as `23505` for a violated unique constraint. */
|
|
4950
|
+
code;
|
|
4951
|
+
/** Name of the constraint that the statement violated, if any. */
|
|
4952
|
+
constraint;
|
|
4953
|
+
constructor(message, fields) {
|
|
4954
|
+
super(message, "cause" in fields ? { cause: fields.cause } : void 0);
|
|
4955
|
+
this.code = fields.code;
|
|
4956
|
+
this.constraint = fields.constraint;
|
|
4957
|
+
setBrand(this, queryErrorBrand);
|
|
4958
|
+
}
|
|
4959
|
+
/** Tells whether `value` is an instance of the class, including one of `QueryError` of another copy of kern-orm. */
|
|
4960
|
+
static [Symbol.hasInstance](value) {
|
|
4961
|
+
return isInstance(this, QueryError, queryErrorBrand, value);
|
|
4962
|
+
}
|
|
4963
|
+
};
|
|
4964
|
+
/**
|
|
4965
|
+
* Error of a statement or connection that failed for another reason than PostgreSQL rejecting a statement, such as a lost connection, a timeout of the client, or a closed driver.
|
|
4966
|
+
*
|
|
4967
|
+
* The statement may have run or not, and its connection may be lost or in an unknown state of its transaction.
|
|
4968
|
+
*/
|
|
4969
|
+
var ConnectionError = class ConnectionError extends Error {
|
|
4970
|
+
name = "ConnectionError";
|
|
4971
|
+
constructor(message, options) {
|
|
4972
|
+
super(message, options);
|
|
4973
|
+
setBrand(this, connectionErrorBrand);
|
|
4974
|
+
}
|
|
4975
|
+
/** Tells whether `value` is an instance of the class, including one of `ConnectionError` of another copy of kern-orm. */
|
|
4976
|
+
static [Symbol.hasInstance](value) {
|
|
4977
|
+
return isInstance(this, ConnectionError, connectionErrorBrand, value);
|
|
4978
|
+
}
|
|
4979
|
+
};
|
|
4980
|
+
/** SQLSTATE of five digits or uppercase letters; clients also give codes of their own, such as `ECONNRESET` or `CONNECTION_CLOSED`. */
|
|
4981
|
+
const sqlState = /^[0-9A-Z]{5}$/;
|
|
4982
|
+
/** SQLSTATE of an error that ends the session: of the classes of connection exceptions, authorization, operator intervention, and internal errors, and the timeouts of an idle transaction and of a transaction. */
|
|
4983
|
+
const sessionEndingCode = /^(?:08|28|57P|XX|25P03$|25P04$)/;
|
|
4984
|
+
/** Tells whether an error of the server of `severity` and SQLSTATE `code` ends its session. */
|
|
4985
|
+
function isSessionEnding(severity, code) {
|
|
4986
|
+
if (severity === "ERROR") return false;
|
|
4987
|
+
if (severity === "FATAL" || severity === "PANIC") return true;
|
|
4988
|
+
return sessionEndingCode.test(code);
|
|
4989
|
+
}
|
|
4990
|
+
/**
|
|
4991
|
+
* Classifies an error of a client as `QueryError` or `ConnectionError`, by the fields of the PostgreSQL error it carries, for a driver to reject with.
|
|
4992
|
+
*
|
|
4993
|
+
* An error that kern-orm has already classified returns as it is.
|
|
4994
|
+
* An error without a severity or a SQLSTATE, such as of a client that lost its connection, is a `ConnectionError`, and so is one of severity `FATAL` or `PANIC`, which ends the session.
|
|
4995
|
+
* An error of severity `ERROR` is a `QueryError`.
|
|
4996
|
+
* With a translated severity, the SQLSTATE tells an error that ends the session, so a few errors of other codes that end it give `QueryError`.
|
|
4997
|
+
*/
|
|
4998
|
+
function toDriverError(error, fields) {
|
|
4999
|
+
if (error instanceof QueryError || error instanceof ConnectionError) return error;
|
|
5000
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
5001
|
+
const { severity, code, constraint } = fields ?? {};
|
|
5002
|
+
if (typeof severity !== "string" || typeof code !== "string" || !sqlState.test(code)) return new ConnectionError(message, { cause: error });
|
|
5003
|
+
if (isSessionEnding(severity, code)) return new ConnectionError(message, { cause: error });
|
|
5004
|
+
return new QueryError(message, {
|
|
5005
|
+
code,
|
|
5006
|
+
constraint: typeof constraint === "string" ? constraint : void 0,
|
|
5007
|
+
cause: error
|
|
5008
|
+
});
|
|
5009
|
+
}
|
|
5010
|
+
export { literal as A, RequiredRelationError as C, createAggregateCall as D, countType as E, combineNodes as F, isColumnValues as M, not as N, createCountCall as O, or as P, NotFoundError as S, countProjection as T, many as _, identifier as a, createTableFactory as b, defineSchema as c, requireDerived as d, addTerms as f, matchColumn as g, orderBy as h, createDatabase as i, and as j, toAggregateType as k, SelectQuery as l, desc as m, QueryError as n, param as o, asc as p, toDriverError as r, sql as s, ConnectionError as t, from as u, one as v, ResultDecodeError as w, defineTable as x, createStatement as y };
|
|
@@ -241,8 +241,11 @@ interface DriverResult {
|
|
|
241
241
|
* Physical database access: transport, pooling, and connections.
|
|
242
242
|
*
|
|
243
243
|
* A driver sends parameters as text without a declared type, so that the statement text alone determines their types, and returns values as text without parsing them.
|
|
244
|
+
* It rejects with `QueryError` a statement or script that PostgreSQL rejected, whose connection stays usable, and with `ConnectionError` any other failure of a statement, a script, or a connection.
|
|
244
245
|
*/
|
|
245
246
|
interface Driver {
|
|
247
|
+
/** Whether the driver closes a reserved connection that it cannot return to the pool, such as one left in a transaction or lost; a driver over a client that cannot close one, such as postgres.js 3, keeps it reserved instead. */
|
|
248
|
+
readonly closesReservedConnections: boolean;
|
|
246
249
|
/** Executes a statement on any pooled connection. */
|
|
247
250
|
execute(statement: SqlStatement): Promise<DriverResult>;
|
|
248
251
|
/** Executes a script of statements without parameters, such as DDL separated by semicolons, on any pooled connection, where PostgreSQL runs them in one implicit transaction. */
|
|
@@ -252,7 +255,7 @@ interface Driver {
|
|
|
252
255
|
/**
|
|
253
256
|
* Closes the connections once the statements on the pool and the transactions on reserved connections end.
|
|
254
257
|
*
|
|
255
|
-
* From the call, it rejects a new statement or script on the pool and a new connection
|
|
258
|
+
* From the call, it rejects a new statement or script on the pool and a new connection with `ConnectionError`.
|
|
256
259
|
*/
|
|
257
260
|
close(): Promise<void>;
|
|
258
261
|
}
|
|
@@ -267,14 +270,14 @@ interface Connection {
|
|
|
267
270
|
/** Executes a script of statements without parameters on the connection, in the order of calls with its statements. */
|
|
268
271
|
executeScript(text: string): Promise<void>;
|
|
269
272
|
/**
|
|
270
|
-
* Returns the connection to the pool
|
|
273
|
+
* Returns the connection to the pool.
|
|
271
274
|
*
|
|
272
|
-
* Without `failure`, the transaction
|
|
273
|
-
* With `failure`,
|
|
275
|
+
* Without `failure`, the connection is idle: no transaction ran on it, or its `COMMIT` or `ROLLBACK` completed.
|
|
276
|
+
* With `failure`, the last statement on the connection failed, such as `BEGIN`, `COMMIT`, or `ROLLBACK`, so the connection may be in a transaction or lost: the driver returns it to the pool only once it is idle, and never returns a connection it lost.
|
|
274
277
|
*/
|
|
275
278
|
release(failure?: TransactionFailure): void | Promise<void>;
|
|
276
279
|
}
|
|
277
|
-
/** Failure of the statement
|
|
280
|
+
/** Failure of the last statement on a reserved connection, after which the connection may not be idle. */
|
|
278
281
|
interface TransactionFailure {
|
|
279
282
|
readonly error: unknown;
|
|
280
283
|
}
|
|
@@ -3332,6 +3335,61 @@ declare const textOperators: TextOperators;
|
|
|
3332
3335
|
declare const TRUE: Expression<boolean>;
|
|
3333
3336
|
/** Condition that never holds, such as for a branch of `or` built in code: `or(check, isAdmin ? other : FALSE)`. */
|
|
3334
3337
|
declare const FALSE: Expression<boolean>;
|
|
3338
|
+
/**
|
|
3339
|
+
* Error of a statement that PostgreSQL rejected, such as for a violated constraint; the connection of the statement stays usable.
|
|
3340
|
+
*
|
|
3341
|
+
* A driver whose client gives the severity of an error only in the language of the server, such as node-postgres, tells such an error by its SQLSTATE when the server translates its messages.
|
|
3342
|
+
* An error that ends the session with a code that a statement also gets, such as `40001` of a conflict with recovery on a replica, then rejects with `QueryError`, and the next statement on the connection with `ConnectionError`.
|
|
3343
|
+
*/
|
|
3344
|
+
declare class QueryError extends Error {
|
|
3345
|
+
readonly name = "QueryError";
|
|
3346
|
+
/** SQLSTATE of the error, such as `23505` for a violated unique constraint. */
|
|
3347
|
+
readonly code: string;
|
|
3348
|
+
/** Name of the constraint that the statement violated, if any. */
|
|
3349
|
+
readonly constraint: string | undefined;
|
|
3350
|
+
constructor(message: string, fields: {
|
|
3351
|
+
code: string;
|
|
3352
|
+
constraint?: string | undefined;
|
|
3353
|
+
cause?: unknown;
|
|
3354
|
+
});
|
|
3355
|
+
/** Tells whether `value` is an instance of the class, including one of `QueryError` of another copy of kern-orm. */
|
|
3356
|
+
static [Symbol.hasInstance]<T>(this: abstract new (...args: never) => T, value: unknown): value is T;
|
|
3357
|
+
}
|
|
3358
|
+
/**
|
|
3359
|
+
* Error of a statement or connection that failed for another reason than PostgreSQL rejecting a statement, such as a lost connection, a timeout of the client, or a closed driver.
|
|
3360
|
+
*
|
|
3361
|
+
* The statement may have run or not, and its connection may be lost or in an unknown state of its transaction.
|
|
3362
|
+
*/
|
|
3363
|
+
declare class ConnectionError extends Error {
|
|
3364
|
+
readonly name = "ConnectionError";
|
|
3365
|
+
constructor(message: string, options?: {
|
|
3366
|
+
cause?: unknown;
|
|
3367
|
+
});
|
|
3368
|
+
/** Tells whether `value` is an instance of the class, including one of `ConnectionError` of another copy of kern-orm. */
|
|
3369
|
+
static [Symbol.hasInstance]<T>(this: abstract new (...args: never) => T, value: unknown): value is T;
|
|
3370
|
+
}
|
|
3371
|
+
/** Fields of the PostgreSQL error that an error of a client carries, by which `toDriverError` classifies it. */
|
|
3372
|
+
interface DriverErrorFields {
|
|
3373
|
+
/**
|
|
3374
|
+
* Severity of the error, such as `ERROR` or `FATAL`.
|
|
3375
|
+
*
|
|
3376
|
+
* Pass the severity in English when the client gives it, and the one in the language of the server otherwise.
|
|
3377
|
+
*/
|
|
3378
|
+
readonly severity?: unknown;
|
|
3379
|
+
/** SQLSTATE of the error, such as `23505`. */
|
|
3380
|
+
readonly code?: unknown;
|
|
3381
|
+
/** Name of the constraint that the statement violated. */
|
|
3382
|
+
readonly constraint?: unknown;
|
|
3383
|
+
}
|
|
3384
|
+
/**
|
|
3385
|
+
* Classifies an error of a client as `QueryError` or `ConnectionError`, by the fields of the PostgreSQL error it carries, for a driver to reject with.
|
|
3386
|
+
*
|
|
3387
|
+
* An error that kern-orm has already classified returns as it is.
|
|
3388
|
+
* An error without a severity or a SQLSTATE, such as of a client that lost its connection, is a `ConnectionError`, and so is one of severity `FATAL` or `PANIC`, which ends the session.
|
|
3389
|
+
* An error of severity `ERROR` is a `QueryError`.
|
|
3390
|
+
* With a translated severity, the SQLSTATE tells an error that ends the session, so a few errors of other codes that end it give `QueryError`.
|
|
3391
|
+
*/
|
|
3392
|
+
declare function toDriverError(error: unknown, fields?: DriverErrorFields): QueryError | ConnectionError;
|
|
3335
3393
|
/**
|
|
3336
3394
|
* Defines a reusable expression of a table, which the callbacks of queries over the table call with their columns and any further arguments, such as to filter by it and select it in one query.
|
|
3337
3395
|
*
|
|
@@ -3415,4 +3473,4 @@ declare function param<E extends AnyExpression, V extends (E extends AnyExpressi
|
|
|
3415
3473
|
* A run of capital letters is one word, such as `user_id` for `userID`, and digits stay in their word, such as `line2`.
|
|
3416
3474
|
*/
|
|
3417
3475
|
declare function toSnakeCase(key: string): string;
|
|
3418
|
-
export {
|
|
3476
|
+
export { TransformedQuery as $, Column as $i, QueryContext as $n, Operand as $r, CaseValue as $t, TypedExpression as A, defineTable as Ai, StringAggOptions as An, CombinedCondition as Ar, SelectionState as At, TransactionOptions as B, TransactionFailure as Bi, stringAgg as Bn, OneValueRows as Br, ConflictActionRequired as Bt, textOperators as C, Selectable as Ci, Literal as Cn, PrimaryKeyColumn as Cr, SchemaPartRelations as Ct, BaseOperators as D, TableOptions as Di, CountExpression as Dn, WhereCondition as Dr, AnyRecordQuery as Dt, AnyExpression as E, TableKeys as Ei, AggregateOptions as En, WhereCallback as Er, defineSchema as Et, DbMutationState as F, ResultRows as Fi, countDistinct as Fn, not as Fr, FieldTypes as Ft, TestFixture as G, Type as Gi, OrderTerm as Gn, CompileOptions as Gr, InsertMutationState as Gt, TransactionCoordinator as H, AnyType as Hi, OrderColumns as Hn, ResultByRows as Hr, ConflictTarget as Ht, DbOf as I, Connection as Ii, every as In, or as Ir, InitialSqlQueryState as It, TestTransactionOptions as J, TypeOptions as Ji, SelectedRefs as Jn, HasEquality as Jr, Helper as Jt, TestHelpers as K, TypeInput as Ki, OrderTerms as Kn, EqualityOperator as Kr, MutationQuery as Kt, DbQueryState as L, Driver as Li, max as Ln, ExistsValueType as Lr, SqlQuery as Lt, AnyDb as M, RequiredRelationError as Mi, UnfilteredStringAggOptions as Mn, ConditionOperand as Mr, SelectQueryKind as Mt, BindOptions as N, ResultDecodeError as Ni, avg as Nn, Predicate as Nr, AnySqlQuery as Nt, Expression as O, ToColumns as Oi, GroupAggregateExpression as On, WhereFilter as Or, RecordQuery as Ot, Db as P, ResultMode as Pi, count as Pn, and as Pr, DecodedFields as Pt, SynchronousResult as Q, AnyColumn as Qi, ColumnRefs as Qn, ComparisonSignature as Qr, CaseCondition as Qt, Database as R, DriverResult as Ri, min as Rn, FilteredRows as Rr, SqlQueryState as Rt, TextTypeOperators as S, KeyColumns as Si, SelectionUses as Sn, NotAKey as Sr, SchemaPart as St, orderingOperators as T, TableFactoryOptions as Ti, AggregateExpression as Tn, EqValue as Tr, Tables as Tt, OpenedTestFixture as U, BaseType as Ui, OrderDirection as Un, ValueRows as Ur, InitialInsertState as Ut, createDatabase as V, createStatement as Vi, sum as Vn, QueryResult as Vr, ConflictKeyRequired as Vt, PendingTestFixture as W, TextValue as Wi, OrderKey as Wn, CountValueType as Wr, InitialMutationState as Wt, AnyTransformedQuery as X, TypeTransform as Xi, desc as Xn, equalityOperators as Xr, defineHelper as Xt, createTestHelpers as Y, TypeOutput as Yi, asc as Yn, InSignature as Yr, HelperEffect as Yt, NotSynchronous as Z, defineType as Zi, orderBy as Zn, BooleanResult as Zr, CaseBranch as Zt, TRUE as _, AnyTableKeys as _i, NestedQuery as _n, SelectedOperandType as _r, UsedRelation as _t, sql as a, NoOperators as aa, ValuesQuery as ai, caseWhen as an, SingletonInsertMany as ar, Relation as at, TextLengthSignature as b, ColumnShape as bi, SelectionFieldTypes as bn, GroupTerms as br, AnySchema as bt, MatchResult as c, GenericOperatorImplementation as ca, Grouped as ci, least as cn, ConflictUpdateSet as cr, RelationKey as ct, defineExpression as d, QueryStateOf as di, ExpressionValue as dn, UpdateValues as dr, RequiredMember as dt, ColumnAttributes as ea, OperandValue as ei, FollowingOperand as en, RelationRefs as er, TransformedQueryState as et, ConnectionError as f, QueryValueType as fi, GroupOperandValue as fn, UpsertValues as fr, SchemaContext as ft, FALSE as g, AnyTable as gi, MergeSelection as gn, GroupedState as gr, UsableRelation as gt, toDriverError as h, TableQueryState as hi, GroupedRecord as hn, FoundState as hr, TableRelations as ht, param as i, MergeOperators as ia, TypedScalarQuery as ii, TypedOperandOperators as in, SelectQuery as ir, OneRelationKeys as it, UntypedExpression as j, NotFoundError as ji, UnfilteredAggregateOptions as jn, Condition as jr, AnyQuery as jt, ExpressionOperators as k, createTableFactory as ki, GroupValue as kn, WhereValues as kr, RecordQueryState as kt, NotAColumn as l, OperatorSignature as la, InitialQueryState as li, ColumnFieldTypes as ln, InsertValues as lr, RelationKeys as lt, QueryError as m, SingletonQueryState as mi, GroupedField as mn, FoundQueryState as mr, TableContext as mt, SqlTemplate as n, ToColumn as na, OperandUses as ni, TypedOperand as nn, BoundSelectQuery as nr, MergeRelations as nt, ColumnRefKey as o, OperatorDefinitions as oa, EmptyRecord as oi, coalesce as on, from as or, RelationDeclaration as ot, DriverErrorFields as p, SelectQueryState as pi, GroupSelectionResult as pn, FilteredStateRows as pr, SchemaRelations as pt, TestHooks as q, TypeOperators as qi, Ordering as qn, EqualityOperators as qr, MutationQueryState as qt, identifier as r, BoundOperators as ra, ScalarQuery as ri, TypedOperandInput as rn, ResultOf as rr, NoRelations as rt, MatchCheck as s, GenericOperator as sa, FoundKey as si, greatest as sn, ColumnValue as sr, RelationDeclarations as st, toSnakeCase as t, KeyKind as ta, compare as ti, NullSkippingResult as tn, AnySelectQuery as tr, DeclaredRelations as tt, matches as u, defineGenericOperator as ua, QueryState as ui, ExpressionInput as un, UpdateSet as ur, RelationKind as ut, PatternSignature as v, ColumnDefinitions as vi, SelectedFieldTypes as vn, RowLockOptions as vr, many as vt, NumberTypeOperators as w, Table as wi, literal as wn, PrimaryKeyValues as wr, SchemaTables as wt, TextOperators as x, ColumnValues as xi, SelectionResult as xn, KeyCheck as xr, Schema as xt, TextConversionSignature as y, ColumnOperators as yi, Selection as yn, GroupTerm as yr, one as yt, DatabaseOptions as z, SqlStatement as zi, some as zn, OneRow as zr, AnyMutationQuery as zt };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { $ as
|
|
2
|
-
export { type AggregateExpression, type AggregateOptions, type AnyColumn, type AnyDb, type AnyExpression, type AnyMutationQuery, type AnyQuery, type AnyRecordQuery, type AnySchema, type AnySelectQuery, type AnySqlQuery, type AnyTable, type AnyTableKeys, type AnyTransformedQuery, type AnyType, type BaseOperators, type BaseType, type BindOptions, type BooleanResult, type BoundOperators, type BoundSelectQuery, type CaseBranch, type CaseCondition, type CaseValue, type Column, type ColumnAttributes, type ColumnDefinitions, type ColumnFieldTypes, type ColumnOperators, type ColumnRefKey, type ColumnRefs, type ColumnShape, type ColumnValue, type ColumnValues, type CombinedCondition, type ComparisonSignature, type CompileOptions, type Condition, type ConditionOperand, type ConflictActionRequired, type ConflictKeyRequired, type ConflictTarget, type ConflictUpdateSet, type Connection, type CountExpression, type CountValueType, type Database, type DatabaseOptions, type Db, type DbMutationState, type DbOf, type DbQueryState, type DeclaredRelations, type DecodedFields, type Driver, type DriverResult, type EmptyRecord, type EqValue, type EqualityOperator, type EqualityOperators, type ExistsValueType, type Expression, type ExpressionInput, type ExpressionOperators, type ExpressionValue, FALSE, type FieldTypes, type FilteredRows, type FilteredStateRows, type FollowingOperand, type FoundKey, type FoundQueryState, type FoundState, type GenericOperator, type GenericOperatorImplementation, type GroupAggregateExpression, type GroupOperandValue, type GroupSelectionResult, type GroupTerm, type GroupTerms, type GroupValue, type Grouped, type GroupedField, type GroupedRecord, type GroupedState, type HasEquality, type Helper, type HelperEffect, type InSignature, type InitialInsertState, type InitialMutationState, type InitialQueryState, type InitialSqlQueryState, type InsertMutationState, type InsertValues, type KeyCheck, type KeyColumns, type KeyKind, type Literal, type MatchCheck, type MatchResult, type MergeOperators, type MergeRelations, type MergeSelection, type MutationQuery, type MutationQueryState, type NestedQuery, type NoOperators, type NoRelations, type NotAColumn, type NotAKey, NotFoundError, type NotSynchronous, type NullSkippingResult, type NumberTypeOperators, type OneRelationKeys, type OneRow, type OneValueRows, type Operand, type OperandUses, type OperandValue, type OperatorDefinitions, type OperatorSignature, type OrderColumns, type OrderDirection, type OrderKey, type OrderTerm, type OrderTerms, type Ordering, type PatternSignature, type Predicate, type PrimaryKeyColumn, type PrimaryKeyValues, type QueryContext, type QueryResult, type QueryState, type QueryStateOf, type QueryValueType, type RecordQuery, type RecordQueryState, type Relation, type RelationDeclaration, type RelationDeclarations, type RelationKey, type RelationKeys, type RelationKind, type RelationRefs, type RequiredMember, RequiredRelationError, type ResultByRows, ResultDecodeError, type ResultMode, type ResultOf, type ResultRows, type RowLockOptions, type ScalarQuery, type Schema, type SchemaContext, type SchemaPart, type SchemaPartRelations, type SchemaRelations, type SchemaTables, type SelectQuery, type SelectQueryKind, type SelectQueryState, type Selectable, type SelectedFieldTypes, type SelectedOperandType, type SelectedRefs, type Selection, type SelectionFieldTypes, type SelectionResult, type SelectionState, type SelectionUses, type SingletonInsertMany, type SingletonQueryState, type SqlQuery, type SqlQueryState, type SqlStatement, type SqlTemplate, type StringAggOptions, type SynchronousResult, TRUE, type Table, type TableContext, type TableFactoryOptions, type TableKeys, type TableOptions, type TableQueryState, type TableRelations, type Tables, type TextConversionSignature, type TextLengthSignature, type TextOperators, type TextTypeOperators, type TextValue, type ToColumn, type ToColumns, type TransactionCoordinator, type TransactionFailure, type TransactionOptions, type TransformedQuery, type TransformedQueryState, type Type, type TypeInput, type TypeOperators, type TypeOptions, type TypeOutput, type TypeTransform, type TypedExpression, type TypedOperand, type TypedOperandInput, type TypedOperandOperators, type TypedScalarQuery, type UnfilteredAggregateOptions, type UnfilteredStringAggOptions, type UntypedExpression, type UpdateSet, type UpdateValues, type UpsertValues, type UsableRelation, type UsedRelation, type ValueRows, type ValuesQuery, type WhereCallback, type WhereCondition, type WhereFilter, type WhereValues, and, asc, avg, caseWhen, coalesce, compare, count, countDistinct, createDatabase, createStatement, createTableFactory, defineExpression, defineGenericOperator, defineHelper, defineSchema, defineTable, defineType, desc, equalityOperators, every, from, greatest, identifier, least, literal, many, matches, max, min, not, one, or, orderBy, orderingOperators, param, some, sql, stringAgg, sum, textOperators, toSnakeCase };
|
|
1
|
+
import { $ as TransformedQuery, $i as Column, $n as QueryContext, $r as Operand, $t as CaseValue, A as TypedExpression, Ai as defineTable, An as StringAggOptions, Ar as CombinedCondition, At as SelectionState, B as TransactionOptions, Bi as TransactionFailure, Bn as stringAgg, Br as OneValueRows, Bt as ConflictActionRequired, C as textOperators, Ci as Selectable, Cn as Literal, Cr as PrimaryKeyColumn, Ct as SchemaPartRelations, D as BaseOperators, Di as TableOptions, Dn as CountExpression, Dr as WhereCondition, Dt as AnyRecordQuery, E as AnyExpression, Ei as TableKeys, En as AggregateOptions, Er as WhereCallback, Et as defineSchema, F as DbMutationState, Fi as ResultRows, Fn as countDistinct, Fr as not, Ft as FieldTypes, Gi as Type, Gn as OrderTerm, Gr as CompileOptions, Gt as InsertMutationState, H as TransactionCoordinator, Hi as AnyType, Hn as OrderColumns, Hr as ResultByRows, Ht as ConflictTarget, I as DbOf, Ii as Connection, In as every, Ir as or, It as InitialSqlQueryState, Ji as TypeOptions, Jn as SelectedRefs, Jr as HasEquality, Jt as Helper, Ki as TypeInput, Kn as OrderTerms, Kr as EqualityOperator, Kt as MutationQuery, L as DbQueryState, Li as Driver, Ln as max, Lr as ExistsValueType, Lt as SqlQuery, M as AnyDb, Mi as RequiredRelationError, Mn as UnfilteredStringAggOptions, Mr as ConditionOperand, Mt as SelectQueryKind, N as BindOptions, Ni as ResultDecodeError, Nn as avg, Nr as Predicate, Nt as AnySqlQuery, O as Expression, Oi as ToColumns, On as GroupAggregateExpression, Or as WhereFilter, Ot as RecordQuery, P as Db, Pi as ResultMode, Pn as count, Pr as and, Pt as DecodedFields, Q as SynchronousResult, Qi as AnyColumn, Qn as ColumnRefs, Qr as ComparisonSignature, Qt as CaseCondition, R as Database, Ri as DriverResult, Rn as min, Rr as FilteredRows, Rt as SqlQueryState, S as TextTypeOperators, Si as KeyColumns, Sn as SelectionUses, Sr as NotAKey, St as SchemaPart, T as orderingOperators, Ti as TableFactoryOptions, Tn as AggregateExpression, Tr as EqValue, Tt as Tables, Ui as BaseType, Un as OrderDirection, Ur as ValueRows, Ut as InitialInsertState, V as createDatabase, Vi as createStatement, Vn as sum, Vr as QueryResult, Vt as ConflictKeyRequired, Wi as TextValue, Wn as OrderKey, Wr as CountValueType, Wt as InitialMutationState, X as AnyTransformedQuery, Xi as TypeTransform, Xn as desc, Xr as equalityOperators, Xt as defineHelper, Yi as TypeOutput, Yn as asc, Yr as InSignature, Yt as HelperEffect, Z as NotSynchronous, Zi as defineType, Zn as orderBy, Zr as BooleanResult, Zt as CaseBranch, _ as TRUE, _i as AnyTableKeys, _n as NestedQuery, _r as SelectedOperandType, _t as UsedRelation, a as sql, aa as NoOperators, ai as ValuesQuery, an as caseWhen, ar as SingletonInsertMany, at as Relation, b as TextLengthSignature, bi as ColumnShape, bn as SelectionFieldTypes, br as GroupTerms, bt as AnySchema, c as MatchResult, ca as GenericOperatorImplementation, ci as Grouped, cn as least, cr as ConflictUpdateSet, ct as RelationKey, d as defineExpression, di as QueryStateOf, dn as ExpressionValue, dr as UpdateValues, dt as RequiredMember, ea as ColumnAttributes, ei as OperandValue, en as FollowingOperand, er as RelationRefs, et as TransformedQueryState, f as ConnectionError, fi as QueryValueType, fn as GroupOperandValue, fr as UpsertValues, ft as SchemaContext, g as FALSE, gi as AnyTable, gn as MergeSelection, gr as GroupedState, gt as UsableRelation, h as toDriverError, hi as TableQueryState, hn as GroupedRecord, hr as FoundState, ht as TableRelations, i as param, ia as MergeOperators, ii as TypedScalarQuery, in as TypedOperandOperators, ir as SelectQuery, it as OneRelationKeys, j as UntypedExpression, ji as NotFoundError, jn as UnfilteredAggregateOptions, jr as Condition, jt as AnyQuery, k as ExpressionOperators, ki as createTableFactory, kn as GroupValue, kr as WhereValues, kt as RecordQueryState, l as NotAColumn, la as OperatorSignature, li as InitialQueryState, ln as ColumnFieldTypes, lr as InsertValues, lt as RelationKeys, m as QueryError, mi as SingletonQueryState, mn as GroupedField, mr as FoundQueryState, mt as TableContext, n as SqlTemplate, na as ToColumn, ni as OperandUses, nn as TypedOperand, nr as BoundSelectQuery, nt as MergeRelations, o as ColumnRefKey, oa as OperatorDefinitions, oi as EmptyRecord, on as coalesce, or as from, ot as RelationDeclaration, p as DriverErrorFields, pi as SelectQueryState, pn as GroupSelectionResult, pr as FilteredStateRows, pt as SchemaRelations, qi as TypeOperators, qn as Ordering, qr as EqualityOperators, qt as MutationQueryState, r as identifier, ra as BoundOperators, ri as ScalarQuery, rn as TypedOperandInput, rr as ResultOf, rt as NoRelations, s as MatchCheck, sa as GenericOperator, si as FoundKey, sn as greatest, sr as ColumnValue, st as RelationDeclarations, t as toSnakeCase, ta as KeyKind, ti as compare, tn as NullSkippingResult, tr as AnySelectQuery, tt as DeclaredRelations, u as matches, ua as defineGenericOperator, ui as QueryState, un as ExpressionInput, ur as UpdateSet, ut as RelationKind, v as PatternSignature, vi as ColumnDefinitions, vn as SelectedFieldTypes, vr as RowLockOptions, vt as many, w as NumberTypeOperators, wi as Table, wn as literal, wr as PrimaryKeyValues, wt as SchemaTables, x as TextOperators, xi as ColumnValues, xn as SelectionResult, xr as KeyCheck, xt as Schema, y as TextConversionSignature, yi as ColumnOperators, yn as Selection, yr as GroupTerm, yt as one, z as DatabaseOptions, zi as SqlStatement, zn as some, zr as OneRow, zt as AnyMutationQuery } from "./index-B1aH5Ht0.mjs";
|
|
2
|
+
export { type AggregateExpression, type AggregateOptions, type AnyColumn, type AnyDb, type AnyExpression, type AnyMutationQuery, type AnyQuery, type AnyRecordQuery, type AnySchema, type AnySelectQuery, type AnySqlQuery, type AnyTable, type AnyTableKeys, type AnyTransformedQuery, type AnyType, type BaseOperators, type BaseType, type BindOptions, type BooleanResult, type BoundOperators, type BoundSelectQuery, type CaseBranch, type CaseCondition, type CaseValue, type Column, type ColumnAttributes, type ColumnDefinitions, type ColumnFieldTypes, type ColumnOperators, type ColumnRefKey, type ColumnRefs, type ColumnShape, type ColumnValue, type ColumnValues, type CombinedCondition, type ComparisonSignature, type CompileOptions, type Condition, type ConditionOperand, type ConflictActionRequired, type ConflictKeyRequired, type ConflictTarget, type ConflictUpdateSet, type Connection, ConnectionError, type CountExpression, type CountValueType, type Database, type DatabaseOptions, type Db, type DbMutationState, type DbOf, type DbQueryState, type DeclaredRelations, type DecodedFields, type Driver, type DriverErrorFields, type DriverResult, type EmptyRecord, type EqValue, type EqualityOperator, type EqualityOperators, type ExistsValueType, type Expression, type ExpressionInput, type ExpressionOperators, type ExpressionValue, FALSE, type FieldTypes, type FilteredRows, type FilteredStateRows, type FollowingOperand, type FoundKey, type FoundQueryState, type FoundState, type GenericOperator, type GenericOperatorImplementation, type GroupAggregateExpression, type GroupOperandValue, type GroupSelectionResult, type GroupTerm, type GroupTerms, type GroupValue, type Grouped, type GroupedField, type GroupedRecord, type GroupedState, type HasEquality, type Helper, type HelperEffect, type InSignature, type InitialInsertState, type InitialMutationState, type InitialQueryState, type InitialSqlQueryState, type InsertMutationState, type InsertValues, type KeyCheck, type KeyColumns, type KeyKind, type Literal, type MatchCheck, type MatchResult, type MergeOperators, type MergeRelations, type MergeSelection, type MutationQuery, type MutationQueryState, type NestedQuery, type NoOperators, type NoRelations, type NotAColumn, type NotAKey, NotFoundError, type NotSynchronous, type NullSkippingResult, type NumberTypeOperators, type OneRelationKeys, type OneRow, type OneValueRows, type Operand, type OperandUses, type OperandValue, type OperatorDefinitions, type OperatorSignature, type OrderColumns, type OrderDirection, type OrderKey, type OrderTerm, type OrderTerms, type Ordering, type PatternSignature, type Predicate, type PrimaryKeyColumn, type PrimaryKeyValues, type QueryContext, QueryError, type QueryResult, type QueryState, type QueryStateOf, type QueryValueType, type RecordQuery, type RecordQueryState, type Relation, type RelationDeclaration, type RelationDeclarations, type RelationKey, type RelationKeys, type RelationKind, type RelationRefs, type RequiredMember, RequiredRelationError, type ResultByRows, ResultDecodeError, type ResultMode, type ResultOf, type ResultRows, type RowLockOptions, type ScalarQuery, type Schema, type SchemaContext, type SchemaPart, type SchemaPartRelations, type SchemaRelations, type SchemaTables, type SelectQuery, type SelectQueryKind, type SelectQueryState, type Selectable, type SelectedFieldTypes, type SelectedOperandType, type SelectedRefs, type Selection, type SelectionFieldTypes, type SelectionResult, type SelectionState, type SelectionUses, type SingletonInsertMany, type SingletonQueryState, type SqlQuery, type SqlQueryState, type SqlStatement, type SqlTemplate, type StringAggOptions, type SynchronousResult, TRUE, type Table, type TableContext, type TableFactoryOptions, type TableKeys, type TableOptions, type TableQueryState, type TableRelations, type Tables, type TextConversionSignature, type TextLengthSignature, type TextOperators, type TextTypeOperators, type TextValue, type ToColumn, type ToColumns, type TransactionCoordinator, type TransactionFailure, type TransactionOptions, type TransformedQuery, type TransformedQueryState, type Type, type TypeInput, type TypeOperators, type TypeOptions, type TypeOutput, type TypeTransform, type TypedExpression, type TypedOperand, type TypedOperandInput, type TypedOperandOperators, type TypedScalarQuery, type UnfilteredAggregateOptions, type UnfilteredStringAggOptions, type UntypedExpression, type UpdateSet, type UpdateValues, type UpsertValues, type UsableRelation, type UsedRelation, type ValueRows, type ValuesQuery, type WhereCallback, type WhereCondition, type WhereFilter, type WhereValues, and, asc, avg, caseWhen, coalesce, compare, count, countDistinct, createDatabase, createStatement, createTableFactory, defineExpression, defineGenericOperator, defineHelper, defineSchema, defineTable, defineType, desc, equalityOperators, every, from, greatest, identifier, least, literal, many, matches, max, min, not, one, or, orderBy, orderingOperators, param, some, sql, stringAgg, sum, textOperators, toDriverError, toSnakeCase };
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { B as noOrder, C as toNode, D as isType, E as defineType, F as createNode, L as falseNode, N as defineGenericOperator, P as createList, S as toFunctionOperandNode, T as getBooleanType, U as trueNode, _ as isOperandSource, b as toCastValueNode, c as textOperators, d as orderingOperators, f as compare, g as isExpression, h as getType, k as equalityOperators, v as operandNode, x as toExpression, y as toBooleanExpression } from "./text-CIUxPWPl.mjs";
|
|
2
|
-
import { A as
|
|
2
|
+
import { A as literal, C as RequiredRelationError, D as createAggregateCall, E as countType, F as combineNodes, M as isColumnValues, N as not, O as createCountCall, P as or, S as NotFoundError, T as countProjection, _ as many, a as identifier, b as createTableFactory, c as defineSchema, d as requireDerived, f as addTerms, g as matchColumn, h as orderBy, i as createDatabase, j as and, k as toAggregateType, l as SelectQuery, m as desc, n as QueryError, o as param, p as asc, r as toDriverError, s as sql, t as ConnectionError, u as from, v as one, w as ResultDecodeError, x as defineTable, y as createStatement } from "./driver-error-Dx5R83Rp.mjs";
|
|
3
3
|
// src/expression/constants.ts
|
|
4
4
|
/** Condition that always holds, such as for a branch of `and` built in code: `and(check, isAdmin ? TRUE : other)`. */
|
|
5
5
|
const TRUE = /* @__PURE__ */ toExpression(trueNode, /* @__PURE__ */ getBooleanType());
|
|
@@ -157,4 +157,4 @@ const wordStart = /(?<=[\p{Ll}\p{N}])(?=\p{Lu})|(?<=\p{Lu})(?=\p{Lu}(?!s$)\p{Ll}
|
|
|
157
157
|
function toSnakeCase(key) {
|
|
158
158
|
return key.replace(wordStart, "_").toLowerCase();
|
|
159
159
|
}
|
|
160
|
-
export { FALSE, NotFoundError, RequiredRelationError, ResultDecodeError, TRUE, and, asc, avg, caseWhen, coalesce, compare, count, countDistinct, createDatabase, createStatement, createTableFactory, defineExpression, defineGenericOperator, defineHelper, defineSchema, defineTable, defineType, desc, equalityOperators, every, from, greatest, identifier, least, literal, many, matches, max, min, not, one, or, orderBy, orderingOperators, param, some, sql, stringAgg, sum, textOperators, toSnakeCase };
|
|
160
|
+
export { ConnectionError, FALSE, NotFoundError, QueryError, RequiredRelationError, ResultDecodeError, TRUE, and, asc, avg, caseWhen, coalesce, compare, count, countDistinct, createDatabase, createStatement, createTableFactory, defineExpression, defineGenericOperator, defineHelper, defineSchema, defineTable, defineType, desc, equalityOperators, every, from, greatest, identifier, least, literal, many, matches, max, min, not, one, or, orderBy, orderingOperators, param, some, sql, stringAgg, sum, textOperators, toDriverError, toSnakeCase };
|
package/dist/testing.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { G as TestFixture, J as TestTransactionOptions, K as TestHelpers, Li as Driver, U as OpenedTestFixture, W as PendingTestFixture, Y as createTestHelpers, q as TestHooks } from "./index-B1aH5Ht0.mjs";
|
|
2
2
|
/** Options of `describeDriverContract`: how to create the driver under test. */
|
|
3
3
|
interface DriverContractOptions {
|
|
4
4
|
/** Creates a driver over a new client of the test database with `max` connections. */
|
|
@@ -7,8 +7,6 @@ interface DriverContractOptions {
|
|
|
7
7
|
}): Driver;
|
|
8
8
|
/** Creates a driver over a new client of the test database whose parsers of result values throw; for a client without parsers, the same as `createDriver`. */
|
|
9
9
|
createDriverWithFailingParsers(): Driver;
|
|
10
|
-
/** Whether the client can close a reserved connection, so that the driver gets rid of a connection left in a transaction or lost; `false` leaves out the tests of it. */
|
|
11
|
-
closesReservedConnections: boolean;
|
|
12
10
|
}
|
|
13
11
|
/**
|
|
14
12
|
* Functions of a test runner that declare the tests of `describeDriverContract`.
|
package/dist/testing.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as text, t as char } from "./text-CIUxPWPl.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { c as defineSchema, i as createDatabase, j as and, n as QueryError, o as param, s as sql, t as ConnectionError, x as defineTable, y as createStatement } from "./driver-error-Dx5R83Rp.mjs";
|
|
3
3
|
import { _ as timestamptz, a as numeric, b as array, d as jsonb, f as enumOf, g as timestamp, h as time, i as integer, l as inet, m as interval, n as bigint, p as date, r as doublePrecision, t as uuid, v as boolean, y as bytea } from "./types-D3d35qR2.mjs";
|
|
4
4
|
import assert from "node:assert/strict";
|
|
5
5
|
// src/execution/testing.ts
|
|
@@ -36,14 +36,14 @@ function createTestHelpers(database, hooks) {
|
|
|
36
36
|
};
|
|
37
37
|
}
|
|
38
38
|
// src/execution/driver-contract.ts
|
|
39
|
-
/** Creates helpers that run raw statements on `database
|
|
40
|
-
function createStatementRunners(
|
|
39
|
+
/** Creates helpers that run raw statements on `target`: a database, a driver, or a reserved connection. */
|
|
40
|
+
function createStatementRunners(target) {
|
|
41
41
|
return {
|
|
42
42
|
async runStatement(text) {
|
|
43
|
-
await
|
|
43
|
+
await target.execute(createStatement(text));
|
|
44
44
|
},
|
|
45
45
|
async selectValue(text, parameters = []) {
|
|
46
|
-
const { rows } = await
|
|
46
|
+
const { rows } = await target.execute(createStatement(text, parameters));
|
|
47
47
|
return rows[0][0];
|
|
48
48
|
}
|
|
49
49
|
};
|
|
@@ -54,12 +54,14 @@ function createStatementRunners(database) {
|
|
|
54
54
|
* They run in the empty database of its clients and leave it unchanged.
|
|
55
55
|
*/
|
|
56
56
|
function describeDriverContract(options, runner) {
|
|
57
|
-
const { createDriver, createDriverWithFailingParsers
|
|
57
|
+
const { createDriver, createDriverWithFailingParsers } = options;
|
|
58
58
|
const { describe, it, before, after } = runner;
|
|
59
59
|
describe("driver contract", () => {
|
|
60
|
-
const
|
|
60
|
+
const driver = createDriver({ max: 2 });
|
|
61
|
+
const database = createDatabase({ driver });
|
|
61
62
|
after(() => database.close());
|
|
62
63
|
const { runStatement, selectValue } = createStatementRunners(database);
|
|
64
|
+
const { selectValue: selectValueOnDriver } = createStatementRunners(driver);
|
|
63
65
|
it("executes a query in a transaction", async () => {
|
|
64
66
|
const tag = defineTable("pg_tag_test", {
|
|
65
67
|
id: integer,
|
|
@@ -91,6 +93,18 @@ function describeDriverContract(options, runner) {
|
|
|
91
93
|
await database.script("SET LOCAL client_min_messages = warning; DROP TABLE IF EXISTS pg_statement_test");
|
|
92
94
|
}
|
|
93
95
|
});
|
|
96
|
+
it("returns every value as text", async () => {
|
|
97
|
+
const { rows } = await driver.execute(createStatement(`SELECT 42::integer, 12345678901234::bigint, true, '{"a":1}'::jsonb, NULL::text, ARRAY['a', 'b'], '2030-01-01 12:00'::timestamp`));
|
|
98
|
+
assert.deepEqual(rows, [[
|
|
99
|
+
"42",
|
|
100
|
+
"12345678901234",
|
|
101
|
+
"t",
|
|
102
|
+
"{\"a\": 1}",
|
|
103
|
+
null,
|
|
104
|
+
"{a,b}",
|
|
105
|
+
"2030-01-01 12:00:00"
|
|
106
|
+
]]);
|
|
107
|
+
});
|
|
94
108
|
it("keeps the values of a statement as text without the parsers of the client", async () => {
|
|
95
109
|
const parsed = createDatabase({ driver: createDriverWithFailingParsers() });
|
|
96
110
|
try {
|
|
@@ -110,7 +124,7 @@ function describeDriverContract(options, runner) {
|
|
|
110
124
|
});
|
|
111
125
|
it("executes a script on the pool in one implicit transaction", async () => {
|
|
112
126
|
try {
|
|
113
|
-
await assert.rejects(database.script("CREATE TABLE pg_script_pool_test (id integer); SELECT 1/0"),
|
|
127
|
+
await assert.rejects(database.script("CREATE TABLE pg_script_pool_test (id integer); SELECT 1/0"), (error) => error instanceof QueryError && error.code === "22012");
|
|
114
128
|
assert.equal(await selectValue("SELECT to_regclass('pg_script_pool_test')::text"), null);
|
|
115
129
|
} finally {
|
|
116
130
|
await database.script("SET LOCAL client_min_messages = warning; DROP TABLE IF EXISTS pg_script_pool_test");
|
|
@@ -156,6 +170,10 @@ function describeDriverContract(options, runner) {
|
|
|
156
170
|
assert.equal(await selectValue("SELECT $1", ["text"]), "text");
|
|
157
171
|
assert.equal(await selectValue("SELECT $1::text IS NULL", [null]), "t");
|
|
158
172
|
});
|
|
173
|
+
it("sends a parameter as it is, whatever type PostgreSQL describes for it", async () => {
|
|
174
|
+
assert.equal(await selectValueOnDriver("SELECT $1::boolean", ["true"]), "t");
|
|
175
|
+
assert.equal(await selectValueOnDriver("SELECT $1::jsonb ->> 'a'", ["{\"a\":\"x\"}"]), "x");
|
|
176
|
+
});
|
|
159
177
|
it("runs concurrent statements of a transaction in the order of calls", async () => {
|
|
160
178
|
const values = await database.transaction(() => Promise.all([
|
|
161
179
|
selectValue("SELECT set_config('kern.test', '1', true) FROM pg_sleep(0.05)"),
|
|
@@ -170,6 +188,32 @@ function describeDriverContract(options, runner) {
|
|
|
170
188
|
"2"
|
|
171
189
|
]);
|
|
172
190
|
});
|
|
191
|
+
it("runs the statements sent on a reserved connection before ROLLBACK inside its transaction", async () => {
|
|
192
|
+
const own = createDriver({ max: 1 });
|
|
193
|
+
try {
|
|
194
|
+
const connection = await own.acquire();
|
|
195
|
+
const { runStatement, selectValue } = createStatementRunners(connection);
|
|
196
|
+
let failure;
|
|
197
|
+
try {
|
|
198
|
+
await runStatement("CREATE TEMP TABLE pg_order_test (id integer)");
|
|
199
|
+
await runStatement("BEGIN");
|
|
200
|
+
await Promise.all([
|
|
201
|
+
runStatement("INSERT INTO pg_order_test VALUES (1)"),
|
|
202
|
+
runStatement("SELECT pg_sleep(0.05)"),
|
|
203
|
+
runStatement("INSERT INTO pg_order_test VALUES (2)"),
|
|
204
|
+
runStatement("ROLLBACK")
|
|
205
|
+
]);
|
|
206
|
+
assert.equal(await selectValue("SELECT count(*) FROM pg_order_test"), "0");
|
|
207
|
+
} catch (error) {
|
|
208
|
+
failure = { error };
|
|
209
|
+
throw error;
|
|
210
|
+
} finally {
|
|
211
|
+
await connection.release(failure);
|
|
212
|
+
}
|
|
213
|
+
} finally {
|
|
214
|
+
await own.close();
|
|
215
|
+
}
|
|
216
|
+
});
|
|
173
217
|
it("decodes selected expressions with their types", async () => {
|
|
174
218
|
const tag = defineTable("pg_tag_test", {
|
|
175
219
|
id: integer,
|
|
@@ -201,6 +245,33 @@ function describeDriverContract(options, runner) {
|
|
|
201
245
|
length: null
|
|
202
246
|
}]);
|
|
203
247
|
});
|
|
248
|
+
it("rejects a statement that PostgreSQL rejected with QueryError and keeps its connection, on the pool and on a reserved connection", async () => {
|
|
249
|
+
const own = createDriver({ max: 1 });
|
|
250
|
+
try {
|
|
251
|
+
const pool = createStatementRunners(own);
|
|
252
|
+
await pool.runStatement("CREATE TEMP TABLE pg_unique_test (id integer CONSTRAINT pg_unique_test_key UNIQUE)");
|
|
253
|
+
await pool.runStatement("INSERT INTO pg_unique_test VALUES (1)");
|
|
254
|
+
const pid = await pool.selectValue("SELECT pg_backend_pid()");
|
|
255
|
+
/** Asserts that inserting a duplicate on `target` rejects with the violated constraint, and that its connection stays the same. */
|
|
256
|
+
async function assertRejected(target) {
|
|
257
|
+
const runners = createStatementRunners(target);
|
|
258
|
+
const error = await runners.runStatement("INSERT INTO pg_unique_test VALUES (1)").catch((error) => error);
|
|
259
|
+
assert.ok(error instanceof QueryError, `Expected QueryError, got ${String(error)}`);
|
|
260
|
+
assert.equal(error.code, "23505");
|
|
261
|
+
assert.equal(error.constraint, "pg_unique_test_key");
|
|
262
|
+
assert.equal(await runners.selectValue("SELECT pg_backend_pid()"), pid);
|
|
263
|
+
}
|
|
264
|
+
await assertRejected(own);
|
|
265
|
+
const connection = await own.acquire();
|
|
266
|
+
try {
|
|
267
|
+
await assertRejected(connection);
|
|
268
|
+
} finally {
|
|
269
|
+
await connection.release();
|
|
270
|
+
}
|
|
271
|
+
} finally {
|
|
272
|
+
await own.close();
|
|
273
|
+
}
|
|
274
|
+
});
|
|
204
275
|
it("rejects a transaction whose failed statement the callback caught", async () => {
|
|
205
276
|
const transaction = database.transaction(async () => {
|
|
206
277
|
await runStatement("SELECT 1/0").catch(() => {});
|
|
@@ -233,7 +304,7 @@ function describeDriverContract(options, runner) {
|
|
|
233
304
|
await driver.close();
|
|
234
305
|
}
|
|
235
306
|
});
|
|
236
|
-
if (closesReservedConnections) {
|
|
307
|
+
if (driver.closesReservedConnections) {
|
|
237
308
|
for (const [state, text] of [["an open", "SELECT 1"], ["a failed", "SELECT 1/0"]]) it(`does not return a connection in ${state} transaction to the pool`, async () => {
|
|
238
309
|
const driver = createDriver({ max: 1 });
|
|
239
310
|
try {
|
|
@@ -261,7 +332,48 @@ function describeDriverContract(options, runner) {
|
|
|
261
332
|
await single.close();
|
|
262
333
|
}
|
|
263
334
|
});
|
|
335
|
+
it("rejects a statement of a transaction whose connection is lost with ConnectionError", async () => {
|
|
336
|
+
const own = createDriver({ max: 1 });
|
|
337
|
+
try {
|
|
338
|
+
const connection = await own.acquire();
|
|
339
|
+
const { runStatement, selectValue: selectValueOnConnection } = createStatementRunners(connection);
|
|
340
|
+
let failure;
|
|
341
|
+
try {
|
|
342
|
+
await runStatement("BEGIN");
|
|
343
|
+
await runStatement("CREATE TEMP TABLE pg_lost_test (id integer) ON COMMIT DROP");
|
|
344
|
+
const pid = await selectValueOnConnection("SELECT pg_backend_pid()");
|
|
345
|
+
assert.equal(await selectValue("SELECT pg_terminate_backend($1, 5000)", [pid]), "t");
|
|
346
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
347
|
+
const error = await runStatement("INSERT INTO pg_lost_test VALUES (1)").catch((error) => error);
|
|
348
|
+
failure = { error };
|
|
349
|
+
assert.ok(error instanceof ConnectionError, `Expected ConnectionError, got ${String(error)}`);
|
|
350
|
+
} catch (error) {
|
|
351
|
+
failure ??= { error };
|
|
352
|
+
throw error;
|
|
353
|
+
} finally {
|
|
354
|
+
await connection.release(failure);
|
|
355
|
+
}
|
|
356
|
+
} finally {
|
|
357
|
+
await own.close();
|
|
358
|
+
}
|
|
359
|
+
});
|
|
264
360
|
}
|
|
361
|
+
it("replaces an idle connection whose backend exited", async () => {
|
|
362
|
+
const own = createDriver({ max: 2 });
|
|
363
|
+
const held = [];
|
|
364
|
+
try {
|
|
365
|
+
for (let count = 0; count < 2; count++) held.push(await own.acquire());
|
|
366
|
+
const pids = [];
|
|
367
|
+
for (const connection of held) pids.push(await createStatementRunners(connection).selectValue("SELECT pg_backend_pid()"));
|
|
368
|
+
while (held.length > 0) await held.shift().release();
|
|
369
|
+
for (const pid of pids) assert.equal(await selectValue("SELECT pg_terminate_backend($1, 5000)", [pid]), "t");
|
|
370
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
371
|
+
assert.equal(await createStatementRunners(own).selectValue("SELECT 'usable'"), "usable");
|
|
372
|
+
} finally {
|
|
373
|
+
await Promise.allSettled(held.map(async (connection) => connection.release()));
|
|
374
|
+
await own.close();
|
|
375
|
+
}
|
|
376
|
+
});
|
|
265
377
|
it("isolates concurrent transactions on their own connections", async () => {
|
|
266
378
|
const bothStarted = Promise.withResolvers();
|
|
267
379
|
let startedCount = 0;
|
|
@@ -353,15 +465,15 @@ function describeDriverContract(options, runner) {
|
|
|
353
465
|
assert.equal(await query, "slept");
|
|
354
466
|
assert.deepEqual(settled, ["query", "database"]);
|
|
355
467
|
});
|
|
356
|
-
it("rejects a statement, a script, and a connection requested right after it starts", async () => {
|
|
468
|
+
it("rejects a statement, a script, and a connection requested right after it starts with ConnectionError", async () => {
|
|
357
469
|
const driver = createDriver({ max: 1 });
|
|
358
470
|
const held = await driver.acquire();
|
|
359
471
|
const closing = driver.close();
|
|
360
472
|
const acquiring = driver.acquire();
|
|
361
473
|
const rejections = [
|
|
362
|
-
assert.rejects(driver.execute(createStatement("SELECT 1"))),
|
|
363
|
-
assert.rejects(driver.executeScript("SELECT 1")),
|
|
364
|
-
assert.rejects(acquiring)
|
|
474
|
+
assert.rejects(driver.execute(createStatement("SELECT 1")), ConnectionError),
|
|
475
|
+
assert.rejects(driver.executeScript("SELECT 1"), ConnectionError),
|
|
476
|
+
assert.rejects(acquiring, ConnectionError)
|
|
365
477
|
];
|
|
366
478
|
acquiring.then((connection) => connection.release()).catch(() => {});
|
|
367
479
|
await held.release();
|
package/dist/types.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { E as AnyExpression, Gi as Type, Jr as HasEquality, Kr as EqualityOperator, Qr as ComparisonSignature, S as TextTypeOperators, Ui as BaseType, Yr as InSignature, aa as NoOperators, ia as MergeOperators, oa as OperatorDefinitions, qr as EqualityOperators, sa as GenericOperator, w as NumberTypeOperators, x as TextOperators } from "./index-B1aH5Ht0.mjs";
|
|
2
2
|
/**
|
|
3
3
|
* Creates a one-dimensional array type of `element` values.
|
|
4
4
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kern-orm",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Fully typed relational query builder for PostgreSQL with ambient transactions and single-query relation loading",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"orm",
|
|
@@ -42,13 +42,7 @@
|
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"@kern-orm/postgres-js": "workspace:*",
|
|
45
|
-
"kern-orm-0.2.0": "https://registry.npmjs.org/kern-orm/-/kern-orm-0.2.0.tgz",
|
|
46
|
-
"kern-orm-0.3.0": "https://registry.npmjs.org/kern-orm/-/kern-orm-0.3.0.tgz",
|
|
47
|
-
"migrations-published": "https://registry.npmjs.org/@kern-orm/migrations/-/migrations-0.3.1.tgz",
|
|
48
|
-
"node-postgres-published": "https://registry.npmjs.org/@kern-orm/node-postgres/-/node-postgres-0.1.0.tgz",
|
|
49
45
|
"postgres": "catalog:",
|
|
50
|
-
"postgres-js-published": "https://registry.npmjs.org/@kern-orm/postgres-js/-/postgres-js-0.1.2.tgz",
|
|
51
|
-
"postgres-js-v3-published": "https://registry.npmjs.org/@kern-orm/postgres-js-v3/-/postgres-js-v3-0.1.2.tgz",
|
|
52
46
|
"typescript-6": "catalog:"
|
|
53
47
|
},
|
|
54
48
|
"engines": {
|