relq 1.0.116 → 1.0.117

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.
@@ -16,6 +16,7 @@ const network_condition_builder_1 = require("./network-condition-builder.cjs");
16
16
  const postgis_condition_builder_1 = require("./postgis-condition-builder.cjs");
17
17
  class ConditionCollector {
18
18
  conditions = [];
19
+ _tables;
19
20
  _jsonb;
20
21
  _array;
21
22
  _fulltext;
@@ -229,11 +230,23 @@ class ConditionCollector {
229
230
  return this.isNotNull(column);
230
231
  }
231
232
  in(column, values) {
232
- this.conditions.push({ method: 'in', column, values });
233
+ if (typeof values === 'function') {
234
+ const subquery = values(this._tables);
235
+ this.conditions.push({ method: 'in', column, values: subquery.toString() });
236
+ }
237
+ else {
238
+ this.conditions.push({ method: 'in', column, values });
239
+ }
233
240
  return this;
234
241
  }
235
242
  notIn(column, values) {
236
- this.conditions.push({ method: 'notIn', column, values });
243
+ if (typeof values === 'function') {
244
+ const subquery = values(this._tables);
245
+ this.conditions.push({ method: 'notIn', column, values: subquery.toString() });
246
+ }
247
+ else {
248
+ this.conditions.push({ method: 'notIn', column, values });
249
+ }
237
250
  return this;
238
251
  }
239
252
  exists(subquery) {
@@ -398,11 +411,17 @@ function buildConditionSQL(condition) {
398
411
  return `(${startCol}, ${endCol}) OVERLAPS (${(0, pg_format_1.default)('%L', startVal)}, ${(0, pg_format_1.default)('%L', endVal)})`;
399
412
  }
400
413
  case 'in': {
414
+ if (typeof values === 'string') {
415
+ return `${col} IN (${values})`;
416
+ }
401
417
  const valueList = Array.isArray(values) ? values : [values];
402
418
  const formattedValues = valueList.map(v => (0, pg_format_1.default)('%L', v)).join(', ');
403
419
  return `${col} IN (${formattedValues})`;
404
420
  }
405
421
  case 'notIn': {
422
+ if (typeof values === 'string') {
423
+ return `${col} NOT IN (${values})`;
424
+ }
406
425
  const valueList = Array.isArray(values) ? values : [values];
407
426
  const formattedValues = valueList.map(v => (0, pg_format_1.default)('%L', v)).join(', ');
408
427
  return `${col} NOT IN (${formattedValues})`;
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ConnectedAggregateBuilder = void 0;
4
4
  const methods_1 = require("./methods.cjs");
5
+ const table_accessor_1 = require("../shared/table-accessor.cjs");
5
6
  class ConnectedAggregateBuilder {
6
7
  builder;
7
8
  relq;
@@ -73,7 +74,10 @@ class ConnectedAggregateBuilder {
73
74
  return this;
74
75
  }
75
76
  where(callback) {
76
- this.builder.where(callback);
77
+ this.builder.where((q) => {
78
+ q._tables = (0, table_accessor_1.createTableAccessor)(this.relq, this.relq.schema);
79
+ return callback(q);
80
+ });
77
81
  return this;
78
82
  }
79
83
  having(callback) {
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ConnectedCountBuilder = void 0;
4
4
  const methods_1 = require("./methods.cjs");
5
+ const table_accessor_1 = require("../shared/table-accessor.cjs");
5
6
  class ConnectedCountBuilder {
6
7
  builder;
7
8
  relq;
@@ -22,6 +23,7 @@ class ConnectedCountBuilder {
22
23
  }
23
24
  where(callback) {
24
25
  this.builder.where((q) => {
26
+ q._tables = (0, table_accessor_1.createTableAccessor)(this.relq, this.relq.schema);
25
27
  const wrapped = this.wrapConditionBuilder(q);
26
28
  return callback(wrapped);
27
29
  });
@@ -4,6 +4,7 @@ exports.ConnectedDeleteBuilder = void 0;
4
4
  const methods_1 = require("./methods.cjs");
5
5
  const ReturningExecutor_1 = require("./ReturningExecutor.cjs");
6
6
  const capability_guard_1 = require("./capability-guard.cjs");
7
+ const table_accessor_1 = require("../shared/table-accessor.cjs");
7
8
  class ConnectedDeleteBuilder {
8
9
  builder;
9
10
  relq;
@@ -35,7 +36,10 @@ class ConnectedDeleteBuilder {
35
36
  });
36
37
  }
37
38
  where(callback) {
38
- this.builder.where(callback);
39
+ this.builder.where((q) => {
40
+ q._tables = (0, table_accessor_1.createTableAccessor)(this.relq, this.relq.schema);
41
+ return callback(q);
42
+ });
39
43
  return this;
40
44
  }
41
45
  toString() {
@@ -5,6 +5,7 @@ const methods_1 = require("./methods.cjs");
5
5
  const select_joins_1 = require("./select-joins.cjs");
6
6
  const select_pagination_1 = require("./select-pagination.cjs");
7
7
  const capability_guard_1 = require("./capability-guard.cjs");
8
+ const table_accessor_1 = require("../shared/table-accessor.cjs");
8
9
  const sql_expression_1 = require("../../select/sql-expression.cjs");
9
10
  const table_proxy_1 = require("../../select/table-proxy.cjs");
10
11
  const fk_resolver_1 = require("../../utils/fk-resolver.cjs");
@@ -116,7 +117,10 @@ class ConnectedSelectBuilder {
116
117
  }
117
118
  }
118
119
  where(callback) {
119
- this.builder.where(callback);
120
+ this.builder.where((q) => {
121
+ q._tables = (0, table_accessor_1.createTableAccessor)(this.relq, this.relq.schema);
122
+ return callback(q);
123
+ });
120
124
  return this;
121
125
  }
122
126
  orderBy(column, direction) {
@@ -1,44 +1,103 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ConnectedTransactionBuilder = void 0;
4
- const transaction_builder_1 = require("../../transaction/transaction-builder.cjs");
3
+ exports.TransactionClient = void 0;
4
+ exports.executeTransaction = executeTransaction;
5
+ const ConnectedRawQueryBuilder_1 = require("./ConnectedRawQueryBuilder.cjs");
6
+ const table_accessor_1 = require("../shared/table-accessor.cjs");
5
7
  const methods_1 = require("./methods.cjs");
6
- class ConnectedTransactionBuilder {
8
+ class TransactionClient {
9
+ client;
7
10
  relq;
8
- constructor(relq) {
11
+ schema;
12
+ constructor(client, relq) {
13
+ this.client = client;
9
14
  this.relq = relq;
15
+ const internal = this.relq[methods_1.INTERNAL];
16
+ this.schema = internal.getSchema?.() ?? this.relq.schema;
10
17
  }
11
- builder = new transaction_builder_1.TransactionBuilder();
12
- toString() {
13
- return this.builder.toString();
18
+ get table() {
19
+ return (0, table_accessor_1.createTableAccessor)(this, this.schema);
14
20
  }
15
- async begin() {
16
- const sql = this.builder.toString();
17
- return this.relq[methods_1.INTERNAL].executeRun(sql);
21
+ raw(query, ...params) {
22
+ return new ConnectedRawQueryBuilder_1.ConnectedRawQueryBuilder(query, params, this);
18
23
  }
19
- async commit() {
20
- const sql = this.builder.commit();
21
- return this.relq[methods_1.INTERNAL].executeRun(sql);
24
+ get [methods_1.INTERNAL]() {
25
+ const parentInternal = this.relq[methods_1.INTERNAL];
26
+ const queryViaClient = async (sql) => {
27
+ const start = performance.now();
28
+ const pgResult = await this.client.query(sql);
29
+ return {
30
+ result: {
31
+ rows: pgResult.rows,
32
+ rowCount: pgResult.rowCount,
33
+ command: pgResult.command,
34
+ fields: pgResult.fields?.map((f) => ({ name: f.name, dataTypeID: f.dataTypeID })) ?? [],
35
+ },
36
+ duration: performance.now() - start,
37
+ };
38
+ };
39
+ const buildMetadata = (result, duration) => ({
40
+ rowCount: result.rowCount,
41
+ command: result.command,
42
+ duration,
43
+ fields: result.fields,
44
+ });
45
+ return {
46
+ executeQuery: queryViaClient,
47
+ async executeSelect(sql, tableName) {
48
+ const { result, duration } = await queryViaClient(sql);
49
+ const rows = tableName
50
+ ? parentInternal.transformResultsFromDb(tableName, result.rows)
51
+ : result.rows;
52
+ return { data: rows, metadata: buildMetadata(result, duration) };
53
+ },
54
+ async executeSelectOne(sql, tableName) {
55
+ const { result, duration } = await queryViaClient(sql);
56
+ const row = result.rows[0]
57
+ ? (tableName ? parentInternal.transformFromDbColumns(tableName, result.rows[0]) : result.rows[0])
58
+ : null;
59
+ return { data: row, metadata: buildMetadata(result, duration) };
60
+ },
61
+ async executeCount(sql) {
62
+ const { result, duration } = await queryViaClient(sql);
63
+ const count = result.rows[0]?.count ? parseInt(result.rows[0].count, 10) : 0;
64
+ return { count, metadata: buildMetadata(result, duration) };
65
+ },
66
+ async executeRun(sql) {
67
+ const { result, duration } = await queryViaClient(sql);
68
+ return { success: true, metadata: buildMetadata(result, duration) };
69
+ },
70
+ transformToDbColumns: parentInternal.transformToDbColumns,
71
+ transformFromDbColumns: parentInternal.transformFromDbColumns,
72
+ transformResultsFromDb: parentInternal.transformResultsFromDb,
73
+ hasColumnMapping: parentInternal.hasColumnMapping,
74
+ validateData: parentInternal.validateData,
75
+ getSchema: parentInternal.getSchema,
76
+ getRelations: parentInternal.getRelations,
77
+ getTableDef: parentInternal.getTableDef,
78
+ getClientForCursor: async () => ({ client: this.client, release: () => { } }),
79
+ };
22
80
  }
23
- async rollback() {
24
- const sql = this.builder.rollback();
25
- return this.relq[methods_1.INTERNAL].executeRun(sql);
26
- }
27
- isolationLevel(level) {
28
- this.builder.isolation(level);
29
- return this;
30
- }
31
- readOnly() {
32
- this.builder.readOnly();
33
- return this;
81
+ }
82
+ exports.TransactionClient = TransactionClient;
83
+ async function executeTransaction(relq, callback) {
84
+ await relq.ensureInitialized();
85
+ const { client, release } = await relq[methods_1.INTERNAL].getClientForCursor();
86
+ try {
87
+ await client.query('BEGIN');
88
+ const tx = new TransactionClient(client, relq);
89
+ const result = await callback(tx);
90
+ await client.query('COMMIT');
91
+ return result;
34
92
  }
35
- readWrite() {
36
- this.builder.readWrite();
37
- return this;
93
+ catch (error) {
94
+ try {
95
+ await client.query('ROLLBACK');
96
+ }
97
+ catch { }
98
+ throw error;
38
99
  }
39
- deferrable() {
40
- this.builder.deferrable();
41
- return this;
100
+ finally {
101
+ release();
42
102
  }
43
103
  }
44
- exports.ConnectedTransactionBuilder = ConnectedTransactionBuilder;
@@ -4,6 +4,7 @@ exports.ConnectedUpdateBuilder = void 0;
4
4
  const methods_1 = require("./methods.cjs");
5
5
  const ReturningExecutor_1 = require("./ReturningExecutor.cjs");
6
6
  const capability_guard_1 = require("./capability-guard.cjs");
7
+ const table_accessor_1 = require("../shared/table-accessor.cjs");
7
8
  class ConnectedUpdateBuilder {
8
9
  builder;
9
10
  relq;
@@ -48,7 +49,10 @@ class ConnectedUpdateBuilder {
48
49
  });
49
50
  }
50
51
  where(callback) {
51
- this.builder.where(callback);
52
+ this.builder.where((q) => {
53
+ q._tables = (0, table_accessor_1.createTableAccessor)(this.relq, this.relq.schema);
54
+ return callback(q);
55
+ });
52
56
  return this;
53
57
  }
54
58
  toString() {
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.debugLog = exports.INTERNAL = exports.ReturningExecutor = exports.PaginateBuilder = exports.ConnectedRawQueryBuilder = exports.ConnectedQueryBuilder = exports.ConnectedTransactionBuilder = exports.ConnectedCountBuilder = exports.ConnectedInsertBuilder = exports.ConnectedDeleteBuilder = exports.ConnectedUpdateBuilder = exports.ConnectedSelectBuilder = exports.ConnectedCTEBuilder = exports.ConnectedAggregateBuilder = void 0;
3
+ exports.debugLog = exports.INTERNAL = exports.ReturningExecutor = exports.PaginateBuilder = exports.ConnectedRawQueryBuilder = exports.ConnectedQueryBuilder = exports.executeTransaction = exports.TransactionClient = exports.ConnectedCountBuilder = exports.ConnectedInsertBuilder = exports.ConnectedDeleteBuilder = exports.ConnectedUpdateBuilder = exports.ConnectedSelectBuilder = exports.ConnectedCTEBuilder = exports.ConnectedAggregateBuilder = void 0;
4
4
  var ConnectedAggregateBuilder_1 = require("./ConnectedAggregateBuilder.cjs");
5
5
  Object.defineProperty(exports, "ConnectedAggregateBuilder", { enumerable: true, get: function () { return ConnectedAggregateBuilder_1.ConnectedAggregateBuilder; } });
6
6
  var ConnectedCTEBuilder_1 = require("./ConnectedCTEBuilder.cjs");
@@ -16,7 +16,8 @@ Object.defineProperty(exports, "ConnectedInsertBuilder", { enumerable: true, get
16
16
  var ConnectedCountBuilder_1 = require("./ConnectedCountBuilder.cjs");
17
17
  Object.defineProperty(exports, "ConnectedCountBuilder", { enumerable: true, get: function () { return ConnectedCountBuilder_1.ConnectedCountBuilder; } });
18
18
  var ConnectedTransactionBuilder_1 = require("./ConnectedTransactionBuilder.cjs");
19
- Object.defineProperty(exports, "ConnectedTransactionBuilder", { enumerable: true, get: function () { return ConnectedTransactionBuilder_1.ConnectedTransactionBuilder; } });
19
+ Object.defineProperty(exports, "TransactionClient", { enumerable: true, get: function () { return ConnectedTransactionBuilder_1.TransactionClient; } });
20
+ Object.defineProperty(exports, "executeTransaction", { enumerable: true, get: function () { return ConnectedTransactionBuilder_1.executeTransaction; } });
20
21
  var ConnectedQueryBuilder_1 = require("./ConnectedQueryBuilder.cjs");
21
22
  Object.defineProperty(exports, "ConnectedQueryBuilder", { enumerable: true, get: function () { return ConnectedQueryBuilder_1.ConnectedQueryBuilder; } });
22
23
  var ConnectedRawQueryBuilder_1 = require("./ConnectedRawQueryBuilder.cjs");
@@ -1,4 +1,37 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  Object.defineProperty(exports, "__esModule", { value: true });
3
36
  exports.RelqBase = void 0;
4
37
  const node_events_1 = require("node:events");
@@ -173,8 +206,9 @@ class RelqBase {
173
206
  raw(query, ...params) {
174
207
  return new helpers_1.ConnectedRawQueryBuilder(query, params, this);
175
208
  }
176
- transaction() {
177
- return new helpers_1.ConnectedTransactionBuilder(this);
209
+ async transaction(callback) {
210
+ const { executeTransaction } = await Promise.resolve().then(() => __importStar(require("./helpers/ConnectedTransactionBuilder.cjs")));
211
+ return executeTransaction(this, callback);
178
212
  }
179
213
  with(name, query) {
180
214
  return new helpers_1.ConnectedCTEBuilder(this).with(name, query);
@@ -8,6 +8,7 @@ import { NetworkConditionCollector, buildNetworkConditionSQL } from "./network-c
8
8
  import { PostgisConditionCollector, buildPostgisConditionSQL } from "./postgis-condition-builder.js";
9
9
  export class ConditionCollector {
10
10
  conditions = [];
11
+ _tables;
11
12
  _jsonb;
12
13
  _array;
13
14
  _fulltext;
@@ -221,11 +222,23 @@ export class ConditionCollector {
221
222
  return this.isNotNull(column);
222
223
  }
223
224
  in(column, values) {
224
- this.conditions.push({ method: 'in', column, values });
225
+ if (typeof values === 'function') {
226
+ const subquery = values(this._tables);
227
+ this.conditions.push({ method: 'in', column, values: subquery.toString() });
228
+ }
229
+ else {
230
+ this.conditions.push({ method: 'in', column, values });
231
+ }
225
232
  return this;
226
233
  }
227
234
  notIn(column, values) {
228
- this.conditions.push({ method: 'notIn', column, values });
235
+ if (typeof values === 'function') {
236
+ const subquery = values(this._tables);
237
+ this.conditions.push({ method: 'notIn', column, values: subquery.toString() });
238
+ }
239
+ else {
240
+ this.conditions.push({ method: 'notIn', column, values });
241
+ }
229
242
  return this;
230
243
  }
231
244
  exists(subquery) {
@@ -389,11 +402,17 @@ export function buildConditionSQL(condition) {
389
402
  return `(${startCol}, ${endCol}) OVERLAPS (${format('%L', startVal)}, ${format('%L', endVal)})`;
390
403
  }
391
404
  case 'in': {
405
+ if (typeof values === 'string') {
406
+ return `${col} IN (${values})`;
407
+ }
392
408
  const valueList = Array.isArray(values) ? values : [values];
393
409
  const formattedValues = valueList.map(v => format('%L', v)).join(', ');
394
410
  return `${col} IN (${formattedValues})`;
395
411
  }
396
412
  case 'notIn': {
413
+ if (typeof values === 'string') {
414
+ return `${col} NOT IN (${values})`;
415
+ }
397
416
  const valueList = Array.isArray(values) ? values : [values];
398
417
  const formattedValues = valueList.map(v => format('%L', v)).join(', ');
399
418
  return `${col} NOT IN (${formattedValues})`;
@@ -1,4 +1,5 @@
1
1
  import { INTERNAL } from "./methods.js";
2
+ import { createTableAccessor } from "../shared/table-accessor.js";
2
3
  export class ConnectedAggregateBuilder {
3
4
  builder;
4
5
  relq;
@@ -70,7 +71,10 @@ export class ConnectedAggregateBuilder {
70
71
  return this;
71
72
  }
72
73
  where(callback) {
73
- this.builder.where(callback);
74
+ this.builder.where((q) => {
75
+ q._tables = createTableAccessor(this.relq, this.relq.schema);
76
+ return callback(q);
77
+ });
74
78
  return this;
75
79
  }
76
80
  having(callback) {
@@ -1,4 +1,5 @@
1
1
  import { INTERNAL } from "./methods.js";
2
+ import { createTableAccessor } from "../shared/table-accessor.js";
2
3
  export class ConnectedCountBuilder {
3
4
  builder;
4
5
  relq;
@@ -19,6 +20,7 @@ export class ConnectedCountBuilder {
19
20
  }
20
21
  where(callback) {
21
22
  this.builder.where((q) => {
23
+ q._tables = createTableAccessor(this.relq, this.relq.schema);
22
24
  const wrapped = this.wrapConditionBuilder(q);
23
25
  return callback(wrapped);
24
26
  });
@@ -1,6 +1,7 @@
1
1
  import { INTERNAL } from "./methods.js";
2
2
  import { ReturningExecutor } from "./ReturningExecutor.js";
3
3
  import { requireCapability } from "./capability-guard.js";
4
+ import { createTableAccessor } from "../shared/table-accessor.js";
4
5
  export class ConnectedDeleteBuilder {
5
6
  builder;
6
7
  relq;
@@ -32,7 +33,10 @@ export class ConnectedDeleteBuilder {
32
33
  });
33
34
  }
34
35
  where(callback) {
35
- this.builder.where(callback);
36
+ this.builder.where((q) => {
37
+ q._tables = createTableAccessor(this.relq, this.relq.schema);
38
+ return callback(q);
39
+ });
36
40
  return this;
37
41
  }
38
42
  toString() {
@@ -2,6 +2,7 @@ import { INTERNAL } from "./methods.js";
2
2
  import { executeTypeSafeJoin, executeTypeSafeJoinMany, executeTypeSafeJoinManyThrough } from "./select-joins.js";
3
3
  import { executeCursorEach, executePagination } from "./select-pagination.js";
4
4
  import { requireCapability } from "./capability-guard.js";
5
+ import { createTableAccessor } from "../shared/table-accessor.js";
5
6
  import { AggregateFunctions } from "../../select/sql-expression.js";
6
7
  import { createTableProxy } from "../../select/table-proxy.js";
7
8
  import { resolveForeignKey } from "../../utils/fk-resolver.js";
@@ -113,7 +114,10 @@ export class ConnectedSelectBuilder {
113
114
  }
114
115
  }
115
116
  where(callback) {
116
- this.builder.where(callback);
117
+ this.builder.where((q) => {
118
+ q._tables = createTableAccessor(this.relq, this.relq.schema);
119
+ return callback(q);
120
+ });
117
121
  return this;
118
122
  }
119
123
  orderBy(column, direction) {
@@ -1,40 +1,98 @@
1
- import { TransactionBuilder } from "../../transaction/transaction-builder.js";
1
+ import { ConnectedRawQueryBuilder } from "./ConnectedRawQueryBuilder.js";
2
+ import { createTableAccessor } from "../shared/table-accessor.js";
2
3
  import { INTERNAL } from "./methods.js";
3
- export class ConnectedTransactionBuilder {
4
+ export class TransactionClient {
5
+ client;
4
6
  relq;
5
- constructor(relq) {
7
+ schema;
8
+ constructor(client, relq) {
9
+ this.client = client;
6
10
  this.relq = relq;
11
+ const internal = this.relq[INTERNAL];
12
+ this.schema = internal.getSchema?.() ?? this.relq.schema;
7
13
  }
8
- builder = new TransactionBuilder();
9
- toString() {
10
- return this.builder.toString();
14
+ get table() {
15
+ return createTableAccessor(this, this.schema);
11
16
  }
12
- async begin() {
13
- const sql = this.builder.toString();
14
- return this.relq[INTERNAL].executeRun(sql);
17
+ raw(query, ...params) {
18
+ return new ConnectedRawQueryBuilder(query, params, this);
15
19
  }
16
- async commit() {
17
- const sql = this.builder.commit();
18
- return this.relq[INTERNAL].executeRun(sql);
20
+ get [INTERNAL]() {
21
+ const parentInternal = this.relq[INTERNAL];
22
+ const queryViaClient = async (sql) => {
23
+ const start = performance.now();
24
+ const pgResult = await this.client.query(sql);
25
+ return {
26
+ result: {
27
+ rows: pgResult.rows,
28
+ rowCount: pgResult.rowCount,
29
+ command: pgResult.command,
30
+ fields: pgResult.fields?.map((f) => ({ name: f.name, dataTypeID: f.dataTypeID })) ?? [],
31
+ },
32
+ duration: performance.now() - start,
33
+ };
34
+ };
35
+ const buildMetadata = (result, duration) => ({
36
+ rowCount: result.rowCount,
37
+ command: result.command,
38
+ duration,
39
+ fields: result.fields,
40
+ });
41
+ return {
42
+ executeQuery: queryViaClient,
43
+ async executeSelect(sql, tableName) {
44
+ const { result, duration } = await queryViaClient(sql);
45
+ const rows = tableName
46
+ ? parentInternal.transformResultsFromDb(tableName, result.rows)
47
+ : result.rows;
48
+ return { data: rows, metadata: buildMetadata(result, duration) };
49
+ },
50
+ async executeSelectOne(sql, tableName) {
51
+ const { result, duration } = await queryViaClient(sql);
52
+ const row = result.rows[0]
53
+ ? (tableName ? parentInternal.transformFromDbColumns(tableName, result.rows[0]) : result.rows[0])
54
+ : null;
55
+ return { data: row, metadata: buildMetadata(result, duration) };
56
+ },
57
+ async executeCount(sql) {
58
+ const { result, duration } = await queryViaClient(sql);
59
+ const count = result.rows[0]?.count ? parseInt(result.rows[0].count, 10) : 0;
60
+ return { count, metadata: buildMetadata(result, duration) };
61
+ },
62
+ async executeRun(sql) {
63
+ const { result, duration } = await queryViaClient(sql);
64
+ return { success: true, metadata: buildMetadata(result, duration) };
65
+ },
66
+ transformToDbColumns: parentInternal.transformToDbColumns,
67
+ transformFromDbColumns: parentInternal.transformFromDbColumns,
68
+ transformResultsFromDb: parentInternal.transformResultsFromDb,
69
+ hasColumnMapping: parentInternal.hasColumnMapping,
70
+ validateData: parentInternal.validateData,
71
+ getSchema: parentInternal.getSchema,
72
+ getRelations: parentInternal.getRelations,
73
+ getTableDef: parentInternal.getTableDef,
74
+ getClientForCursor: async () => ({ client: this.client, release: () => { } }),
75
+ };
19
76
  }
20
- async rollback() {
21
- const sql = this.builder.rollback();
22
- return this.relq[INTERNAL].executeRun(sql);
23
- }
24
- isolationLevel(level) {
25
- this.builder.isolation(level);
26
- return this;
27
- }
28
- readOnly() {
29
- this.builder.readOnly();
30
- return this;
77
+ }
78
+ export async function executeTransaction(relq, callback) {
79
+ await relq.ensureInitialized();
80
+ const { client, release } = await relq[INTERNAL].getClientForCursor();
81
+ try {
82
+ await client.query('BEGIN');
83
+ const tx = new TransactionClient(client, relq);
84
+ const result = await callback(tx);
85
+ await client.query('COMMIT');
86
+ return result;
31
87
  }
32
- readWrite() {
33
- this.builder.readWrite();
34
- return this;
88
+ catch (error) {
89
+ try {
90
+ await client.query('ROLLBACK');
91
+ }
92
+ catch { }
93
+ throw error;
35
94
  }
36
- deferrable() {
37
- this.builder.deferrable();
38
- return this;
95
+ finally {
96
+ release();
39
97
  }
40
98
  }
@@ -1,6 +1,7 @@
1
1
  import { INTERNAL } from "./methods.js";
2
2
  import { ReturningExecutor } from "./ReturningExecutor.js";
3
3
  import { requireCapability } from "./capability-guard.js";
4
+ import { createTableAccessor } from "../shared/table-accessor.js";
4
5
  export class ConnectedUpdateBuilder {
5
6
  builder;
6
7
  relq;
@@ -45,7 +46,10 @@ export class ConnectedUpdateBuilder {
45
46
  });
46
47
  }
47
48
  where(callback) {
48
- this.builder.where(callback);
49
+ this.builder.where((q) => {
50
+ q._tables = createTableAccessor(this.relq, this.relq.schema);
51
+ return callback(q);
52
+ });
49
53
  return this;
50
54
  }
51
55
  toString() {
@@ -5,7 +5,7 @@ export { ConnectedUpdateBuilder } from "./ConnectedUpdateBuilder.js";
5
5
  export { ConnectedDeleteBuilder } from "./ConnectedDeleteBuilder.js";
6
6
  export { ConnectedInsertBuilder } from "./ConnectedInsertBuilder.js";
7
7
  export { ConnectedCountBuilder } from "./ConnectedCountBuilder.js";
8
- export { ConnectedTransactionBuilder } from "./ConnectedTransactionBuilder.js";
8
+ export { TransactionClient, executeTransaction } from "./ConnectedTransactionBuilder.js";
9
9
  export { ConnectedQueryBuilder } from "./ConnectedQueryBuilder.js";
10
10
  export { ConnectedRawQueryBuilder } from "./ConnectedRawQueryBuilder.js";
11
11
  export { PaginateBuilder } from "./PaginateBuilder.js";
@@ -1,7 +1,7 @@
1
1
  import { EventEmitter } from 'node:events';
2
2
  import { RelqConnectionError } from "../errors/relq-errors.js";
3
3
  import { ConditionCollector } from "../condition/condition-collector.js";
4
- import { ConnectedCTEBuilder, ConnectedRawQueryBuilder, ConnectedTransactionBuilder, INTERNAL, debugLog } from "./helpers/index.js";
4
+ import { ConnectedCTEBuilder, ConnectedRawQueryBuilder, INTERNAL, debugLog } from "./helpers/index.js";
5
5
  import { ConnectedScalarSelectBuilder } from "../select/scalar-select-builder.js";
6
6
  import { buildColumnMappings, transformToDbColumns, transformFromDbColumns, transformResultsFromDb, hasColumnMapping } from "./shared/column-mapping.js";
7
7
  import { validateData } from "./shared/validation.js";
@@ -170,8 +170,9 @@ export class RelqBase {
170
170
  raw(query, ...params) {
171
171
  return new ConnectedRawQueryBuilder(query, params, this);
172
172
  }
173
- transaction() {
174
- return new ConnectedTransactionBuilder(this);
173
+ async transaction(callback) {
174
+ const { executeTransaction } = await import("./helpers/ConnectedTransactionBuilder.js");
175
+ return executeTransaction(this, callback);
175
176
  }
176
177
  with(name, query) {
177
178
  return new ConnectedCTEBuilder(this).with(name, query);
package/dist/index.d.ts CHANGED
@@ -919,10 +919,16 @@ export interface TypedConditionBuilder<TTable = any> {
919
919
  lessThanOrEqual<K extends ColumnName<TTable>>(column: K, value: ConditionValue<TTable, K>): TypedConditionBuilder<TTable>;
920
920
  /** Alias for isNotNull - creates an IS NOT NULL condition */
921
921
  notNull<K extends ColumnName<TTable>>(column: K): TypedConditionBuilder<TTable>;
922
- /** Creates an IN condition for array matching */
922
+ /** Creates an IN condition for array matching or subquery */
923
923
  in<K extends ColumnName<TTable>>(column: K, values: ConditionValue<TTable, K>[]): TypedConditionBuilder<TTable>;
924
- /** Creates a NOT IN condition for array exclusion */
924
+ in<K extends ColumnName<TTable>>(column: K, subquery: (t: any) => {
925
+ toString(): string;
926
+ }): TypedConditionBuilder<TTable>;
927
+ /** Creates a NOT IN condition for array exclusion or subquery */
925
928
  notIn<K extends ColumnName<TTable>>(column: K, values: ConditionValue<TTable, K>[]): TypedConditionBuilder<TTable>;
929
+ notIn<K extends ColumnName<TTable>>(column: K, subquery: (t: any) => {
930
+ toString(): string;
931
+ }): TypedConditionBuilder<TTable>;
926
932
  /** Creates an EXISTS condition with subquery */
927
933
  exists(subquery: string): TypedConditionBuilder<TTable>;
928
934
  /** Creates a NOT EXISTS condition with subquery */
@@ -9703,43 +9709,6 @@ declare class ConnectedSelectBuilder<TSchema = any, TTable = any, TColumns exten
9703
9709
  */
9704
9710
  pagination<T = InferResultType<TSchema, TTable, TColumns> & TJoined>(options: PaginationOptions): Promise<PaginatedResult<T>>;
9705
9711
  }
9706
- declare class ConnectedTransactionBuilder {
9707
- private relq;
9708
- constructor(relq: RelqBase);
9709
- private builder;
9710
- /**
9711
- * Get SQL string (always available)
9712
- */
9713
- toString(): string;
9714
- /**
9715
- * Begin transaction
9716
- */
9717
- begin(): Promise<RelqRun>;
9718
- /**
9719
- * Commit transaction
9720
- */
9721
- commit(): Promise<RelqRun>;
9722
- /**
9723
- * Rollback transaction
9724
- */
9725
- rollback(): Promise<RelqRun>;
9726
- /**
9727
- * Set isolation level
9728
- */
9729
- isolationLevel(level: "READ UNCOMMITTED" | "READ COMMITTED" | "REPEATABLE READ" | "SERIALIZABLE"): this;
9730
- /**
9731
- * Set transaction as read only
9732
- */
9733
- readOnly(): this;
9734
- /**
9735
- * Set transaction as read write
9736
- */
9737
- readWrite(): this;
9738
- /**
9739
- * Set transaction as deferrable
9740
- */
9741
- deferrable(): this;
9742
- }
9743
9712
  declare class ConnectedRawQueryBuilder {
9744
9713
  private query;
9745
9714
  private params;
@@ -9819,6 +9788,18 @@ declare class ConnectedRawQueryBuilder {
9819
9788
  count(): Promise<RelqCount>;
9820
9789
  }
9821
9790
  declare const INTERNAL: unique symbol;
9791
+ declare class TransactionClient<TSchema = any> {
9792
+ private client;
9793
+ private relq;
9794
+ private schema;
9795
+ constructor(client: any, relq: RelqBase<TSchema>);
9796
+ get table(): TableAccessor<TSchema, this>;
9797
+ raw(query: string, ...params: QueryValue[]): ConnectedRawQueryBuilder;
9798
+ /**
9799
+ * INTERNAL accessor — same interface as RelqBase but queries go through the tx client
9800
+ */
9801
+ get [INTERNAL](): RelqInternal;
9802
+ }
9822
9803
  /**
9823
9804
  * Marker interface for scalar subquery results.
9824
9805
  * Contains type information and SQL generation capability.
@@ -10087,9 +10068,12 @@ export declare abstract class RelqBase<TSchema = any> {
10087
10068
  */
10088
10069
  raw(query: string, ...params: QueryValue[]): ConnectedRawQueryBuilder;
10089
10070
  /**
10090
- * Create a transaction builder
10071
+ * Run a callback inside a transaction.
10072
+ * Acquires a dedicated client, runs BEGIN, executes the callback,
10073
+ * then COMMIT on success or ROLLBACK on error.
10074
+ * Returns whatever the callback returns with full type inference.
10091
10075
  */
10092
- transaction(): ConnectedTransactionBuilder;
10076
+ transaction<TResult>(callback: (tx: TransactionClient<TSchema>) => Promise<TResult>): Promise<TResult>;
10093
10077
  /**
10094
10078
  * Start a CTE (Common Table Expression) query
10095
10079
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "relq",
3
- "version": "1.0.116",
3
+ "version": "1.0.117",
4
4
  "description": "The Fully-Typed PostgreSQL ORM for TypeScript",
5
5
  "author": "Olajide Mathew O. <olajide.mathew@yuniq.solutions>",
6
6
  "license": "MIT",