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.
- package/dist/cjs/condition/condition-collector.cjs +21 -2
- package/dist/cjs/core/helpers/ConnectedAggregateBuilder.cjs +5 -1
- package/dist/cjs/core/helpers/ConnectedCountBuilder.cjs +2 -0
- package/dist/cjs/core/helpers/ConnectedDeleteBuilder.cjs +5 -1
- package/dist/cjs/core/helpers/ConnectedSelectBuilder.cjs +5 -1
- package/dist/cjs/core/helpers/ConnectedTransactionBuilder.cjs +90 -31
- package/dist/cjs/core/helpers/ConnectedUpdateBuilder.cjs +5 -1
- package/dist/cjs/core/helpers/index.cjs +3 -2
- package/dist/cjs/core/relq-base.cjs +36 -2
- package/dist/esm/condition/condition-collector.js +21 -2
- package/dist/esm/core/helpers/ConnectedAggregateBuilder.js +5 -1
- package/dist/esm/core/helpers/ConnectedCountBuilder.js +2 -0
- package/dist/esm/core/helpers/ConnectedDeleteBuilder.js +5 -1
- package/dist/esm/core/helpers/ConnectedSelectBuilder.js +5 -1
- package/dist/esm/core/helpers/ConnectedTransactionBuilder.js +87 -29
- package/dist/esm/core/helpers/ConnectedUpdateBuilder.js +5 -1
- package/dist/esm/core/helpers/index.js +1 -1
- package/dist/esm/core/relq-base.js +4 -3
- package/dist/index.d.ts +25 -41
- package/package.json +1 -1
|
@@ -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
|
-
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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.
|
|
4
|
-
|
|
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
|
|
8
|
+
class TransactionClient {
|
|
9
|
+
client;
|
|
7
10
|
relq;
|
|
8
|
-
|
|
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
|
-
|
|
12
|
-
|
|
13
|
-
return this.builder.toString();
|
|
18
|
+
get table() {
|
|
19
|
+
return (0, table_accessor_1.createTableAccessor)(this, this.schema);
|
|
14
20
|
}
|
|
15
|
-
|
|
16
|
-
|
|
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
|
-
|
|
20
|
-
const
|
|
21
|
-
|
|
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
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
return
|
|
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
|
-
|
|
36
|
-
|
|
37
|
-
|
|
93
|
+
catch (error) {
|
|
94
|
+
try {
|
|
95
|
+
await client.query('ROLLBACK');
|
|
96
|
+
}
|
|
97
|
+
catch { }
|
|
98
|
+
throw error;
|
|
38
99
|
}
|
|
39
|
-
|
|
40
|
-
|
|
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(
|
|
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.
|
|
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, "
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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 {
|
|
1
|
+
import { ConnectedRawQueryBuilder } from "./ConnectedRawQueryBuilder.js";
|
|
2
|
+
import { createTableAccessor } from "../shared/table-accessor.js";
|
|
2
3
|
import { INTERNAL } from "./methods.js";
|
|
3
|
-
export class
|
|
4
|
+
export class TransactionClient {
|
|
5
|
+
client;
|
|
4
6
|
relq;
|
|
5
|
-
|
|
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
|
-
|
|
9
|
-
|
|
10
|
-
return this.builder.toString();
|
|
14
|
+
get table() {
|
|
15
|
+
return createTableAccessor(this, this.schema);
|
|
11
16
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
return this.relq[INTERNAL].executeRun(sql);
|
|
17
|
+
raw(query, ...params) {
|
|
18
|
+
return new ConnectedRawQueryBuilder(query, params, this);
|
|
15
19
|
}
|
|
16
|
-
|
|
17
|
-
const
|
|
18
|
-
|
|
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
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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
|
-
|
|
33
|
-
|
|
34
|
-
|
|
88
|
+
catch (error) {
|
|
89
|
+
try {
|
|
90
|
+
await client.query('ROLLBACK');
|
|
91
|
+
}
|
|
92
|
+
catch { }
|
|
93
|
+
throw error;
|
|
35
94
|
}
|
|
36
|
-
|
|
37
|
-
|
|
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(
|
|
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 {
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
*
|
|
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():
|
|
10076
|
+
transaction<TResult>(callback: (tx: TransactionClient<TSchema>) => Promise<TResult>): Promise<TResult>;
|
|
10093
10077
|
/**
|
|
10094
10078
|
* Start a CTE (Common Table Expression) query
|
|
10095
10079
|
*/
|