@nestjs-kitchen/connextion-postgres 2.0.3 → 2.0.4
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/constants.d.ts +7 -9
- package/dist/constants.js +12 -45
- package/dist/define-postgres.d.ts +6 -14
- package/dist/define-postgres.js +40 -59
- package/dist/errors.d.ts +1 -4
- package/dist/errors.js +15 -34
- package/dist/index.d.ts +3 -9
- package/dist/index.js +8 -31
- package/dist/polyfill.d.ts +1 -2
- package/dist/polyfill.js +4 -2
- package/dist/postgres.instance.d.ts +4 -7
- package/dist/postgres.instance.js +191 -199
- package/dist/transaction.d.ts +3 -4
- package/dist/transaction.js +104 -120
- package/dist/types.d.ts +4 -7
- package/dist/types.js +2 -15
- package/dist/utils.d.ts +16 -19
- package/dist/utils.js +199 -235
- package/package.json +6 -5
|
@@ -1,211 +1,203 @@
|
|
|
1
|
-
|
|
2
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
-
var __export = (target, all) => {
|
|
6
|
-
for (var name in all)
|
|
7
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
-
};
|
|
9
|
-
var __copyProps = (to, from, except, desc) => {
|
|
10
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
-
for (let key of __getOwnPropNames(from))
|
|
12
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
-
}
|
|
15
|
-
return to;
|
|
16
|
-
};
|
|
17
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
-
var postgres_instance_exports = {};
|
|
19
|
-
__export(postgres_instance_exports, {
|
|
20
|
-
PostgresInstance: () => PostgresInstance
|
|
21
|
-
});
|
|
22
|
-
module.exports = __toCommonJS(postgres_instance_exports);
|
|
23
|
-
var import_node_async_hooks = require("node:async_hooks");
|
|
24
|
-
var import_connextion = require("@nestjs-kitchen/connextion");
|
|
25
|
-
var import_common = require("@nestjs/common");
|
|
26
|
-
var import_pg = require("pg");
|
|
27
|
-
var import_uid = require("uid");
|
|
28
|
-
var import_constants = require("./constants");
|
|
29
|
-
var import_errors = require("./errors");
|
|
30
|
-
var import_utils = require("./utils");
|
|
1
|
+
"use strict";
|
|
31
2
|
var _a;
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
this.logger.error(error);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
dispose() {
|
|
60
|
-
if (!this.pool) {
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
const pool = this.pool;
|
|
64
|
-
this.pool = void 0;
|
|
65
|
-
return this.end(pool);
|
|
66
|
-
}
|
|
67
|
-
create(options) {
|
|
68
|
-
this.dispose();
|
|
69
|
-
try {
|
|
70
|
-
const pool = new import_pg.Pool(options);
|
|
71
|
-
pool.on("connect", this.listener1);
|
|
72
|
-
pool.on("error", this.listener2);
|
|
73
|
-
this.pool = pool;
|
|
74
|
-
} catch (error) {
|
|
75
|
-
this.logger.error(error.message);
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.PostgresInstance = void 0;
|
|
5
|
+
const node_async_hooks_1 = require("node:async_hooks");
|
|
6
|
+
const connextion_1 = require("@nestjs-kitchen/connextion");
|
|
7
|
+
const common_1 = require("@nestjs/common");
|
|
8
|
+
const pg_1 = require("pg");
|
|
9
|
+
const uid_1 = require("uid");
|
|
10
|
+
const constants_1 = require("./constants");
|
|
11
|
+
const errors_1 = require("./errors");
|
|
12
|
+
const utils_1 = require("./utils");
|
|
13
|
+
class PostgresInstance extends connextion_1.ConnextionInstance {
|
|
14
|
+
constructor(name, options) {
|
|
15
|
+
super(name, options);
|
|
16
|
+
this.pool = undefined;
|
|
17
|
+
// Every instance should have its own als to avoid accessing wrong context.
|
|
18
|
+
this[_a] = new node_async_hooks_1.AsyncLocalStorage();
|
|
19
|
+
this.listener1 = (_cli) => {
|
|
20
|
+
_cli.on('error', this.listener2);
|
|
21
|
+
};
|
|
22
|
+
this.listener2 = (err) => {
|
|
23
|
+
this.logger.error(err);
|
|
24
|
+
};
|
|
25
|
+
this.logger = new common_1.Logger(`Postgres][${name}`);
|
|
26
|
+
this.debug = Boolean(process.env[constants_1.CONNEXTION_POSTGRES_DEBUG]) || options?.debug;
|
|
76
27
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
28
|
+
async end(pool) {
|
|
29
|
+
if (!pool) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
try {
|
|
33
|
+
await pool.end();
|
|
34
|
+
pool.off('connect', this.listener1);
|
|
35
|
+
pool.off('error', this.listener2);
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
this.logger.error(error);
|
|
39
|
+
}
|
|
81
40
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
90
|
-
return client2;
|
|
41
|
+
dispose() {
|
|
42
|
+
if (!this.pool) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const pool = this.pool;
|
|
46
|
+
this.pool = undefined;
|
|
47
|
+
return this.end(pool);
|
|
91
48
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
49
|
+
create(options) {
|
|
50
|
+
this.dispose();
|
|
51
|
+
try {
|
|
52
|
+
const pool = new pg_1.Pool(options);
|
|
53
|
+
//https://github.com/brianc/node-postgres/issues/2439#issuecomment-757691278
|
|
54
|
+
pool.on('connect', this.listener1);
|
|
55
|
+
pool.on('error', this.listener2);
|
|
56
|
+
this.pool = pool;
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
this.logger.error(error.message);
|
|
60
|
+
}
|
|
97
61
|
}
|
|
98
|
-
|
|
99
|
-
|
|
62
|
+
async [(_a = constants_1.ALS, constants_1.GET_CLIENT)]() {
|
|
63
|
+
if (!this.pool) {
|
|
64
|
+
throw new errors_1.PostgresError('pool not found');
|
|
65
|
+
}
|
|
66
|
+
if (!this.debug) {
|
|
67
|
+
const [client, err] = await (0, utils_1.plainPromise)(this.pool.connect());
|
|
68
|
+
if (err) {
|
|
69
|
+
throw new errors_1.PostgresError(err, err);
|
|
70
|
+
}
|
|
71
|
+
if (!client) {
|
|
72
|
+
throw new errors_1.PostgresError('client not found');
|
|
73
|
+
}
|
|
74
|
+
return client;
|
|
75
|
+
}
|
|
76
|
+
// Debug mode
|
|
77
|
+
const logger = (0, utils_1.createDebugLogger)(this.logger.debug.bind(this.logger), this.debug);
|
|
78
|
+
const debug = (0, utils_1.debugFactroy)(this.name, (0, uid_1.uid)(21), logger);
|
|
79
|
+
const [client, err] = await (0, utils_1.plainPromise)(debug.pool.connect(this.pool.connect.bind(this.pool))());
|
|
80
|
+
if (err) {
|
|
81
|
+
throw new errors_1.PostgresError(err, err);
|
|
82
|
+
}
|
|
83
|
+
if (!client) {
|
|
84
|
+
throw new errors_1.PostgresError('client not found');
|
|
85
|
+
}
|
|
86
|
+
return new Proxy(client, {
|
|
87
|
+
get(target, prop, receiver) {
|
|
88
|
+
const value = Reflect.get(target, prop, receiver);
|
|
89
|
+
if (debug.client[prop]) {
|
|
90
|
+
return debug.client[prop](value.bind(target));
|
|
91
|
+
}
|
|
92
|
+
return value;
|
|
93
|
+
}
|
|
94
|
+
});
|
|
100
95
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
if (!rest.length) {
|
|
113
|
-
throw new import_errors.PostgresError(`empty parameters`);
|
|
96
|
+
async query(...rest) {
|
|
97
|
+
if (!rest.length) {
|
|
98
|
+
throw new errors_1.PostgresError(`empty parameters`);
|
|
99
|
+
}
|
|
100
|
+
const store = this[constants_1.ALS].getStore();
|
|
101
|
+
const methodMap = {
|
|
102
|
+
submittable: store ? this.transactionQueryWithSubmittable : this.queryWithSubmittable,
|
|
103
|
+
config: store ? this.transactionQueryWithConfig : this.queryWithConfig
|
|
104
|
+
};
|
|
105
|
+
const method = methodMap[(0, utils_1.isSubmittable)(rest[0]) ? 'submittable' : 'config'].bind(this);
|
|
106
|
+
return method(...rest);
|
|
114
107
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
} catch (error) {
|
|
129
|
-
err = new import_errors.PostgresError(error, error);
|
|
130
|
-
throw err;
|
|
131
|
-
} finally {
|
|
132
|
-
client.release(err ?? true);
|
|
108
|
+
async queryWithConfig(...rest) {
|
|
109
|
+
const client = await this[constants_1.GET_CLIENT]();
|
|
110
|
+
let err = undefined;
|
|
111
|
+
try {
|
|
112
|
+
return (await client.query(...rest));
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
err = new errors_1.PostgresError(error, error);
|
|
116
|
+
throw err;
|
|
117
|
+
}
|
|
118
|
+
finally {
|
|
119
|
+
client.release(err ?? true);
|
|
120
|
+
}
|
|
133
121
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
122
|
+
async transactionQueryWithConfig(...rest) {
|
|
123
|
+
const store = this[constants_1.ALS].getStore();
|
|
124
|
+
const client = await store.client;
|
|
125
|
+
let err = undefined;
|
|
126
|
+
const { promise, resolve } = Promise.withResolvers();
|
|
127
|
+
store.queries.push(promise);
|
|
128
|
+
try {
|
|
129
|
+
return (await client.query(...rest));
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
err = new errors_1.PostgresError(error, error);
|
|
133
|
+
throw err;
|
|
134
|
+
}
|
|
135
|
+
finally {
|
|
136
|
+
resolve(err ?? true);
|
|
137
|
+
}
|
|
148
138
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
139
|
+
async queryWithSubmittable(queryStream) {
|
|
140
|
+
const client = await this[constants_1.GET_CLIENT]();
|
|
141
|
+
let res = undefined;
|
|
142
|
+
let err = undefined;
|
|
143
|
+
try {
|
|
144
|
+
res = (await client.query(queryStream));
|
|
145
|
+
return res;
|
|
146
|
+
}
|
|
147
|
+
catch (error) {
|
|
148
|
+
err = new errors_1.PostgresError(error, error);
|
|
149
|
+
throw err;
|
|
150
|
+
}
|
|
151
|
+
finally {
|
|
152
|
+
if (res) {
|
|
153
|
+
const onError = (error) => {
|
|
154
|
+
res.off('end', onEnd);
|
|
155
|
+
client.release(new errors_1.PostgresError(error, error));
|
|
156
|
+
};
|
|
157
|
+
const onEnd = () => {
|
|
158
|
+
res.off('error', onError);
|
|
159
|
+
client.release(true);
|
|
160
|
+
};
|
|
161
|
+
res.once('end', onEnd);
|
|
162
|
+
res.once('error', onError);
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
client.release(err ?? true);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
175
168
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
169
|
+
async transactionQueryWithSubmittable(queryStream) {
|
|
170
|
+
const store = this[constants_1.ALS].getStore();
|
|
171
|
+
const client = await store.client;
|
|
172
|
+
let res = undefined;
|
|
173
|
+
let err = undefined;
|
|
174
|
+
const { promise, resolve } = Promise.withResolvers();
|
|
175
|
+
store.queries.push(promise);
|
|
176
|
+
try {
|
|
177
|
+
res = (await client.query(queryStream));
|
|
178
|
+
return res;
|
|
179
|
+
}
|
|
180
|
+
catch (error) {
|
|
181
|
+
err = new errors_1.PostgresError(error, error);
|
|
182
|
+
throw err;
|
|
183
|
+
}
|
|
184
|
+
finally {
|
|
185
|
+
if (res) {
|
|
186
|
+
const onError = (error) => {
|
|
187
|
+
res.off('end', onEnd);
|
|
188
|
+
resolve(new errors_1.PostgresError(error, error));
|
|
189
|
+
};
|
|
190
|
+
const onEnd = () => {
|
|
191
|
+
res.off('error', onError);
|
|
192
|
+
resolve(true);
|
|
193
|
+
};
|
|
194
|
+
res.once('end', onEnd);
|
|
195
|
+
res.once('error', onError);
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
resolve(err ?? true);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
205
201
|
}
|
|
206
|
-
}
|
|
207
202
|
}
|
|
208
|
-
|
|
209
|
-
0 && (module.exports = {
|
|
210
|
-
PostgresInstance
|
|
211
|
-
});
|
|
203
|
+
exports.PostgresInstance = PostgresInstance;
|
package/dist/transaction.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { defineConnextionBuilder } from '@nestjs-kitchen/connextion';
|
|
2
|
-
|
|
2
|
+
import type { PostgresInstance } from './postgres.instance';
|
|
3
3
|
type Postgres = ReturnType<ReturnType<typeof defineConnextionBuilder<'Postgres', PostgresInstance>>>['Postgres'];
|
|
4
|
-
declare const createTransaction: <T extends string>(Postgres: Postgres) => (...rest: T[]) => (target: any, _propertyKey: string, propertyDescriptor: PropertyDescriptor) => PropertyDescriptor;
|
|
5
|
-
|
|
6
|
-
export { createTransaction };
|
|
4
|
+
export declare const createTransaction: <T extends string>(Postgres: Postgres) => (...rest: T[]) => (target: any, _propertyKey: string, propertyDescriptor: PropertyDescriptor) => PropertyDescriptor;
|
|
5
|
+
export {};
|
package/dist/transaction.js
CHANGED
|
@@ -1,125 +1,109 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
};
|
|
9
|
-
var __copyProps = (to, from, except, desc) => {
|
|
10
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
-
for (let key of __getOwnPropNames(from))
|
|
12
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
-
}
|
|
15
|
-
return to;
|
|
16
|
-
};
|
|
17
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
-
var transaction_exports = {};
|
|
19
|
-
__export(transaction_exports, {
|
|
20
|
-
createTransaction: () => createTransaction
|
|
21
|
-
});
|
|
22
|
-
module.exports = __toCommonJS(transaction_exports);
|
|
23
|
-
var import_common = require("@nestjs/common");
|
|
24
|
-
var import_constants = require("./constants");
|
|
25
|
-
var import_errors = require("./errors");
|
|
26
|
-
var import_utils = require("./utils");
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createTransaction = void 0;
|
|
4
|
+
const common_1 = require("@nestjs/common");
|
|
5
|
+
const constants_1 = require("./constants");
|
|
6
|
+
const errors_1 = require("./errors");
|
|
7
|
+
const utils_1 = require("./utils");
|
|
27
8
|
const createTransaction = (Postgres) => {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
const that = this;
|
|
40
|
-
const postgres = that[postgresPropName];
|
|
41
|
-
const keys = rest.length ? rest : Object.keys(postgres.instanceTokens);
|
|
42
|
-
const validNames = [];
|
|
43
|
-
const invalidNames = [];
|
|
44
|
-
(0, import_utils.normalizeStrings)(keys).forEach((name) => {
|
|
45
|
-
if (postgres.instanceTokens[name]) {
|
|
46
|
-
validNames.push(name);
|
|
47
|
-
} else {
|
|
48
|
-
invalidNames.push(name);
|
|
49
|
-
}
|
|
50
|
-
});
|
|
51
|
-
if (invalidNames.length) {
|
|
52
|
-
throw new import_errors.PostgresError(`Invalid keys: ${invalidNames.join(", ")}`);
|
|
53
|
-
}
|
|
54
|
-
const list = validNames.map((name) => {
|
|
55
|
-
return {
|
|
56
|
-
name,
|
|
57
|
-
store: {
|
|
58
|
-
client: postgres[name][import_constants.GET_CLIENT](),
|
|
59
|
-
queries: []
|
|
60
|
-
},
|
|
61
|
-
als: postgres[name][import_constants.ALS],
|
|
62
|
-
inited: false
|
|
63
|
-
};
|
|
64
|
-
});
|
|
65
|
-
const initClients = async () => {
|
|
66
|
-
for (const ele of list) {
|
|
67
|
-
await ele.store.client;
|
|
68
|
-
ele.inited = true;
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
const runWithClients = async (fn) => {
|
|
72
|
-
for (const ele of list) {
|
|
73
|
-
if (ele.inited) {
|
|
74
|
-
const client = await ele.store.client;
|
|
75
|
-
await fn(client);
|
|
9
|
+
const postgresPropName = Symbol('postgres');
|
|
10
|
+
return (...rest) => {
|
|
11
|
+
const injectPostgres = (0, common_1.Inject)(Postgres);
|
|
12
|
+
return (target, _propertyKey, propertyDescriptor) => {
|
|
13
|
+
// This is equivalent to property-based injection in the class.
|
|
14
|
+
// It will append a new injection to the class where the target method is located.
|
|
15
|
+
// Ref: https://stackoverflow.com/questions/52106406/in-nest-js-how-to-get-a-service-instance-inside-a-decorator
|
|
16
|
+
injectPostgres(target, postgresPropName);
|
|
17
|
+
const originalMethod = propertyDescriptor.value;
|
|
18
|
+
if ((0, utils_1.getTransactionMetdata)(originalMethod)) {
|
|
19
|
+
throw new errors_1.PostgresError('Cannot reapply the same transaction decorator multiple times.');
|
|
76
20
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
const result3 = await executeQueries();
|
|
96
|
-
const queryResults = await Promise.all(list.flatMap((c) => c.store.queries));
|
|
97
|
-
const queryFailures = queryResults.filter((res) => res !== true);
|
|
98
|
-
if (queryFailures.length) {
|
|
99
|
-
throw queryFailures[0];
|
|
21
|
+
(0, utils_1.setTransactionMetdata)(originalMethod);
|
|
22
|
+
propertyDescriptor.value = async function (...args) {
|
|
23
|
+
const that = this;
|
|
24
|
+
const postgres = that[postgresPropName];
|
|
25
|
+
// Enables transaction by default for all instances.
|
|
26
|
+
const keys = rest.length ? rest : Object.keys(postgres.instanceTokens);
|
|
27
|
+
const validNames = [];
|
|
28
|
+
const invalidNames = [];
|
|
29
|
+
(0, utils_1.normalizeStrings)(keys).forEach((name) => {
|
|
30
|
+
if (postgres.instanceTokens[name]) {
|
|
31
|
+
validNames.push(name);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
invalidNames.push(name);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
if (invalidNames.length) {
|
|
38
|
+
throw new errors_1.PostgresError(`Invalid keys: ${invalidNames.join(', ')}`);
|
|
100
39
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
40
|
+
const list = validNames.map((name) => {
|
|
41
|
+
return {
|
|
42
|
+
name,
|
|
43
|
+
store: {
|
|
44
|
+
client: postgres[name][constants_1.GET_CLIENT](),
|
|
45
|
+
queries: []
|
|
46
|
+
},
|
|
47
|
+
als: postgres[name][constants_1.ALS],
|
|
48
|
+
inited: false
|
|
49
|
+
};
|
|
50
|
+
});
|
|
51
|
+
const initClients = async () => {
|
|
52
|
+
for (const ele of list) {
|
|
53
|
+
await ele.store.client;
|
|
54
|
+
ele.inited = true;
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
const runWithClients = async (fn) => {
|
|
58
|
+
for (const ele of list) {
|
|
59
|
+
if (ele.inited) {
|
|
60
|
+
const client = await ele.store.client;
|
|
61
|
+
await fn(client);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
const releaseClients = async (err) => runWithClients((client) => client.release(err ?? true));
|
|
66
|
+
// Ensure all clients are available.
|
|
67
|
+
const [_, initErr] = await (0, utils_1.plainPromise)(initClients());
|
|
68
|
+
if (initErr) {
|
|
69
|
+
// Error is not caused by the available clients. No need to pass the error.
|
|
70
|
+
await releaseClients();
|
|
71
|
+
throw initErr;
|
|
72
|
+
}
|
|
73
|
+
const executeQueries = list.reduce((next, ele) => () => ele.als.run(ele.store, next), () => originalMethod.apply(that, args));
|
|
74
|
+
const [result, err] = await (0, utils_1.plainPromise)((async () => {
|
|
75
|
+
const [result, err] = await (0, utils_1.plainPromise)(
|
|
76
|
+
// Start transaction and execute queries.
|
|
77
|
+
(async () => {
|
|
78
|
+
await runWithClients((client) => client.query('BEGIN'));
|
|
79
|
+
const result = await executeQueries();
|
|
80
|
+
// Collect query errors.
|
|
81
|
+
const queryResults = await Promise.all(list.flatMap((c) => c.store.queries));
|
|
82
|
+
const queryFailures = queryResults.filter((res) => res !== true);
|
|
83
|
+
if (queryFailures.length) {
|
|
84
|
+
throw queryFailures[0];
|
|
85
|
+
}
|
|
86
|
+
return result;
|
|
87
|
+
})());
|
|
88
|
+
// End transaction with thrown/query error.
|
|
89
|
+
await runWithClients((client) => client.query(err ? 'ROLLBACK' : 'COMMIT'));
|
|
90
|
+
if (err) {
|
|
91
|
+
throw err;
|
|
92
|
+
}
|
|
93
|
+
return result;
|
|
94
|
+
})());
|
|
95
|
+
// Release all clients.
|
|
96
|
+
await releaseClients(err);
|
|
97
|
+
// Resume function call.
|
|
98
|
+
if (err) {
|
|
99
|
+
throw err;
|
|
100
|
+
}
|
|
101
|
+
return result;
|
|
102
|
+
};
|
|
103
|
+
// Compatible with NestJS decorators.
|
|
104
|
+
(0, utils_1.copyMethodMetadata)(originalMethod, propertyDescriptor.value);
|
|
105
|
+
return propertyDescriptor;
|
|
106
|
+
};
|
|
119
107
|
};
|
|
120
|
-
};
|
|
121
108
|
};
|
|
122
|
-
|
|
123
|
-
0 && (module.exports = {
|
|
124
|
-
createTransaction
|
|
125
|
-
});
|
|
109
|
+
exports.createTransaction = createTransaction;
|