@nymphjs/driver-postgresql 1.0.0-beta.6 → 1.0.0-beta.60
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/CHANGELOG.md +240 -0
- package/dist/PostgreSQLDriver.d.ts +43 -16
- package/dist/PostgreSQLDriver.js +368 -272
- package/dist/PostgreSQLDriver.js.map +1 -1
- package/dist/PostgreSQLDriver.test.js +3 -2
- package/dist/PostgreSQLDriver.test.js.map +1 -1
- package/dist/conf/d.d.ts +26 -0
- package/package.json +16 -18
- package/src/PostgreSQLDriver.test.ts +2 -2
- package/src/PostgreSQLDriver.ts +671 -637
- package/tsconfig.json +1 -1
- package/typedoc.json +4 -0
- package/dist/runPostgresqlSync.js +0 -35
- package/src/runPostgresqlSync.js +0 -35
- package/src/testpostgresql.js +0 -59
package/src/PostgreSQLDriver.ts
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
|
-
import cp from 'child_process';
|
|
2
1
|
import { Pool, PoolClient, PoolConfig, QueryResult } from 'pg';
|
|
3
2
|
import format from 'pg-format';
|
|
4
3
|
import {
|
|
5
4
|
NymphDriver,
|
|
6
|
-
EntityConstructor,
|
|
7
|
-
EntityData,
|
|
8
|
-
EntityInterface,
|
|
9
|
-
|
|
5
|
+
type EntityConstructor,
|
|
6
|
+
type EntityData,
|
|
7
|
+
type EntityInterface,
|
|
8
|
+
type EntityInstanceType,
|
|
9
|
+
type SerializedEntityData,
|
|
10
|
+
type FormattedSelector,
|
|
11
|
+
type Options,
|
|
12
|
+
type Selector,
|
|
13
|
+
EntityUniqueConstraintError,
|
|
10
14
|
InvalidParametersError,
|
|
11
15
|
NotConfiguredError,
|
|
12
16
|
QueryFailedError,
|
|
13
17
|
UnableToConnectError,
|
|
14
|
-
FormattedSelector,
|
|
15
|
-
Options,
|
|
16
|
-
Selector,
|
|
17
18
|
xor,
|
|
18
19
|
} from '@nymphjs/nymph';
|
|
19
20
|
import { makeTableSuffix } from '@nymphjs/guid';
|
|
@@ -56,7 +57,7 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
56
57
|
constructor(
|
|
57
58
|
config: Partial<PostgreSQLDriverConfig>,
|
|
58
59
|
link?: Pool,
|
|
59
|
-
transaction?: PostgreSQLDriverTransaction
|
|
60
|
+
transaction?: PostgreSQLDriverTransaction,
|
|
60
61
|
) {
|
|
61
62
|
super();
|
|
62
63
|
this.config = { ...defaults, ...config };
|
|
@@ -82,14 +83,31 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
82
83
|
}
|
|
83
84
|
}
|
|
84
85
|
|
|
86
|
+
/**
|
|
87
|
+
* This is used internally by Nymph. Don't call it yourself.
|
|
88
|
+
*
|
|
89
|
+
* @returns A clone of this instance.
|
|
90
|
+
*/
|
|
91
|
+
public clone() {
|
|
92
|
+
return new PostgreSQLDriver(
|
|
93
|
+
this.config,
|
|
94
|
+
this.link,
|
|
95
|
+
this.transaction ?? undefined,
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
85
99
|
private getConnection(): Promise<PostgreSQLDriverConnection> {
|
|
86
100
|
if (this.transaction != null && this.transaction.connection != null) {
|
|
87
101
|
return Promise.resolve(this.transaction.connection);
|
|
88
102
|
}
|
|
89
103
|
return new Promise((resolve, reject) =>
|
|
90
104
|
this.link.connect((err, client, done) =>
|
|
91
|
-
err
|
|
92
|
-
|
|
105
|
+
err
|
|
106
|
+
? reject(err)
|
|
107
|
+
: client
|
|
108
|
+
? resolve({ client, done })
|
|
109
|
+
: reject('No client returned from connect.'),
|
|
110
|
+
),
|
|
93
111
|
);
|
|
94
112
|
}
|
|
95
113
|
|
|
@@ -105,8 +123,12 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
105
123
|
const connection: PostgreSQLDriverConnection = await new Promise(
|
|
106
124
|
(resolve, reject) =>
|
|
107
125
|
this.link.connect((err, client, done) =>
|
|
108
|
-
err
|
|
109
|
-
|
|
126
|
+
err
|
|
127
|
+
? reject(err)
|
|
128
|
+
: client
|
|
129
|
+
? resolve({ client, done })
|
|
130
|
+
: reject('No client returned from connect.'),
|
|
131
|
+
),
|
|
110
132
|
);
|
|
111
133
|
await new Promise((resolve, reject) =>
|
|
112
134
|
connection.client.query('SELECT 1;', [], (err, res) => {
|
|
@@ -114,7 +136,7 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
114
136
|
reject(err);
|
|
115
137
|
}
|
|
116
138
|
resolve(0);
|
|
117
|
-
})
|
|
139
|
+
}),
|
|
118
140
|
);
|
|
119
141
|
connection.done();
|
|
120
142
|
}
|
|
@@ -135,7 +157,7 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
135
157
|
this.postgresqlConfig.database === 'nymph'
|
|
136
158
|
) {
|
|
137
159
|
throw new NotConfiguredError(
|
|
138
|
-
"It seems the config hasn't been set up correctly."
|
|
160
|
+
"It seems the config hasn't been set up correctly.",
|
|
139
161
|
);
|
|
140
162
|
} else {
|
|
141
163
|
throw new UnableToConnectError('Could not connect: ' + e?.message);
|
|
@@ -177,65 +199,65 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
177
199
|
* @param etype The entity type to create a table for. If this is blank, the default tables are created.
|
|
178
200
|
* @returns True on success, false on failure.
|
|
179
201
|
*/
|
|
180
|
-
private createTables(etype: string | null = null) {
|
|
202
|
+
private async createTables(etype: string | null = null) {
|
|
181
203
|
if (etype != null) {
|
|
182
204
|
// Create the entity table.
|
|
183
|
-
this.
|
|
205
|
+
await this.queryRun(
|
|
184
206
|
`CREATE TABLE IF NOT EXISTS ${PostgreSQLDriver.escape(
|
|
185
|
-
`${this.prefix}entities_${etype}
|
|
207
|
+
`${this.prefix}entities_${etype}`,
|
|
186
208
|
)} (
|
|
187
209
|
"guid" BYTEA NOT NULL,
|
|
188
210
|
"tags" TEXT[],
|
|
189
211
|
"cdate" DOUBLE PRECISION NOT NULL,
|
|
190
212
|
"mdate" DOUBLE PRECISION NOT NULL,
|
|
191
213
|
PRIMARY KEY ("guid")
|
|
192
|
-
) WITH ( OIDS=FALSE )
|
|
214
|
+
) WITH ( OIDS=FALSE );`,
|
|
193
215
|
);
|
|
194
|
-
this.
|
|
216
|
+
await this.queryRun(
|
|
195
217
|
`ALTER TABLE ${PostgreSQLDriver.escape(
|
|
196
|
-
`${this.prefix}entities_${etype}
|
|
197
|
-
)} OWNER TO ${PostgreSQLDriver.escape(this.config.user)}
|
|
218
|
+
`${this.prefix}entities_${etype}`,
|
|
219
|
+
)} OWNER TO ${PostgreSQLDriver.escape(this.config.user)};`,
|
|
198
220
|
);
|
|
199
|
-
this.
|
|
221
|
+
await this.queryRun(
|
|
200
222
|
`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(
|
|
201
|
-
`${this.prefix}entities_${etype}_id_cdate
|
|
202
|
-
)}
|
|
223
|
+
`${this.prefix}entities_${etype}_id_cdate`,
|
|
224
|
+
)};`,
|
|
203
225
|
);
|
|
204
|
-
this.
|
|
226
|
+
await this.queryRun(
|
|
205
227
|
`CREATE INDEX ${PostgreSQLDriver.escape(
|
|
206
|
-
`${this.prefix}entities_${etype}_id_cdate
|
|
228
|
+
`${this.prefix}entities_${etype}_id_cdate`,
|
|
207
229
|
)} ON ${PostgreSQLDriver.escape(
|
|
208
|
-
`${this.prefix}entities_${etype}
|
|
209
|
-
)} USING btree ("cdate")
|
|
230
|
+
`${this.prefix}entities_${etype}`,
|
|
231
|
+
)} USING btree ("cdate");`,
|
|
210
232
|
);
|
|
211
|
-
this.
|
|
233
|
+
await this.queryRun(
|
|
212
234
|
`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(
|
|
213
|
-
`${this.prefix}entities_${etype}_id_mdate
|
|
214
|
-
)}
|
|
235
|
+
`${this.prefix}entities_${etype}_id_mdate`,
|
|
236
|
+
)};`,
|
|
215
237
|
);
|
|
216
|
-
this.
|
|
238
|
+
await this.queryRun(
|
|
217
239
|
`CREATE INDEX ${PostgreSQLDriver.escape(
|
|
218
|
-
`${this.prefix}entities_${etype}_id_mdate
|
|
240
|
+
`${this.prefix}entities_${etype}_id_mdate`,
|
|
219
241
|
)} ON ${PostgreSQLDriver.escape(
|
|
220
|
-
`${this.prefix}entities_${etype}
|
|
221
|
-
)} USING btree ("mdate")
|
|
242
|
+
`${this.prefix}entities_${etype}`,
|
|
243
|
+
)} USING btree ("mdate");`,
|
|
222
244
|
);
|
|
223
|
-
this.
|
|
245
|
+
await this.queryRun(
|
|
224
246
|
`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(
|
|
225
|
-
`${this.prefix}entities_${etype}_id_tags
|
|
226
|
-
)}
|
|
247
|
+
`${this.prefix}entities_${etype}_id_tags`,
|
|
248
|
+
)};`,
|
|
227
249
|
);
|
|
228
|
-
this.
|
|
250
|
+
await this.queryRun(
|
|
229
251
|
`CREATE INDEX ${PostgreSQLDriver.escape(
|
|
230
|
-
`${this.prefix}entities_${etype}_id_tags
|
|
252
|
+
`${this.prefix}entities_${etype}_id_tags`,
|
|
231
253
|
)} ON ${PostgreSQLDriver.escape(
|
|
232
|
-
`${this.prefix}entities_${etype}
|
|
233
|
-
)} USING gin ("tags")
|
|
254
|
+
`${this.prefix}entities_${etype}`,
|
|
255
|
+
)} USING gin ("tags");`,
|
|
234
256
|
);
|
|
235
257
|
// Create the data table.
|
|
236
|
-
this.
|
|
258
|
+
await this.queryRun(
|
|
237
259
|
`CREATE TABLE IF NOT EXISTS ${PostgreSQLDriver.escape(
|
|
238
|
-
`${this.prefix}data_${etype}
|
|
260
|
+
`${this.prefix}data_${etype}`,
|
|
239
261
|
)} (
|
|
240
262
|
"guid" BYTEA NOT NULL,
|
|
241
263
|
"name" TEXT NOT NULL,
|
|
@@ -243,67 +265,67 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
243
265
|
PRIMARY KEY ("guid", "name"),
|
|
244
266
|
FOREIGN KEY ("guid")
|
|
245
267
|
REFERENCES ${PostgreSQLDriver.escape(
|
|
246
|
-
`${this.prefix}entities_${etype}
|
|
268
|
+
`${this.prefix}entities_${etype}`,
|
|
247
269
|
)} ("guid") MATCH SIMPLE ON UPDATE NO ACTION ON DELETE CASCADE
|
|
248
|
-
) WITH ( OIDS=FALSE )
|
|
270
|
+
) WITH ( OIDS=FALSE );`,
|
|
249
271
|
);
|
|
250
|
-
this.
|
|
272
|
+
await this.queryRun(
|
|
251
273
|
`ALTER TABLE ${PostgreSQLDriver.escape(
|
|
252
|
-
`${this.prefix}data_${etype}
|
|
253
|
-
)} OWNER TO ${PostgreSQLDriver.escape(this.config.user)}
|
|
274
|
+
`${this.prefix}data_${etype}`,
|
|
275
|
+
)} OWNER TO ${PostgreSQLDriver.escape(this.config.user)};`,
|
|
254
276
|
);
|
|
255
|
-
this.
|
|
277
|
+
await this.queryRun(
|
|
256
278
|
`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(
|
|
257
|
-
`${this.prefix}data_${etype}_id_guid
|
|
258
|
-
)}
|
|
279
|
+
`${this.prefix}data_${etype}_id_guid`,
|
|
280
|
+
)};`,
|
|
259
281
|
);
|
|
260
|
-
this.
|
|
282
|
+
await this.queryRun(
|
|
261
283
|
`CREATE INDEX ${PostgreSQLDriver.escape(
|
|
262
|
-
`${this.prefix}data_${etype}_id_guid
|
|
284
|
+
`${this.prefix}data_${etype}_id_guid`,
|
|
263
285
|
)} ON ${PostgreSQLDriver.escape(
|
|
264
|
-
`${this.prefix}data_${etype}
|
|
265
|
-
)} USING btree ("guid")
|
|
286
|
+
`${this.prefix}data_${etype}`,
|
|
287
|
+
)} USING btree ("guid");`,
|
|
266
288
|
);
|
|
267
|
-
this.
|
|
289
|
+
await this.queryRun(
|
|
268
290
|
`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(
|
|
269
|
-
`${this.prefix}data_${etype}_id_name
|
|
270
|
-
)}
|
|
291
|
+
`${this.prefix}data_${etype}_id_name`,
|
|
292
|
+
)};`,
|
|
271
293
|
);
|
|
272
|
-
this.
|
|
294
|
+
await this.queryRun(
|
|
273
295
|
`CREATE INDEX ${PostgreSQLDriver.escape(
|
|
274
|
-
`${this.prefix}data_${etype}_id_name
|
|
296
|
+
`${this.prefix}data_${etype}_id_name`,
|
|
275
297
|
)} ON ${PostgreSQLDriver.escape(
|
|
276
|
-
`${this.prefix}data_${etype}
|
|
277
|
-
)} USING btree ("name")
|
|
298
|
+
`${this.prefix}data_${etype}`,
|
|
299
|
+
)} USING btree ("name");`,
|
|
278
300
|
);
|
|
279
|
-
this.
|
|
301
|
+
await this.queryRun(
|
|
280
302
|
`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(
|
|
281
|
-
`${this.prefix}data_${etype}_id_guid_name__user
|
|
282
|
-
)}
|
|
303
|
+
`${this.prefix}data_${etype}_id_guid_name__user`,
|
|
304
|
+
)};`,
|
|
283
305
|
);
|
|
284
|
-
this.
|
|
306
|
+
await this.queryRun(
|
|
285
307
|
`CREATE INDEX ${PostgreSQLDriver.escape(
|
|
286
|
-
`${this.prefix}data_${etype}_id_guid_name__user
|
|
308
|
+
`${this.prefix}data_${etype}_id_guid_name__user`,
|
|
287
309
|
)} ON ${PostgreSQLDriver.escape(
|
|
288
|
-
`${this.prefix}data_${etype}
|
|
289
|
-
)} USING btree ("guid") WHERE "name" = 'user'::text
|
|
310
|
+
`${this.prefix}data_${etype}`,
|
|
311
|
+
)} USING btree ("guid") WHERE "name" = 'user'::text;`,
|
|
290
312
|
);
|
|
291
|
-
this.
|
|
313
|
+
await this.queryRun(
|
|
292
314
|
`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(
|
|
293
|
-
`${this.prefix}data_${etype}_id_guid_name__group
|
|
294
|
-
)}
|
|
315
|
+
`${this.prefix}data_${etype}_id_guid_name__group`,
|
|
316
|
+
)};`,
|
|
295
317
|
);
|
|
296
|
-
this.
|
|
318
|
+
await this.queryRun(
|
|
297
319
|
`CREATE INDEX ${PostgreSQLDriver.escape(
|
|
298
|
-
`${this.prefix}data_${etype}_id_guid_name__group
|
|
320
|
+
`${this.prefix}data_${etype}_id_guid_name__group`,
|
|
299
321
|
)} ON ${PostgreSQLDriver.escape(
|
|
300
|
-
`${this.prefix}data_${etype}
|
|
301
|
-
)} USING btree ("guid") WHERE "name" = 'group'::text
|
|
322
|
+
`${this.prefix}data_${etype}`,
|
|
323
|
+
)} USING btree ("guid") WHERE "name" = 'group'::text;`,
|
|
302
324
|
);
|
|
303
325
|
// Create the data comparisons table.
|
|
304
|
-
this.
|
|
326
|
+
await this.queryRun(
|
|
305
327
|
`CREATE TABLE IF NOT EXISTS ${PostgreSQLDriver.escape(
|
|
306
|
-
`${this.prefix}comparisons_${etype}
|
|
328
|
+
`${this.prefix}comparisons_${etype}`,
|
|
307
329
|
)} (
|
|
308
330
|
"guid" BYTEA NOT NULL,
|
|
309
331
|
"name" TEXT NOT NULL,
|
|
@@ -313,67 +335,67 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
313
335
|
PRIMARY KEY ("guid", "name"),
|
|
314
336
|
FOREIGN KEY ("guid")
|
|
315
337
|
REFERENCES ${PostgreSQLDriver.escape(
|
|
316
|
-
`${this.prefix}entities_${etype}
|
|
338
|
+
`${this.prefix}entities_${etype}`,
|
|
317
339
|
)} ("guid") MATCH SIMPLE ON UPDATE NO ACTION ON DELETE CASCADE
|
|
318
|
-
) WITH ( OIDS=FALSE )
|
|
340
|
+
) WITH ( OIDS=FALSE );`,
|
|
319
341
|
);
|
|
320
|
-
this.
|
|
342
|
+
await this.queryRun(
|
|
321
343
|
`ALTER TABLE ${PostgreSQLDriver.escape(
|
|
322
|
-
`${this.prefix}comparisons_${etype}
|
|
323
|
-
)} OWNER TO ${PostgreSQLDriver.escape(this.config.user)}
|
|
344
|
+
`${this.prefix}comparisons_${etype}`,
|
|
345
|
+
)} OWNER TO ${PostgreSQLDriver.escape(this.config.user)};`,
|
|
324
346
|
);
|
|
325
|
-
this.
|
|
347
|
+
await this.queryRun(
|
|
326
348
|
`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(
|
|
327
|
-
`${this.prefix}comparisons_${etype}_id_guid
|
|
328
|
-
)}
|
|
349
|
+
`${this.prefix}comparisons_${etype}_id_guid`,
|
|
350
|
+
)};`,
|
|
329
351
|
);
|
|
330
|
-
this.
|
|
352
|
+
await this.queryRun(
|
|
331
353
|
`CREATE INDEX ${PostgreSQLDriver.escape(
|
|
332
|
-
`${this.prefix}comparisons_${etype}_id_guid
|
|
354
|
+
`${this.prefix}comparisons_${etype}_id_guid`,
|
|
333
355
|
)} ON ${PostgreSQLDriver.escape(
|
|
334
|
-
`${this.prefix}comparisons_${etype}
|
|
335
|
-
)} USING btree ("guid")
|
|
356
|
+
`${this.prefix}comparisons_${etype}`,
|
|
357
|
+
)} USING btree ("guid");`,
|
|
336
358
|
);
|
|
337
|
-
this.
|
|
359
|
+
await this.queryRun(
|
|
338
360
|
`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(
|
|
339
|
-
`${this.prefix}comparisons_${etype}_id_name
|
|
340
|
-
)}
|
|
361
|
+
`${this.prefix}comparisons_${etype}_id_name`,
|
|
362
|
+
)};`,
|
|
341
363
|
);
|
|
342
|
-
this.
|
|
364
|
+
await this.queryRun(
|
|
343
365
|
`CREATE INDEX ${PostgreSQLDriver.escape(
|
|
344
|
-
`${this.prefix}comparisons_${etype}_id_name
|
|
366
|
+
`${this.prefix}comparisons_${etype}_id_name`,
|
|
345
367
|
)} ON ${PostgreSQLDriver.escape(
|
|
346
|
-
`${this.prefix}comparisons_${etype}
|
|
347
|
-
)} USING btree ("name")
|
|
368
|
+
`${this.prefix}comparisons_${etype}`,
|
|
369
|
+
)} USING btree ("name");`,
|
|
348
370
|
);
|
|
349
|
-
this.
|
|
371
|
+
await this.queryRun(
|
|
350
372
|
`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(
|
|
351
|
-
`${this.prefix}comparisons_${etype}_id_guid_name_truthy
|
|
352
|
-
)}
|
|
373
|
+
`${this.prefix}comparisons_${etype}_id_guid_name_truthy`,
|
|
374
|
+
)};`,
|
|
353
375
|
);
|
|
354
|
-
this.
|
|
376
|
+
await this.queryRun(
|
|
355
377
|
`CREATE INDEX ${PostgreSQLDriver.escape(
|
|
356
|
-
`${this.prefix}comparisons_${etype}_id_guid_name_truthy
|
|
378
|
+
`${this.prefix}comparisons_${etype}_id_guid_name_truthy`,
|
|
357
379
|
)} ON ${PostgreSQLDriver.escape(
|
|
358
|
-
`${this.prefix}comparisons_${etype}
|
|
359
|
-
)} USING btree ("guid", "name") WHERE "truthy" = TRUE
|
|
380
|
+
`${this.prefix}comparisons_${etype}`,
|
|
381
|
+
)} USING btree ("guid", "name") WHERE "truthy" = TRUE;`,
|
|
360
382
|
);
|
|
361
|
-
this.
|
|
383
|
+
await this.queryRun(
|
|
362
384
|
`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(
|
|
363
|
-
`${this.prefix}comparisons_${etype}_id_guid_name_falsy
|
|
364
|
-
)}
|
|
385
|
+
`${this.prefix}comparisons_${etype}_id_guid_name_falsy`,
|
|
386
|
+
)};`,
|
|
365
387
|
);
|
|
366
|
-
this.
|
|
388
|
+
await this.queryRun(
|
|
367
389
|
`CREATE INDEX ${PostgreSQLDriver.escape(
|
|
368
|
-
`${this.prefix}comparisons_${etype}_id_guid_name_falsy
|
|
390
|
+
`${this.prefix}comparisons_${etype}_id_guid_name_falsy`,
|
|
369
391
|
)} ON ${PostgreSQLDriver.escape(
|
|
370
|
-
`${this.prefix}comparisons_${etype}
|
|
371
|
-
)} USING btree ("guid", "name") WHERE "truthy" <> TRUE
|
|
392
|
+
`${this.prefix}comparisons_${etype}`,
|
|
393
|
+
)} USING btree ("guid", "name") WHERE "truthy" <> TRUE;`,
|
|
372
394
|
);
|
|
373
395
|
// Create the references table.
|
|
374
|
-
this.
|
|
396
|
+
await this.queryRun(
|
|
375
397
|
`CREATE TABLE IF NOT EXISTS ${PostgreSQLDriver.escape(
|
|
376
|
-
`${this.prefix}references_${etype}
|
|
398
|
+
`${this.prefix}references_${etype}`,
|
|
377
399
|
)} (
|
|
378
400
|
"guid" BYTEA NOT NULL,
|
|
379
401
|
"name" TEXT NOT NULL,
|
|
@@ -381,66 +403,80 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
381
403
|
PRIMARY KEY ("guid", "name", "reference"),
|
|
382
404
|
FOREIGN KEY ("guid")
|
|
383
405
|
REFERENCES ${PostgreSQLDriver.escape(
|
|
384
|
-
`${this.prefix}entities_${etype}
|
|
406
|
+
`${this.prefix}entities_${etype}`,
|
|
385
407
|
)} ("guid") MATCH SIMPLE ON UPDATE NO ACTION ON DELETE CASCADE
|
|
386
|
-
) WITH ( OIDS=FALSE )
|
|
408
|
+
) WITH ( OIDS=FALSE );`,
|
|
387
409
|
);
|
|
388
|
-
this.
|
|
410
|
+
await this.queryRun(
|
|
389
411
|
`ALTER TABLE ${PostgreSQLDriver.escape(
|
|
390
|
-
`${this.prefix}references_${etype}
|
|
391
|
-
)} OWNER TO ${PostgreSQLDriver.escape(this.config.user)}
|
|
412
|
+
`${this.prefix}references_${etype}`,
|
|
413
|
+
)} OWNER TO ${PostgreSQLDriver.escape(this.config.user)};`,
|
|
392
414
|
);
|
|
393
|
-
this.
|
|
415
|
+
await this.queryRun(
|
|
394
416
|
`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(
|
|
395
|
-
`${this.prefix}references_${etype}_id_guid
|
|
396
|
-
)}
|
|
417
|
+
`${this.prefix}references_${etype}_id_guid`,
|
|
418
|
+
)};`,
|
|
397
419
|
);
|
|
398
|
-
this.
|
|
420
|
+
await this.queryRun(
|
|
399
421
|
`CREATE INDEX ${PostgreSQLDriver.escape(
|
|
400
|
-
`${this.prefix}references_${etype}_id_guid
|
|
422
|
+
`${this.prefix}references_${etype}_id_guid`,
|
|
401
423
|
)} ON ${PostgreSQLDriver.escape(
|
|
402
|
-
`${this.prefix}references_${etype}
|
|
403
|
-
)} USING btree ("guid")
|
|
424
|
+
`${this.prefix}references_${etype}`,
|
|
425
|
+
)} USING btree ("guid");`,
|
|
404
426
|
);
|
|
405
|
-
this.
|
|
427
|
+
await this.queryRun(
|
|
406
428
|
`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(
|
|
407
|
-
`${this.prefix}references_${etype}_id_name
|
|
408
|
-
)}
|
|
429
|
+
`${this.prefix}references_${etype}_id_name`,
|
|
430
|
+
)};`,
|
|
409
431
|
);
|
|
410
|
-
this.
|
|
432
|
+
await this.queryRun(
|
|
411
433
|
`CREATE INDEX ${PostgreSQLDriver.escape(
|
|
412
|
-
`${this.prefix}references_${etype}_id_name
|
|
434
|
+
`${this.prefix}references_${etype}_id_name`,
|
|
413
435
|
)} ON ${PostgreSQLDriver.escape(
|
|
414
|
-
`${this.prefix}references_${etype}
|
|
415
|
-
)} USING btree ("name")
|
|
436
|
+
`${this.prefix}references_${etype}`,
|
|
437
|
+
)} USING btree ("name");`,
|
|
416
438
|
);
|
|
417
|
-
this.
|
|
439
|
+
await this.queryRun(
|
|
418
440
|
`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(
|
|
419
|
-
`${this.prefix}references_${etype}_id_reference
|
|
420
|
-
)}
|
|
441
|
+
`${this.prefix}references_${etype}_id_reference`,
|
|
442
|
+
)};`,
|
|
421
443
|
);
|
|
422
|
-
this.
|
|
444
|
+
await this.queryRun(
|
|
423
445
|
`CREATE INDEX ${PostgreSQLDriver.escape(
|
|
424
|
-
`${this.prefix}references_${etype}_id_reference
|
|
446
|
+
`${this.prefix}references_${etype}_id_reference`,
|
|
425
447
|
)} ON ${PostgreSQLDriver.escape(
|
|
426
|
-
`${this.prefix}references_${etype}
|
|
427
|
-
)} USING btree ("reference")
|
|
448
|
+
`${this.prefix}references_${etype}`,
|
|
449
|
+
)} USING btree ("reference");`,
|
|
450
|
+
);
|
|
451
|
+
// Create the unique strings table.
|
|
452
|
+
await this.queryRun(
|
|
453
|
+
`CREATE TABLE IF NOT EXISTS ${PostgreSQLDriver.escape(
|
|
454
|
+
`${this.prefix}uniques_${etype}`,
|
|
455
|
+
)} (
|
|
456
|
+
"guid" BYTEA NOT NULL,
|
|
457
|
+
"unique" TEXT NOT NULL UNIQUE,
|
|
458
|
+
PRIMARY KEY ("guid", "unique"),
|
|
459
|
+
FOREIGN KEY ("guid")
|
|
460
|
+
REFERENCES ${PostgreSQLDriver.escape(
|
|
461
|
+
`${this.prefix}entities_${etype}`,
|
|
462
|
+
)} ("guid") MATCH SIMPLE ON UPDATE NO ACTION ON DELETE CASCADE
|
|
463
|
+
) WITH ( OIDS=FALSE );`,
|
|
428
464
|
);
|
|
429
465
|
} else {
|
|
430
466
|
// Create the UID table.
|
|
431
|
-
this.
|
|
467
|
+
await this.queryRun(
|
|
432
468
|
`CREATE TABLE IF NOT EXISTS ${PostgreSQLDriver.escape(
|
|
433
|
-
`${this.prefix}uids
|
|
469
|
+
`${this.prefix}uids`,
|
|
434
470
|
)} (
|
|
435
471
|
"name" TEXT NOT NULL,
|
|
436
472
|
"cur_uid" BIGINT NOT NULL,
|
|
437
473
|
PRIMARY KEY ("name")
|
|
438
|
-
) WITH ( OIDS = FALSE )
|
|
474
|
+
) WITH ( OIDS = FALSE );`,
|
|
439
475
|
);
|
|
440
|
-
this.
|
|
476
|
+
await this.queryRun(
|
|
441
477
|
`ALTER TABLE ${PostgreSQLDriver.escape(
|
|
442
|
-
`${this.prefix}uids
|
|
443
|
-
)} OWNER TO ${PostgreSQLDriver.escape(this.config.user)}
|
|
478
|
+
`${this.prefix}uids`,
|
|
479
|
+
)} OWNER TO ${PostgreSQLDriver.escape(this.config.user)};`,
|
|
444
480
|
);
|
|
445
481
|
}
|
|
446
482
|
return true;
|
|
@@ -448,7 +484,7 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
448
484
|
|
|
449
485
|
private translateQuery(
|
|
450
486
|
origQuery: string,
|
|
451
|
-
origParams: { [k: string]: any }
|
|
487
|
+
origParams: { [k: string]: any },
|
|
452
488
|
): { query: string; params: any[] } {
|
|
453
489
|
const params: any[] = [];
|
|
454
490
|
let query = origQuery;
|
|
@@ -468,56 +504,33 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
468
504
|
private async query<T extends () => any>(
|
|
469
505
|
runQuery: T,
|
|
470
506
|
query: string,
|
|
471
|
-
etypes: string[] = []
|
|
507
|
+
etypes: string[] = [],
|
|
472
508
|
// @ts-ignore: The return type of T is a promise.
|
|
473
509
|
): ReturnType<T> {
|
|
474
510
|
try {
|
|
475
511
|
return await runQuery();
|
|
476
512
|
} catch (e: any) {
|
|
477
513
|
const errorCode = e?.code;
|
|
478
|
-
if (errorCode === '42P01' && this.createTables()) {
|
|
514
|
+
if (errorCode === '42P01' && (await this.createTables())) {
|
|
479
515
|
// If the tables don't exist yet, create them.
|
|
480
516
|
for (let etype of etypes) {
|
|
481
|
-
this.createTables(etype);
|
|
517
|
+
await this.createTables(etype);
|
|
482
518
|
}
|
|
483
519
|
try {
|
|
484
520
|
return await runQuery();
|
|
485
521
|
} catch (e2: any) {
|
|
486
522
|
throw new QueryFailedError(
|
|
487
523
|
'Query failed: ' + e2?.code + ' - ' + e2?.message,
|
|
488
|
-
query
|
|
524
|
+
query,
|
|
489
525
|
);
|
|
490
526
|
}
|
|
527
|
+
} else if (errorCode === '23505') {
|
|
528
|
+
throw new EntityUniqueConstraintError(`Unique constraint violation.`);
|
|
491
529
|
} else {
|
|
492
|
-
throw
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
private querySync<T extends () => any>(
|
|
498
|
-
runQuery: T,
|
|
499
|
-
query: string,
|
|
500
|
-
etypes: string[] = []
|
|
501
|
-
): ReturnType<T> {
|
|
502
|
-
try {
|
|
503
|
-
return runQuery();
|
|
504
|
-
} catch (e: any) {
|
|
505
|
-
const errorCode = e?.code;
|
|
506
|
-
if (errorCode === '42P01' && this.createTables()) {
|
|
507
|
-
// If the tables don't exist yet, create them.
|
|
508
|
-
for (let etype of etypes) {
|
|
509
|
-
this.createTables(etype);
|
|
510
|
-
}
|
|
511
|
-
try {
|
|
512
|
-
return runQuery();
|
|
513
|
-
} catch (e2: any) {
|
|
514
|
-
throw new QueryFailedError(
|
|
515
|
-
'Query failed: ' + e2?.code + ' - ' + e2?.message,
|
|
516
|
-
query
|
|
517
|
-
);
|
|
518
|
-
}
|
|
519
|
-
} else {
|
|
520
|
-
throw e;
|
|
530
|
+
throw new QueryFailedError(
|
|
531
|
+
'Query failed: ' + e?.code + ' - ' + e?.message,
|
|
532
|
+
query,
|
|
533
|
+
);
|
|
521
534
|
}
|
|
522
535
|
}
|
|
523
536
|
}
|
|
@@ -530,11 +543,11 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
530
543
|
}: {
|
|
531
544
|
etypes?: string[];
|
|
532
545
|
params?: { [k: string]: any };
|
|
533
|
-
} = {}
|
|
546
|
+
} = {},
|
|
534
547
|
) {
|
|
535
548
|
const { query: newQuery, params: newParams } = this.translateQuery(
|
|
536
549
|
query,
|
|
537
|
-
params
|
|
550
|
+
params,
|
|
538
551
|
);
|
|
539
552
|
return this.query(
|
|
540
553
|
async () => {
|
|
@@ -545,64 +558,17 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
545
558
|
.query(newQuery, newParams)
|
|
546
559
|
.then(
|
|
547
560
|
(results) => resolve(results),
|
|
548
|
-
(error) => reject(error)
|
|
561
|
+
(error) => reject(error),
|
|
549
562
|
);
|
|
550
563
|
} catch (e) {
|
|
551
564
|
reject(e);
|
|
552
565
|
}
|
|
553
|
-
}
|
|
566
|
+
},
|
|
554
567
|
);
|
|
555
568
|
return results.rows;
|
|
556
569
|
},
|
|
557
570
|
`${query} -- ${JSON.stringify(params)}`,
|
|
558
|
-
etypes
|
|
559
|
-
);
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
private queryIterSync(
|
|
563
|
-
query: string,
|
|
564
|
-
{
|
|
565
|
-
etypes = [],
|
|
566
|
-
params = {},
|
|
567
|
-
}: { etypes?: string[]; params?: { [k: string]: any } } = {}
|
|
568
|
-
) {
|
|
569
|
-
const { query: newQuery, params: newParams } = this.translateQuery(
|
|
570
|
-
query,
|
|
571
|
-
params
|
|
572
|
-
);
|
|
573
|
-
return this.querySync(
|
|
574
|
-
() => {
|
|
575
|
-
const output = cp.spawnSync(
|
|
576
|
-
process.argv0,
|
|
577
|
-
[__dirname + '/runPostgresqlSync.js'],
|
|
578
|
-
{
|
|
579
|
-
input: JSON.stringify({
|
|
580
|
-
postgresqlConfig: this.postgresqlConfig,
|
|
581
|
-
query: newQuery,
|
|
582
|
-
params: newParams,
|
|
583
|
-
}),
|
|
584
|
-
timeout: 30000,
|
|
585
|
-
maxBuffer: 100 * 1024 * 1024,
|
|
586
|
-
encoding: 'utf8',
|
|
587
|
-
windowsHide: true,
|
|
588
|
-
}
|
|
589
|
-
);
|
|
590
|
-
try {
|
|
591
|
-
return JSON.parse(output.stdout).rows;
|
|
592
|
-
} catch (e) {
|
|
593
|
-
// Do nothing.
|
|
594
|
-
}
|
|
595
|
-
if (output.status === 0) {
|
|
596
|
-
throw new Error('Unknown parse error.');
|
|
597
|
-
}
|
|
598
|
-
const err = JSON.parse(output.stderr);
|
|
599
|
-
const e = new Error(err.name);
|
|
600
|
-
for (const name in err) {
|
|
601
|
-
(e as any)[name] = err[name];
|
|
602
|
-
}
|
|
603
|
-
},
|
|
604
|
-
`${query} -- ${JSON.stringify(params)}`,
|
|
605
|
-
etypes
|
|
571
|
+
etypes,
|
|
606
572
|
);
|
|
607
573
|
}
|
|
608
574
|
|
|
@@ -614,11 +580,11 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
614
580
|
}: {
|
|
615
581
|
etypes?: string[];
|
|
616
582
|
params?: { [k: string]: any };
|
|
617
|
-
} = {}
|
|
583
|
+
} = {},
|
|
618
584
|
) {
|
|
619
585
|
const { query: newQuery, params: newParams } = this.translateQuery(
|
|
620
586
|
query,
|
|
621
|
-
params
|
|
587
|
+
params,
|
|
622
588
|
);
|
|
623
589
|
return this.query(
|
|
624
590
|
async () => {
|
|
@@ -629,17 +595,17 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
629
595
|
.query(newQuery, newParams)
|
|
630
596
|
.then(
|
|
631
597
|
(results) => resolve(results),
|
|
632
|
-
(error) => reject(error)
|
|
598
|
+
(error) => reject(error),
|
|
633
599
|
);
|
|
634
600
|
} catch (e) {
|
|
635
601
|
reject(e);
|
|
636
602
|
}
|
|
637
|
-
}
|
|
603
|
+
},
|
|
638
604
|
);
|
|
639
605
|
return results.rows[0];
|
|
640
606
|
},
|
|
641
607
|
`${query} -- ${JSON.stringify(params)}`,
|
|
642
|
-
etypes
|
|
608
|
+
etypes,
|
|
643
609
|
);
|
|
644
610
|
}
|
|
645
611
|
|
|
@@ -651,11 +617,11 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
651
617
|
}: {
|
|
652
618
|
etypes?: string[];
|
|
653
619
|
params?: { [k: string]: any };
|
|
654
|
-
} = {}
|
|
620
|
+
} = {},
|
|
655
621
|
) {
|
|
656
622
|
const { query: newQuery, params: newParams } = this.translateQuery(
|
|
657
623
|
query,
|
|
658
|
-
params
|
|
624
|
+
params,
|
|
659
625
|
);
|
|
660
626
|
return this.query(
|
|
661
627
|
async () => {
|
|
@@ -666,72 +632,24 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
666
632
|
.query(newQuery, newParams)
|
|
667
633
|
.then(
|
|
668
634
|
(results) => resolve(results),
|
|
669
|
-
(error) => reject(error)
|
|
635
|
+
(error) => reject(error),
|
|
670
636
|
);
|
|
671
637
|
} catch (e) {
|
|
672
638
|
reject(e);
|
|
673
639
|
}
|
|
674
|
-
}
|
|
640
|
+
},
|
|
675
641
|
);
|
|
676
642
|
return { rowCount: results.rowCount ?? 0 };
|
|
677
643
|
},
|
|
678
644
|
`${query} -- ${JSON.stringify(params)}`,
|
|
679
|
-
etypes
|
|
680
|
-
);
|
|
681
|
-
}
|
|
682
|
-
|
|
683
|
-
private queryRunSync(
|
|
684
|
-
query: string,
|
|
685
|
-
{
|
|
686
|
-
etypes = [],
|
|
687
|
-
params = {},
|
|
688
|
-
}: { etypes?: string[]; params?: { [k: string]: any } } = {}
|
|
689
|
-
) {
|
|
690
|
-
const { query: newQuery, params: newParams } = this.translateQuery(
|
|
691
|
-
query,
|
|
692
|
-
params
|
|
693
|
-
);
|
|
694
|
-
return this.querySync(
|
|
695
|
-
() => {
|
|
696
|
-
const output = cp.spawnSync(
|
|
697
|
-
process.argv0,
|
|
698
|
-
[__dirname + '/runPostgresqlSync.js'],
|
|
699
|
-
{
|
|
700
|
-
input: JSON.stringify({
|
|
701
|
-
postgresqlConfig: this.postgresqlConfig,
|
|
702
|
-
query: newQuery,
|
|
703
|
-
params: newParams,
|
|
704
|
-
}),
|
|
705
|
-
timeout: 30000,
|
|
706
|
-
maxBuffer: 100 * 1024 * 1024,
|
|
707
|
-
encoding: 'utf8',
|
|
708
|
-
windowsHide: true,
|
|
709
|
-
}
|
|
710
|
-
);
|
|
711
|
-
try {
|
|
712
|
-
const results = JSON.parse(output.stdout);
|
|
713
|
-
return { rowCount: results.rowCount ?? 0 };
|
|
714
|
-
} catch (e) {
|
|
715
|
-
// Do nothing.
|
|
716
|
-
}
|
|
717
|
-
if (output.status === 0) {
|
|
718
|
-
throw new Error('Unknown parse error.');
|
|
719
|
-
}
|
|
720
|
-
const err = JSON.parse(output.stderr);
|
|
721
|
-
const e = new Error(err.name);
|
|
722
|
-
for (const name in err) {
|
|
723
|
-
(e as any)[name] = err[name];
|
|
724
|
-
}
|
|
725
|
-
},
|
|
726
|
-
`${query} -- ${JSON.stringify(params)}`,
|
|
727
|
-
etypes
|
|
645
|
+
etypes,
|
|
728
646
|
);
|
|
729
647
|
}
|
|
730
648
|
|
|
731
649
|
public async commit(name: string) {
|
|
732
650
|
if (name == null || typeof name !== 'string' || name.length === 0) {
|
|
733
651
|
throw new InvalidParametersError(
|
|
734
|
-
'Transaction commit attempted without a name.'
|
|
652
|
+
'Transaction commit attempted without a name.',
|
|
735
653
|
);
|
|
736
654
|
}
|
|
737
655
|
if (!this.transaction || this.transaction.count === 0) {
|
|
@@ -751,7 +669,7 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
751
669
|
|
|
752
670
|
public async deleteEntityByID(
|
|
753
671
|
guid: string,
|
|
754
|
-
className?: EntityConstructor | string | null
|
|
672
|
+
className?: EntityConstructor | string | null,
|
|
755
673
|
) {
|
|
756
674
|
let EntityClass: EntityConstructor;
|
|
757
675
|
if (typeof className === 'string' || className == null) {
|
|
@@ -765,58 +683,71 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
765
683
|
try {
|
|
766
684
|
await this.queryRun(
|
|
767
685
|
`DELETE FROM ${PostgreSQLDriver.escape(
|
|
768
|
-
`${this.prefix}entities_${etype}
|
|
686
|
+
`${this.prefix}entities_${etype}`,
|
|
769
687
|
)} WHERE "guid"=decode(@guid, 'hex');`,
|
|
770
688
|
{
|
|
771
689
|
etypes: [etype],
|
|
772
690
|
params: {
|
|
773
691
|
guid,
|
|
774
692
|
},
|
|
775
|
-
}
|
|
693
|
+
},
|
|
776
694
|
);
|
|
777
695
|
await this.queryRun(
|
|
778
696
|
`DELETE FROM ${PostgreSQLDriver.escape(
|
|
779
|
-
`${this.prefix}data_${etype}
|
|
697
|
+
`${this.prefix}data_${etype}`,
|
|
780
698
|
)} WHERE "guid"=decode(@guid, 'hex');`,
|
|
781
699
|
{
|
|
782
700
|
etypes: [etype],
|
|
783
701
|
params: {
|
|
784
702
|
guid,
|
|
785
703
|
},
|
|
786
|
-
}
|
|
704
|
+
},
|
|
787
705
|
);
|
|
788
706
|
await this.queryRun(
|
|
789
707
|
`DELETE FROM ${PostgreSQLDriver.escape(
|
|
790
|
-
`${this.prefix}comparisons_${etype}
|
|
708
|
+
`${this.prefix}comparisons_${etype}`,
|
|
791
709
|
)} WHERE "guid"=decode(@guid, 'hex');`,
|
|
792
710
|
{
|
|
793
711
|
etypes: [etype],
|
|
794
712
|
params: {
|
|
795
713
|
guid,
|
|
796
714
|
},
|
|
797
|
-
}
|
|
715
|
+
},
|
|
798
716
|
);
|
|
799
717
|
await this.queryRun(
|
|
800
718
|
`DELETE FROM ${PostgreSQLDriver.escape(
|
|
801
|
-
`${this.prefix}references_${etype}
|
|
719
|
+
`${this.prefix}references_${etype}`,
|
|
802
720
|
)} WHERE "guid"=decode(@guid, 'hex');`,
|
|
803
721
|
{
|
|
804
722
|
etypes: [etype],
|
|
805
723
|
params: {
|
|
806
724
|
guid,
|
|
807
725
|
},
|
|
808
|
-
}
|
|
726
|
+
},
|
|
727
|
+
);
|
|
728
|
+
await this.queryRun(
|
|
729
|
+
`DELETE FROM ${PostgreSQLDriver.escape(
|
|
730
|
+
`${this.prefix}uniques_${etype}`,
|
|
731
|
+
)} WHERE "guid"=decode(@guid, 'hex');`,
|
|
732
|
+
{
|
|
733
|
+
etypes: [etype],
|
|
734
|
+
params: {
|
|
735
|
+
guid,
|
|
736
|
+
},
|
|
737
|
+
},
|
|
809
738
|
);
|
|
810
|
-
await this.commit('nymph-delete');
|
|
811
|
-
// Remove any cached versions of this entity.
|
|
812
|
-
if (this.nymph.config.cache) {
|
|
813
|
-
this.cleanCache(guid);
|
|
814
|
-
}
|
|
815
|
-
return true;
|
|
816
739
|
} catch (e: any) {
|
|
740
|
+
this.nymph.config.debugError('postgresql', `Delete entity error: "${e}"`);
|
|
817
741
|
await this.rollback('nymph-delete');
|
|
818
742
|
throw e;
|
|
819
743
|
}
|
|
744
|
+
|
|
745
|
+
await this.commit('nymph-delete');
|
|
746
|
+
// Remove any cached versions of this entity.
|
|
747
|
+
if (this.nymph.config.cache) {
|
|
748
|
+
this.cleanCache(guid);
|
|
749
|
+
}
|
|
750
|
+
return true;
|
|
820
751
|
}
|
|
821
752
|
|
|
822
753
|
public async deleteUID(name: string) {
|
|
@@ -825,13 +756,13 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
825
756
|
}
|
|
826
757
|
await this.queryRun(
|
|
827
758
|
`DELETE FROM ${PostgreSQLDriver.escape(
|
|
828
|
-
`${this.prefix}uids
|
|
759
|
+
`${this.prefix}uids`,
|
|
829
760
|
)} WHERE "name"=@name;`,
|
|
830
761
|
{
|
|
831
762
|
params: {
|
|
832
763
|
name,
|
|
833
764
|
},
|
|
834
|
-
}
|
|
765
|
+
},
|
|
835
766
|
);
|
|
836
767
|
return true;
|
|
837
768
|
}
|
|
@@ -852,8 +783,8 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
852
783
|
// Export UIDs.
|
|
853
784
|
let uids = await this.queryIter(
|
|
854
785
|
`SELECT * FROM ${PostgreSQLDriver.escape(
|
|
855
|
-
`${this.prefix}uids
|
|
856
|
-
)} ORDER BY "name"
|
|
786
|
+
`${this.prefix}uids`,
|
|
787
|
+
)} ORDER BY "name";`,
|
|
857
788
|
);
|
|
858
789
|
for (const uid of uids) {
|
|
859
790
|
writeLine(`<${uid.name}>[${uid.cur_uid}]`);
|
|
@@ -867,7 +798,7 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
867
798
|
|
|
868
799
|
// Get the etypes.
|
|
869
800
|
const tables = await this.queryIter(
|
|
870
|
-
'SELECT relname FROM pg_stat_user_tables ORDER BY relname;'
|
|
801
|
+
'SELECT relname FROM pg_stat_user_tables ORDER BY relname;',
|
|
871
802
|
);
|
|
872
803
|
const etypes = [];
|
|
873
804
|
for (const tableRow of tables) {
|
|
@@ -884,12 +815,12 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
884
815
|
`SELECT encode(e."guid", 'hex') AS "guid", e."tags", e."cdate", e."mdate", d."name" AS "dname", d."value" AS "dvalue", c."string", c."number"
|
|
885
816
|
FROM ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}`)} e
|
|
886
817
|
LEFT JOIN ${PostgreSQLDriver.escape(
|
|
887
|
-
`${this.prefix}data_${etype}
|
|
818
|
+
`${this.prefix}data_${etype}`,
|
|
888
819
|
)} d ON e."guid"=d."guid"
|
|
889
820
|
INNER JOIN ${PostgreSQLDriver.escape(
|
|
890
|
-
`${this.prefix}comparisons_${etype}
|
|
821
|
+
`${this.prefix}comparisons_${etype}`,
|
|
891
822
|
)} c ON d."guid"=c."guid" AND d."name"=c."name"
|
|
892
|
-
ORDER BY e."guid"
|
|
823
|
+
ORDER BY e."guid";`,
|
|
893
824
|
)
|
|
894
825
|
)[Symbol.iterator]();
|
|
895
826
|
let datum = dataIterator.next();
|
|
@@ -942,7 +873,7 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
942
873
|
params: { [k: string]: any } = {},
|
|
943
874
|
subquery = false,
|
|
944
875
|
tableSuffix = '',
|
|
945
|
-
etypes: string[] = []
|
|
876
|
+
etypes: string[] = [],
|
|
946
877
|
) {
|
|
947
878
|
if (typeof options.class?.alterOptions === 'function') {
|
|
948
879
|
options = options.class.alterOptions(options);
|
|
@@ -953,10 +884,11 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
953
884
|
const fTable = `f${tableSuffix}`;
|
|
954
885
|
const ieTable = `ie${tableSuffix}`;
|
|
955
886
|
const countTable = `count${tableSuffix}`;
|
|
887
|
+
const sTable = `s${tableSuffix}`;
|
|
956
888
|
const sort = options.sort ?? 'cdate';
|
|
957
889
|
const queryParts = this.iterateSelectorsForQuery(
|
|
958
890
|
formattedSelectors,
|
|
959
|
-
(key, value, typeIsOr, typeIsNot) => {
|
|
891
|
+
({ key, value, typeIsOr, typeIsNot }) => {
|
|
960
892
|
const clauseNot = key.startsWith('!');
|
|
961
893
|
let curQuery = '';
|
|
962
894
|
for (const curValue of value) {
|
|
@@ -1038,7 +970,7 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
1038
970
|
ieTable +
|
|
1039
971
|
'."guid" IN (SELECT "guid" FROM ' +
|
|
1040
972
|
PostgreSQLDriver.escape(
|
|
1041
|
-
this.prefix + 'comparisons_' + etype
|
|
973
|
+
this.prefix + 'comparisons_' + etype,
|
|
1042
974
|
) +
|
|
1043
975
|
' WHERE "name"=@' +
|
|
1044
976
|
name +
|
|
@@ -1088,7 +1020,7 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
1088
1020
|
ieTable +
|
|
1089
1021
|
'."guid" IN (SELECT "guid" FROM ' +
|
|
1090
1022
|
PostgreSQLDriver.escape(
|
|
1091
|
-
this.prefix + 'comparisons_' + etype
|
|
1023
|
+
this.prefix + 'comparisons_' + etype,
|
|
1092
1024
|
) +
|
|
1093
1025
|
' WHERE "name"=@' +
|
|
1094
1026
|
name +
|
|
@@ -1108,7 +1040,7 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
1108
1040
|
ieTable +
|
|
1109
1041
|
'."guid" IN (SELECT "guid" FROM ' +
|
|
1110
1042
|
PostgreSQLDriver.escape(
|
|
1111
|
-
this.prefix + 'comparisons_' + etype
|
|
1043
|
+
this.prefix + 'comparisons_' + etype,
|
|
1112
1044
|
) +
|
|
1113
1045
|
' WHERE "name"=@' +
|
|
1114
1046
|
name +
|
|
@@ -1210,7 +1142,7 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
1210
1142
|
ieTable +
|
|
1211
1143
|
'."guid" IN (SELECT "guid" FROM ' +
|
|
1212
1144
|
PostgreSQLDriver.escape(
|
|
1213
|
-
this.prefix + 'comparisons_' + etype
|
|
1145
|
+
this.prefix + 'comparisons_' + etype,
|
|
1214
1146
|
) +
|
|
1215
1147
|
' WHERE "name"=@' +
|
|
1216
1148
|
name +
|
|
@@ -1275,7 +1207,7 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
1275
1207
|
ieTable +
|
|
1276
1208
|
'."guid" IN (SELECT "guid" FROM ' +
|
|
1277
1209
|
PostgreSQLDriver.escape(
|
|
1278
|
-
this.prefix + 'comparisons_' + etype
|
|
1210
|
+
this.prefix + 'comparisons_' + etype,
|
|
1279
1211
|
) +
|
|
1280
1212
|
' WHERE "name"=@' +
|
|
1281
1213
|
name +
|
|
@@ -1327,7 +1259,7 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
1327
1259
|
ieTable +
|
|
1328
1260
|
'."guid" IN (SELECT "guid" FROM ' +
|
|
1329
1261
|
PostgreSQLDriver.escape(
|
|
1330
|
-
this.prefix + 'comparisons_' + etype
|
|
1262
|
+
this.prefix + 'comparisons_' + etype,
|
|
1331
1263
|
) +
|
|
1332
1264
|
' WHERE "name"=@' +
|
|
1333
1265
|
name +
|
|
@@ -1379,7 +1311,7 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
1379
1311
|
ieTable +
|
|
1380
1312
|
'."guid" IN (SELECT "guid" FROM ' +
|
|
1381
1313
|
PostgreSQLDriver.escape(
|
|
1382
|
-
this.prefix + 'comparisons_' + etype
|
|
1314
|
+
this.prefix + 'comparisons_' + etype,
|
|
1383
1315
|
) +
|
|
1384
1316
|
' WHERE "name"=@' +
|
|
1385
1317
|
name +
|
|
@@ -1431,7 +1363,7 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
1431
1363
|
ieTable +
|
|
1432
1364
|
'."guid" IN (SELECT "guid" FROM ' +
|
|
1433
1365
|
PostgreSQLDriver.escape(
|
|
1434
|
-
this.prefix + 'comparisons_' + etype
|
|
1366
|
+
this.prefix + 'comparisons_' + etype,
|
|
1435
1367
|
) +
|
|
1436
1368
|
' WHERE "name"=@' +
|
|
1437
1369
|
name +
|
|
@@ -1483,7 +1415,7 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
1483
1415
|
ieTable +
|
|
1484
1416
|
'."guid" IN (SELECT "guid" FROM ' +
|
|
1485
1417
|
PostgreSQLDriver.escape(
|
|
1486
|
-
this.prefix + 'comparisons_' + etype
|
|
1418
|
+
this.prefix + 'comparisons_' + etype,
|
|
1487
1419
|
) +
|
|
1488
1420
|
' WHERE "name"=@' +
|
|
1489
1421
|
name +
|
|
@@ -1537,7 +1469,7 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
1537
1469
|
ieTable +
|
|
1538
1470
|
'."guid" IN (SELECT "guid" FROM ' +
|
|
1539
1471
|
PostgreSQLDriver.escape(
|
|
1540
|
-
this.prefix + 'comparisons_' + etype
|
|
1472
|
+
this.prefix + 'comparisons_' + etype,
|
|
1541
1473
|
) +
|
|
1542
1474
|
' WHERE "name"=@' +
|
|
1543
1475
|
name +
|
|
@@ -1591,7 +1523,7 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
1591
1523
|
ieTable +
|
|
1592
1524
|
'."guid" IN (SELECT "guid" FROM ' +
|
|
1593
1525
|
PostgreSQLDriver.escape(
|
|
1594
|
-
this.prefix + 'comparisons_' + etype
|
|
1526
|
+
this.prefix + 'comparisons_' + etype,
|
|
1595
1527
|
) +
|
|
1596
1528
|
' WHERE "name"=@' +
|
|
1597
1529
|
name +
|
|
@@ -1645,7 +1577,7 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
1645
1577
|
ieTable +
|
|
1646
1578
|
'."guid" IN (SELECT "guid" FROM ' +
|
|
1647
1579
|
PostgreSQLDriver.escape(
|
|
1648
|
-
this.prefix + 'comparisons_' + etype
|
|
1580
|
+
this.prefix + 'comparisons_' + etype,
|
|
1649
1581
|
) +
|
|
1650
1582
|
' WHERE "name"=@' +
|
|
1651
1583
|
name +
|
|
@@ -1696,7 +1628,7 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
1696
1628
|
params,
|
|
1697
1629
|
true,
|
|
1698
1630
|
tableSuffix,
|
|
1699
|
-
etypes
|
|
1631
|
+
etypes,
|
|
1700
1632
|
);
|
|
1701
1633
|
if (curQuery) {
|
|
1702
1634
|
curQuery += typeIsOr ? ' OR ' : ' AND ';
|
|
@@ -1711,7 +1643,7 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
1711
1643
|
case '!qref':
|
|
1712
1644
|
const [qrefOptions, ...qrefSelectors] = curValue[1] as [
|
|
1713
1645
|
Options,
|
|
1714
|
-
...FormattedSelector[]
|
|
1646
|
+
...FormattedSelector[],
|
|
1715
1647
|
];
|
|
1716
1648
|
const QrefEntityClass = qrefOptions.class as EntityConstructor;
|
|
1717
1649
|
etypes.push(QrefEntityClass.ETYPE);
|
|
@@ -1723,7 +1655,7 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
1723
1655
|
params,
|
|
1724
1656
|
false,
|
|
1725
1657
|
makeTableSuffix(),
|
|
1726
|
-
etypes
|
|
1658
|
+
etypes,
|
|
1727
1659
|
);
|
|
1728
1660
|
if (curQuery) {
|
|
1729
1661
|
curQuery += typeIsOr ? ' OR ' : ' AND ';
|
|
@@ -1744,22 +1676,46 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
1744
1676
|
}
|
|
1745
1677
|
}
|
|
1746
1678
|
return curQuery;
|
|
1747
|
-
}
|
|
1679
|
+
},
|
|
1748
1680
|
);
|
|
1749
1681
|
|
|
1750
1682
|
let sortBy: string;
|
|
1683
|
+
let sortByInner: string;
|
|
1684
|
+
let sortJoin = '';
|
|
1685
|
+
let sortJoinInner = '';
|
|
1686
|
+
const order = options.reverse ? ' DESC' : '';
|
|
1751
1687
|
switch (sort) {
|
|
1752
1688
|
case 'mdate':
|
|
1753
|
-
sortBy =
|
|
1689
|
+
sortBy = `${eTable}."mdate"${order}`;
|
|
1690
|
+
sortByInner = `${ieTable}."mdate"${order}`;
|
|
1754
1691
|
break;
|
|
1755
1692
|
case 'cdate':
|
|
1693
|
+
sortBy = `${eTable}."cdate"${order}`;
|
|
1694
|
+
sortByInner = `${ieTable}."cdate"${order}`;
|
|
1695
|
+
break;
|
|
1756
1696
|
default:
|
|
1757
|
-
|
|
1697
|
+
const name = `param${++count.i}`;
|
|
1698
|
+
sortJoin = `LEFT JOIN (
|
|
1699
|
+
SELECT "guid", "string", "number"
|
|
1700
|
+
FROM ${PostgreSQLDriver.escape(
|
|
1701
|
+
this.prefix + 'comparisons_' + etype,
|
|
1702
|
+
)}
|
|
1703
|
+
WHERE "name"=@${name}
|
|
1704
|
+
ORDER BY "number"${order}, "string"${order}
|
|
1705
|
+
) ${sTable} ON ${eTable}."guid"=${sTable}."guid"`;
|
|
1706
|
+
sortJoinInner = `LEFT JOIN (
|
|
1707
|
+
SELECT "guid", "string", "number"
|
|
1708
|
+
FROM ${PostgreSQLDriver.escape(
|
|
1709
|
+
this.prefix + 'comparisons_' + etype,
|
|
1710
|
+
)}
|
|
1711
|
+
WHERE "name"=@${name}
|
|
1712
|
+
ORDER BY "number"${order}, "string"${order}
|
|
1713
|
+
) ${sTable} ON ${ieTable}."guid"=${sTable}."guid"`;
|
|
1714
|
+
sortBy = `${sTable}."number"${order}, ${sTable}."string"${order}`;
|
|
1715
|
+
sortByInner = sortBy;
|
|
1716
|
+
params[name] = sort;
|
|
1758
1717
|
break;
|
|
1759
1718
|
}
|
|
1760
|
-
if (options.reverse) {
|
|
1761
|
-
sortBy += ' DESC';
|
|
1762
|
-
}
|
|
1763
1719
|
|
|
1764
1720
|
let query: string;
|
|
1765
1721
|
if (queryParts.length) {
|
|
@@ -1769,13 +1725,13 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
1769
1725
|
let limit = '';
|
|
1770
1726
|
if ('limit' in options) {
|
|
1771
1727
|
limit = ` LIMIT ${Math.floor(
|
|
1772
|
-
isNaN(Number(options.limit)) ? 0 : Number(options.limit)
|
|
1728
|
+
isNaN(Number(options.limit)) ? 0 : Number(options.limit),
|
|
1773
1729
|
)}`;
|
|
1774
1730
|
}
|
|
1775
1731
|
let offset = '';
|
|
1776
1732
|
if ('offset' in options) {
|
|
1777
1733
|
offset = ` OFFSET ${Math.floor(
|
|
1778
|
-
isNaN(Number(options.offset)) ? 0 : Number(options.offset)
|
|
1734
|
+
isNaN(Number(options.offset)) ? 0 : Number(options.offset),
|
|
1779
1735
|
)}`;
|
|
1780
1736
|
}
|
|
1781
1737
|
const whereClause = queryParts.join(') AND (');
|
|
@@ -1784,14 +1740,14 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
1784
1740
|
query = `SELECT COUNT(${countTable}."guid") AS "count" FROM (
|
|
1785
1741
|
SELECT COUNT(${ieTable}."guid") AS "guid"
|
|
1786
1742
|
FROM ${PostgreSQLDriver.escape(
|
|
1787
|
-
`${this.prefix}entities_${etype}
|
|
1743
|
+
`${this.prefix}entities_${etype}`,
|
|
1788
1744
|
)} ${ieTable}
|
|
1789
1745
|
WHERE (${whereClause})${limit}${offset}
|
|
1790
1746
|
) ${countTable}`;
|
|
1791
1747
|
} else {
|
|
1792
1748
|
query = `SELECT COUNT(${ieTable}."guid") AS "count"
|
|
1793
1749
|
FROM ${PostgreSQLDriver.escape(
|
|
1794
|
-
`${this.prefix}entities_${etype}
|
|
1750
|
+
`${this.prefix}entities_${etype}`,
|
|
1795
1751
|
)} ${ieTable}
|
|
1796
1752
|
WHERE (${whereClause})`;
|
|
1797
1753
|
}
|
|
@@ -1802,10 +1758,11 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
1802
1758
|
: `${ieTable}."guid"`;
|
|
1803
1759
|
query = `SELECT ${guidColumn} AS "guid"
|
|
1804
1760
|
FROM ${PostgreSQLDriver.escape(
|
|
1805
|
-
`${this.prefix}entities_${etype}
|
|
1761
|
+
`${this.prefix}entities_${etype}`,
|
|
1806
1762
|
)} ${ieTable}
|
|
1763
|
+
${sortJoinInner}
|
|
1807
1764
|
WHERE (${whereClause})
|
|
1808
|
-
ORDER BY ${
|
|
1765
|
+
ORDER BY ${sortByInner}, ${ieTable}."guid"${limit}${offset}`;
|
|
1809
1766
|
} else {
|
|
1810
1767
|
query = `SELECT
|
|
1811
1768
|
encode(${eTable}."guid", 'hex') AS "guid",
|
|
@@ -1817,23 +1774,25 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
1817
1774
|
${cTable}."string",
|
|
1818
1775
|
${cTable}."number"
|
|
1819
1776
|
FROM ${PostgreSQLDriver.escape(
|
|
1820
|
-
`${this.prefix}entities_${etype}
|
|
1777
|
+
`${this.prefix}entities_${etype}`,
|
|
1821
1778
|
)} ${eTable}
|
|
1822
1779
|
LEFT JOIN ${PostgreSQLDriver.escape(
|
|
1823
|
-
`${this.prefix}data_${etype}
|
|
1780
|
+
`${this.prefix}data_${etype}`,
|
|
1824
1781
|
)} ${dTable} ON ${eTable}."guid"=${dTable}."guid"
|
|
1825
1782
|
INNER JOIN ${PostgreSQLDriver.escape(
|
|
1826
|
-
`${this.prefix}comparisons_${etype}
|
|
1783
|
+
`${this.prefix}comparisons_${etype}`,
|
|
1827
1784
|
)} ${cTable} ON ${dTable}."guid"=${cTable}."guid" AND ${dTable}."name"=${cTable}."name"
|
|
1785
|
+
${sortJoin}
|
|
1828
1786
|
INNER JOIN (
|
|
1829
1787
|
SELECT ${ieTable}."guid"
|
|
1830
1788
|
FROM ${PostgreSQLDriver.escape(
|
|
1831
|
-
`${this.prefix}entities_${etype}
|
|
1789
|
+
`${this.prefix}entities_${etype}`,
|
|
1832
1790
|
)} ${ieTable}
|
|
1791
|
+
${sortJoinInner}
|
|
1833
1792
|
WHERE (${whereClause})
|
|
1834
|
-
ORDER BY ${
|
|
1793
|
+
ORDER BY ${sortByInner}${limit}${offset}
|
|
1835
1794
|
) ${fTable} ON ${eTable}."guid"=${fTable}."guid"
|
|
1836
|
-
ORDER BY ${
|
|
1795
|
+
ORDER BY ${sortBy}, ${eTable}."guid"`;
|
|
1837
1796
|
}
|
|
1838
1797
|
}
|
|
1839
1798
|
} else {
|
|
@@ -1843,13 +1802,13 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
1843
1802
|
let limit = '';
|
|
1844
1803
|
if ('limit' in options) {
|
|
1845
1804
|
limit = ` LIMIT ${Math.floor(
|
|
1846
|
-
isNaN(Number(options.limit)) ? 0 : Number(options.limit)
|
|
1805
|
+
isNaN(Number(options.limit)) ? 0 : Number(options.limit),
|
|
1847
1806
|
)}`;
|
|
1848
1807
|
}
|
|
1849
1808
|
let offset = '';
|
|
1850
1809
|
if ('offset' in options) {
|
|
1851
1810
|
offset = ` OFFSET ${Math.floor(
|
|
1852
|
-
isNaN(Number(options.offset)) ? 0 : Number(options.offset)
|
|
1811
|
+
isNaN(Number(options.offset)) ? 0 : Number(options.offset),
|
|
1853
1812
|
)}`;
|
|
1854
1813
|
}
|
|
1855
1814
|
if (options.return === 'count') {
|
|
@@ -1857,13 +1816,13 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
1857
1816
|
query = `SELECT COUNT(${countTable}."guid") AS "count" FROM (
|
|
1858
1817
|
SELECT COUNT(${ieTable}."guid") AS "guid"
|
|
1859
1818
|
FROM ${PostgreSQLDriver.escape(
|
|
1860
|
-
`${this.prefix}entities_${etype}
|
|
1819
|
+
`${this.prefix}entities_${etype}`,
|
|
1861
1820
|
)} ${ieTable}${limit}${offset}
|
|
1862
1821
|
) ${countTable}`;
|
|
1863
1822
|
} else {
|
|
1864
1823
|
query = `SELECT COUNT(${ieTable}."guid") AS "count"
|
|
1865
1824
|
FROM ${PostgreSQLDriver.escape(
|
|
1866
|
-
`${this.prefix}entities_${etype}
|
|
1825
|
+
`${this.prefix}entities_${etype}`,
|
|
1867
1826
|
)} ${ieTable}`;
|
|
1868
1827
|
}
|
|
1869
1828
|
} else if (options.return === 'guid') {
|
|
@@ -1873,9 +1832,10 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
1873
1832
|
: `${ieTable}."guid"`;
|
|
1874
1833
|
query = `SELECT ${guidColumn} AS "guid"
|
|
1875
1834
|
FROM ${PostgreSQLDriver.escape(
|
|
1876
|
-
`${this.prefix}entities_${etype}
|
|
1835
|
+
`${this.prefix}entities_${etype}`,
|
|
1877
1836
|
)} ${ieTable}
|
|
1878
|
-
|
|
1837
|
+
${sortJoinInner}
|
|
1838
|
+
ORDER BY ${sortByInner}, ${ieTable}."guid"${limit}${offset}`;
|
|
1879
1839
|
} else {
|
|
1880
1840
|
if (limit || offset) {
|
|
1881
1841
|
query = `SELECT
|
|
@@ -1888,22 +1848,24 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
1888
1848
|
${cTable}."string",
|
|
1889
1849
|
${cTable}."number"
|
|
1890
1850
|
FROM ${PostgreSQLDriver.escape(
|
|
1891
|
-
`${this.prefix}entities_${etype}
|
|
1851
|
+
`${this.prefix}entities_${etype}`,
|
|
1892
1852
|
)} ${eTable}
|
|
1893
1853
|
LEFT JOIN ${PostgreSQLDriver.escape(
|
|
1894
|
-
`${this.prefix}data_${etype}
|
|
1854
|
+
`${this.prefix}data_${etype}`,
|
|
1895
1855
|
)} ${dTable} ON ${eTable}."guid"=${dTable}."guid"
|
|
1896
1856
|
INNER JOIN ${PostgreSQLDriver.escape(
|
|
1897
|
-
`${this.prefix}comparisons_${etype}
|
|
1857
|
+
`${this.prefix}comparisons_${etype}`,
|
|
1898
1858
|
)} ${cTable} ON ${dTable}."guid"=${cTable}."guid" AND ${dTable}."name"=${cTable}."name"
|
|
1859
|
+
${sortJoin}
|
|
1899
1860
|
INNER JOIN (
|
|
1900
1861
|
SELECT ${ieTable}."guid"
|
|
1901
1862
|
FROM ${PostgreSQLDriver.escape(
|
|
1902
|
-
`${this.prefix}entities_${etype}
|
|
1863
|
+
`${this.prefix}entities_${etype}`,
|
|
1903
1864
|
)} ${ieTable}
|
|
1904
|
-
|
|
1865
|
+
${sortJoinInner}
|
|
1866
|
+
ORDER BY ${sortByInner}${limit}${offset}
|
|
1905
1867
|
) ${fTable} ON ${eTable}."guid"=${fTable}."guid"
|
|
1906
|
-
ORDER BY ${
|
|
1868
|
+
ORDER BY ${sortBy}, ${eTable}."guid"`;
|
|
1907
1869
|
} else {
|
|
1908
1870
|
query = `SELECT
|
|
1909
1871
|
encode(${eTable}."guid", 'hex') AS "guid",
|
|
@@ -1915,15 +1877,16 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
1915
1877
|
${cTable}."string",
|
|
1916
1878
|
${cTable}."number"
|
|
1917
1879
|
FROM ${PostgreSQLDriver.escape(
|
|
1918
|
-
`${this.prefix}entities_${etype}
|
|
1880
|
+
`${this.prefix}entities_${etype}`,
|
|
1919
1881
|
)} ${eTable}
|
|
1920
1882
|
LEFT JOIN ${PostgreSQLDriver.escape(
|
|
1921
|
-
`${this.prefix}data_${etype}
|
|
1883
|
+
`${this.prefix}data_${etype}`,
|
|
1922
1884
|
)} ${dTable} ON ${eTable}."guid"=${dTable}."guid"
|
|
1923
1885
|
INNER JOIN ${PostgreSQLDriver.escape(
|
|
1924
|
-
`${this.prefix}comparisons_${etype}
|
|
1886
|
+
`${this.prefix}comparisons_${etype}`,
|
|
1925
1887
|
)} ${cTable} ON ${dTable}."guid"=${cTable}."guid" AND ${dTable}."name"=${cTable}."name"
|
|
1926
|
-
|
|
1888
|
+
${sortJoin}
|
|
1889
|
+
ORDER BY ${sortBy}, ${eTable}."guid"`;
|
|
1927
1890
|
}
|
|
1928
1891
|
}
|
|
1929
1892
|
}
|
|
@@ -1943,38 +1906,18 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
1943
1906
|
protected performQuery(
|
|
1944
1907
|
options: Options,
|
|
1945
1908
|
formattedSelectors: FormattedSelector[],
|
|
1946
|
-
etype: string
|
|
1909
|
+
etype: string,
|
|
1947
1910
|
): {
|
|
1948
1911
|
result: any;
|
|
1949
1912
|
} {
|
|
1950
1913
|
const { query, params, etypes } = this.makeEntityQuery(
|
|
1951
1914
|
options,
|
|
1952
1915
|
formattedSelectors,
|
|
1953
|
-
etype
|
|
1916
|
+
etype,
|
|
1954
1917
|
);
|
|
1955
1918
|
const result = this.queryIter(query, { etypes, params }).then((val) =>
|
|
1956
|
-
val[Symbol.iterator]()
|
|
1957
|
-
);
|
|
1958
|
-
return {
|
|
1959
|
-
result,
|
|
1960
|
-
};
|
|
1961
|
-
}
|
|
1962
|
-
|
|
1963
|
-
protected performQuerySync(
|
|
1964
|
-
options: Options,
|
|
1965
|
-
formattedSelectors: FormattedSelector[],
|
|
1966
|
-
etype: string
|
|
1967
|
-
): {
|
|
1968
|
-
result: any;
|
|
1969
|
-
} {
|
|
1970
|
-
const { query, params, etypes } = this.makeEntityQuery(
|
|
1971
|
-
options,
|
|
1972
|
-
formattedSelectors,
|
|
1973
|
-
etype
|
|
1919
|
+
val[Symbol.iterator](),
|
|
1974
1920
|
);
|
|
1975
|
-
const result = (this.queryIterSync(query, { etypes, params }) || [])[
|
|
1976
|
-
Symbol.iterator
|
|
1977
|
-
]();
|
|
1978
1921
|
return {
|
|
1979
1922
|
result,
|
|
1980
1923
|
};
|
|
@@ -1991,17 +1934,17 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
1991
1934
|
public async getEntities<T extends EntityConstructor = EntityConstructor>(
|
|
1992
1935
|
options?: Options<T>,
|
|
1993
1936
|
...selectors: Selector[]
|
|
1994
|
-
): Promise<
|
|
1937
|
+
): Promise<EntityInstanceType<T>[]>;
|
|
1995
1938
|
public async getEntities<T extends EntityConstructor = EntityConstructor>(
|
|
1996
1939
|
options: Options<T> = {},
|
|
1997
1940
|
...selectors: Selector[]
|
|
1998
|
-
): Promise<
|
|
1999
|
-
const { result: resultPromise, process } = this.
|
|
1941
|
+
): Promise<EntityInstanceType<T>[] | string[] | number> {
|
|
1942
|
+
const { result: resultPromise, process } = this.getEntitiesRowLike<T>(
|
|
2000
1943
|
// @ts-ignore: options is correct here.
|
|
2001
1944
|
options,
|
|
2002
1945
|
selectors,
|
|
2003
|
-
(options,
|
|
2004
|
-
this.performQuery(options,
|
|
1946
|
+
({ options, selectors, etype }) =>
|
|
1947
|
+
this.performQuery(options, selectors, etype),
|
|
2005
1948
|
() => {
|
|
2006
1949
|
const next: any = result.next();
|
|
2007
1950
|
return next.done ? null : next.value;
|
|
@@ -2022,7 +1965,7 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
2022
1965
|
: row.value === 'S'
|
|
2023
1966
|
? JSON.stringify(row.string)
|
|
2024
1967
|
: row.value,
|
|
2025
|
-
})
|
|
1968
|
+
}),
|
|
2026
1969
|
);
|
|
2027
1970
|
|
|
2028
1971
|
const result = await resultPromise;
|
|
@@ -2033,251 +1976,269 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
2033
1976
|
return value;
|
|
2034
1977
|
}
|
|
2035
1978
|
|
|
2036
|
-
protected getEntitiesSync<T extends EntityConstructor = EntityConstructor>(
|
|
2037
|
-
options: Options<T> & { return: 'count' },
|
|
2038
|
-
...selectors: Selector[]
|
|
2039
|
-
): number;
|
|
2040
|
-
protected getEntitiesSync<T extends EntityConstructor = EntityConstructor>(
|
|
2041
|
-
options: Options<T> & { return: 'guid' },
|
|
2042
|
-
...selectors: Selector[]
|
|
2043
|
-
): string[];
|
|
2044
|
-
protected getEntitiesSync<T extends EntityConstructor = EntityConstructor>(
|
|
2045
|
-
options?: Options<T>,
|
|
2046
|
-
...selectors: Selector[]
|
|
2047
|
-
): ReturnType<T['factorySync']>[];
|
|
2048
|
-
protected getEntitiesSync<T extends EntityConstructor = EntityConstructor>(
|
|
2049
|
-
options: Options<T> = {},
|
|
2050
|
-
...selectors: Selector[]
|
|
2051
|
-
): ReturnType<T['factorySync']>[] | string[] | number {
|
|
2052
|
-
const { result, process } = this.getEntitesRowLike<T>(
|
|
2053
|
-
// @ts-ignore: options is correct here.
|
|
2054
|
-
options,
|
|
2055
|
-
selectors,
|
|
2056
|
-
(options, formattedSelectors, etype) =>
|
|
2057
|
-
this.performQuerySync(options, formattedSelectors, etype),
|
|
2058
|
-
() => {
|
|
2059
|
-
const next: any = result.next();
|
|
2060
|
-
return next.done ? null : next.value;
|
|
2061
|
-
},
|
|
2062
|
-
() => undefined,
|
|
2063
|
-
(row) => Number(row.count),
|
|
2064
|
-
(row) => row.guid,
|
|
2065
|
-
(row) => ({
|
|
2066
|
-
tags: row.tags,
|
|
2067
|
-
cdate: isNaN(Number(row.cdate)) ? null : Number(row.cdate),
|
|
2068
|
-
mdate: isNaN(Number(row.mdate)) ? null : Number(row.mdate),
|
|
2069
|
-
}),
|
|
2070
|
-
(row) => ({
|
|
2071
|
-
name: row.name,
|
|
2072
|
-
svalue:
|
|
2073
|
-
row.value === 'N'
|
|
2074
|
-
? JSON.stringify(Number(row.number))
|
|
2075
|
-
: row.value === 'S'
|
|
2076
|
-
? JSON.stringify(row.string)
|
|
2077
|
-
: row.value,
|
|
2078
|
-
})
|
|
2079
|
-
);
|
|
2080
|
-
const value = process();
|
|
2081
|
-
if (value instanceof Error) {
|
|
2082
|
-
throw value;
|
|
2083
|
-
}
|
|
2084
|
-
return value;
|
|
2085
|
-
}
|
|
2086
|
-
|
|
2087
1979
|
public async getUID(name: string) {
|
|
2088
1980
|
if (name == null) {
|
|
2089
1981
|
throw new InvalidParametersError('Name not given for UID.');
|
|
2090
1982
|
}
|
|
2091
1983
|
const result = await this.queryGet(
|
|
2092
1984
|
`SELECT "cur_uid" FROM ${PostgreSQLDriver.escape(
|
|
2093
|
-
`${this.prefix}uids
|
|
1985
|
+
`${this.prefix}uids`,
|
|
2094
1986
|
)} WHERE "name"=@name;`,
|
|
2095
1987
|
{
|
|
2096
1988
|
params: {
|
|
2097
1989
|
name: name,
|
|
2098
1990
|
},
|
|
2099
|
-
}
|
|
1991
|
+
},
|
|
2100
1992
|
);
|
|
2101
1993
|
return result?.cur_uid == null ? null : Number(result.cur_uid);
|
|
2102
1994
|
}
|
|
2103
1995
|
|
|
2104
|
-
public async import(filename: string) {
|
|
1996
|
+
public async import(filename: string, transaction?: boolean) {
|
|
2105
1997
|
try {
|
|
2106
1998
|
const result = await this.importFromFile(
|
|
2107
1999
|
filename,
|
|
2108
2000
|
async (guid, tags, sdata, etype) => {
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
}
|
|
2119
|
-
);
|
|
2120
|
-
await this.queryRun(
|
|
2121
|
-
`INSERT INTO ${PostgreSQLDriver.escape(
|
|
2122
|
-
`${this.prefix}entities_${etype}`
|
|
2123
|
-
)} ("guid", "tags", "cdate", "mdate") VALUES (decode(@guid, 'hex'), @tags, @cdate, @mdate);`,
|
|
2124
|
-
{
|
|
2125
|
-
etypes: [etype],
|
|
2126
|
-
params: {
|
|
2127
|
-
guid,
|
|
2128
|
-
tags,
|
|
2129
|
-
cdate: isNaN(Number(JSON.parse(sdata.cdate)))
|
|
2130
|
-
? null
|
|
2131
|
-
: Number(JSON.parse(sdata.cdate)),
|
|
2132
|
-
mdate: isNaN(Number(JSON.parse(sdata.mdate)))
|
|
2133
|
-
? null
|
|
2134
|
-
: Number(JSON.parse(sdata.mdate)),
|
|
2135
|
-
},
|
|
2136
|
-
}
|
|
2137
|
-
);
|
|
2138
|
-
const promises = [];
|
|
2139
|
-
promises.push(
|
|
2140
|
-
this.queryRun(
|
|
2141
|
-
`DELETE FROM ${PostgreSQLDriver.escape(
|
|
2142
|
-
`${this.prefix}data_${etype}`
|
|
2143
|
-
)} WHERE "guid"=decode(@guid, 'hex');`,
|
|
2144
|
-
{
|
|
2145
|
-
etypes: [etype],
|
|
2146
|
-
params: {
|
|
2147
|
-
guid,
|
|
2148
|
-
},
|
|
2149
|
-
}
|
|
2150
|
-
)
|
|
2151
|
-
);
|
|
2152
|
-
promises.push(
|
|
2153
|
-
this.queryRun(
|
|
2001
|
+
try {
|
|
2002
|
+
await this.internalTransaction(`nymph-import-entity-${guid}`);
|
|
2003
|
+
|
|
2004
|
+
const cdate = Number(JSON.parse(sdata.cdate));
|
|
2005
|
+
delete sdata.cdate;
|
|
2006
|
+
const mdate = Number(JSON.parse(sdata.mdate));
|
|
2007
|
+
delete sdata.mdate;
|
|
2008
|
+
|
|
2009
|
+
await this.queryRun(
|
|
2154
2010
|
`DELETE FROM ${PostgreSQLDriver.escape(
|
|
2155
|
-
`${this.prefix}
|
|
2011
|
+
`${this.prefix}entities_${etype}`,
|
|
2156
2012
|
)} WHERE "guid"=decode(@guid, 'hex');`,
|
|
2157
2013
|
{
|
|
2158
2014
|
etypes: [etype],
|
|
2159
2015
|
params: {
|
|
2160
2016
|
guid,
|
|
2161
2017
|
},
|
|
2162
|
-
}
|
|
2163
|
-
)
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
`${this.prefix}references_${etype}`
|
|
2169
|
-
)} WHERE "guid"=decode(@guid, 'hex');`,
|
|
2018
|
+
},
|
|
2019
|
+
);
|
|
2020
|
+
await this.queryRun(
|
|
2021
|
+
`INSERT INTO ${PostgreSQLDriver.escape(
|
|
2022
|
+
`${this.prefix}entities_${etype}`,
|
|
2023
|
+
)} ("guid", "tags", "cdate", "mdate") VALUES (decode(@guid, 'hex'), @tags, @cdate, @mdate);`,
|
|
2170
2024
|
{
|
|
2171
2025
|
etypes: [etype],
|
|
2172
2026
|
params: {
|
|
2173
2027
|
guid,
|
|
2028
|
+
tags,
|
|
2029
|
+
cdate: isNaN(cdate) ? null : cdate,
|
|
2030
|
+
mdate: isNaN(mdate) ? null : mdate,
|
|
2174
2031
|
},
|
|
2175
|
-
}
|
|
2176
|
-
)
|
|
2177
|
-
);
|
|
2178
|
-
await Promise.all(promises);
|
|
2179
|
-
delete sdata.cdate;
|
|
2180
|
-
delete sdata.mdate;
|
|
2181
|
-
for (const name in sdata) {
|
|
2182
|
-
const value = sdata[name];
|
|
2183
|
-
const uvalue = JSON.parse(value);
|
|
2184
|
-
if (value === undefined) {
|
|
2185
|
-
continue;
|
|
2186
|
-
}
|
|
2187
|
-
const storageValue =
|
|
2188
|
-
typeof uvalue === 'number'
|
|
2189
|
-
? 'N'
|
|
2190
|
-
: typeof uvalue === 'string'
|
|
2191
|
-
? 'S'
|
|
2192
|
-
: value;
|
|
2032
|
+
},
|
|
2033
|
+
);
|
|
2193
2034
|
const promises = [];
|
|
2194
2035
|
promises.push(
|
|
2195
2036
|
this.queryRun(
|
|
2196
|
-
`
|
|
2197
|
-
`${this.prefix}data_${etype}
|
|
2198
|
-
)}
|
|
2037
|
+
`DELETE FROM ${PostgreSQLDriver.escape(
|
|
2038
|
+
`${this.prefix}data_${etype}`,
|
|
2039
|
+
)} WHERE "guid"=decode(@guid, 'hex');`,
|
|
2199
2040
|
{
|
|
2200
2041
|
etypes: [etype],
|
|
2201
2042
|
params: {
|
|
2202
2043
|
guid,
|
|
2203
|
-
name,
|
|
2204
|
-
storageValue,
|
|
2205
2044
|
},
|
|
2206
|
-
}
|
|
2207
|
-
)
|
|
2045
|
+
},
|
|
2046
|
+
),
|
|
2208
2047
|
);
|
|
2209
2048
|
promises.push(
|
|
2210
2049
|
this.queryRun(
|
|
2211
|
-
`
|
|
2212
|
-
`${this.prefix}comparisons_${etype}
|
|
2213
|
-
)}
|
|
2050
|
+
`DELETE FROM ${PostgreSQLDriver.escape(
|
|
2051
|
+
`${this.prefix}comparisons_${etype}`,
|
|
2052
|
+
)} WHERE "guid"=decode(@guid, 'hex');`,
|
|
2214
2053
|
{
|
|
2215
2054
|
etypes: [etype],
|
|
2216
2055
|
params: {
|
|
2217
2056
|
guid,
|
|
2218
|
-
name,
|
|
2219
|
-
truthy: !!uvalue,
|
|
2220
|
-
string: `${uvalue}`,
|
|
2221
|
-
number: isNaN(Number(uvalue)) ? null : Number(uvalue),
|
|
2222
2057
|
},
|
|
2223
|
-
}
|
|
2224
|
-
)
|
|
2058
|
+
},
|
|
2059
|
+
),
|
|
2225
2060
|
);
|
|
2226
|
-
|
|
2227
|
-
|
|
2061
|
+
promises.push(
|
|
2062
|
+
this.queryRun(
|
|
2063
|
+
`DELETE FROM ${PostgreSQLDriver.escape(
|
|
2064
|
+
`${this.prefix}references_${etype}`,
|
|
2065
|
+
)} WHERE "guid"=decode(@guid, 'hex');`,
|
|
2066
|
+
{
|
|
2067
|
+
etypes: [etype],
|
|
2068
|
+
params: {
|
|
2069
|
+
guid,
|
|
2070
|
+
},
|
|
2071
|
+
},
|
|
2072
|
+
),
|
|
2073
|
+
);
|
|
2074
|
+
promises.push(
|
|
2075
|
+
this.queryRun(
|
|
2076
|
+
`DELETE FROM ${PostgreSQLDriver.escape(
|
|
2077
|
+
`${this.prefix}uniques_${etype}`,
|
|
2078
|
+
)} WHERE "guid"=decode(@guid, 'hex');`,
|
|
2079
|
+
{
|
|
2080
|
+
etypes: [etype],
|
|
2081
|
+
params: {
|
|
2082
|
+
guid,
|
|
2083
|
+
},
|
|
2084
|
+
},
|
|
2085
|
+
),
|
|
2086
|
+
);
|
|
2087
|
+
await Promise.all(promises);
|
|
2088
|
+
for (const name in sdata) {
|
|
2089
|
+
const value = sdata[name];
|
|
2090
|
+
const uvalue = JSON.parse(value);
|
|
2091
|
+
if (value === undefined) {
|
|
2092
|
+
continue;
|
|
2093
|
+
}
|
|
2094
|
+
const storageValue =
|
|
2095
|
+
typeof uvalue === 'number'
|
|
2096
|
+
? 'N'
|
|
2097
|
+
: typeof uvalue === 'string'
|
|
2098
|
+
? 'S'
|
|
2099
|
+
: value;
|
|
2100
|
+
const promises = [];
|
|
2228
2101
|
promises.push(
|
|
2229
2102
|
this.queryRun(
|
|
2230
2103
|
`INSERT INTO ${PostgreSQLDriver.escape(
|
|
2231
|
-
`${this.prefix}
|
|
2232
|
-
)} ("guid", "name", "
|
|
2104
|
+
`${this.prefix}data_${etype}`,
|
|
2105
|
+
)} ("guid", "name", "value") VALUES (decode(@guid, 'hex'), @name, @storageValue);`,
|
|
2233
2106
|
{
|
|
2234
2107
|
etypes: [etype],
|
|
2235
2108
|
params: {
|
|
2236
2109
|
guid,
|
|
2237
2110
|
name,
|
|
2238
|
-
|
|
2111
|
+
storageValue,
|
|
2239
2112
|
},
|
|
2113
|
+
},
|
|
2114
|
+
),
|
|
2115
|
+
);
|
|
2116
|
+
promises.push(
|
|
2117
|
+
this.queryRun(
|
|
2118
|
+
`INSERT INTO ${PostgreSQLDriver.escape(
|
|
2119
|
+
`${this.prefix}comparisons_${etype}`,
|
|
2120
|
+
)} ("guid", "name", "truthy", "string", "number") VALUES (decode(@guid, 'hex'), @name, @truthy, @string, @number);`,
|
|
2121
|
+
{
|
|
2122
|
+
etypes: [etype],
|
|
2123
|
+
params: {
|
|
2124
|
+
guid,
|
|
2125
|
+
name,
|
|
2126
|
+
truthy: !!uvalue,
|
|
2127
|
+
string: `${uvalue}`,
|
|
2128
|
+
number: isNaN(Number(uvalue)) ? null : Number(uvalue),
|
|
2129
|
+
},
|
|
2130
|
+
},
|
|
2131
|
+
),
|
|
2132
|
+
);
|
|
2133
|
+
const references = this.findReferences(value);
|
|
2134
|
+
for (const reference of references) {
|
|
2135
|
+
promises.push(
|
|
2136
|
+
this.queryRun(
|
|
2137
|
+
`INSERT INTO ${PostgreSQLDriver.escape(
|
|
2138
|
+
`${this.prefix}references_${etype}`,
|
|
2139
|
+
)} ("guid", "name", "reference") VALUES (decode(@guid, 'hex'), @name, decode(@reference, 'hex'));`,
|
|
2140
|
+
{
|
|
2141
|
+
etypes: [etype],
|
|
2142
|
+
params: {
|
|
2143
|
+
guid,
|
|
2144
|
+
name,
|
|
2145
|
+
reference,
|
|
2146
|
+
},
|
|
2147
|
+
},
|
|
2148
|
+
),
|
|
2149
|
+
);
|
|
2150
|
+
}
|
|
2151
|
+
}
|
|
2152
|
+
const uniques = await this.nymph
|
|
2153
|
+
.getEntityClassByEtype(etype)
|
|
2154
|
+
.getUniques({ guid, cdate, mdate, tags, data: {}, sdata });
|
|
2155
|
+
for (const unique of uniques) {
|
|
2156
|
+
promises.push(
|
|
2157
|
+
this.queryRun(
|
|
2158
|
+
`INSERT INTO ${PostgreSQLDriver.escape(
|
|
2159
|
+
`${this.prefix}uniques_${etype}`,
|
|
2160
|
+
)} ("guid", "unique") VALUES (decode(@guid, 'hex'), @unique);`,
|
|
2161
|
+
{
|
|
2162
|
+
etypes: [etype],
|
|
2163
|
+
params: {
|
|
2164
|
+
guid,
|
|
2165
|
+
unique,
|
|
2166
|
+
},
|
|
2167
|
+
},
|
|
2168
|
+
).catch((e: any) => {
|
|
2169
|
+
if (e instanceof EntityUniqueConstraintError) {
|
|
2170
|
+
this.nymph.config.debugError(
|
|
2171
|
+
'postgresql',
|
|
2172
|
+
`Import entity unique constraint violation for GUID "${guid}" on etype "${etype}": "${unique}"`,
|
|
2173
|
+
);
|
|
2240
2174
|
}
|
|
2241
|
-
|
|
2175
|
+
return e;
|
|
2176
|
+
}),
|
|
2242
2177
|
);
|
|
2243
2178
|
}
|
|
2179
|
+
await Promise.all(promises);
|
|
2180
|
+
await this.commit(`nymph-import-entity-${guid}`);
|
|
2181
|
+
} catch (e: any) {
|
|
2182
|
+
this.nymph.config.debugError(
|
|
2183
|
+
'postgresql',
|
|
2184
|
+
`Import entity error: "${e}"`,
|
|
2185
|
+
);
|
|
2186
|
+
await this.rollback(`nymph-import-entity-${guid}`);
|
|
2187
|
+
throw e;
|
|
2244
2188
|
}
|
|
2245
|
-
await Promise.all(promises);
|
|
2246
2189
|
},
|
|
2247
2190
|
async (name, curUid) => {
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2191
|
+
try {
|
|
2192
|
+
await this.internalTransaction(`nymph-import-uid-${name}`);
|
|
2193
|
+
await this.queryRun(
|
|
2194
|
+
`DELETE FROM ${PostgreSQLDriver.escape(
|
|
2195
|
+
`${this.prefix}uids`,
|
|
2196
|
+
)} WHERE "name"=@name;`,
|
|
2197
|
+
{
|
|
2198
|
+
params: {
|
|
2199
|
+
name,
|
|
2200
|
+
},
|
|
2255
2201
|
},
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2202
|
+
);
|
|
2203
|
+
await this.queryRun(
|
|
2204
|
+
`INSERT INTO ${PostgreSQLDriver.escape(
|
|
2205
|
+
`${this.prefix}uids`,
|
|
2206
|
+
)} ("name", "cur_uid") VALUES (@name, @curUid);`,
|
|
2207
|
+
{
|
|
2208
|
+
params: {
|
|
2209
|
+
name,
|
|
2210
|
+
curUid,
|
|
2211
|
+
},
|
|
2266
2212
|
},
|
|
2267
|
-
|
|
2268
|
-
|
|
2213
|
+
);
|
|
2214
|
+
await this.commit(`nymph-import-uid-${name}`);
|
|
2215
|
+
} catch (e: any) {
|
|
2216
|
+
this.nymph.config.debugError(
|
|
2217
|
+
'postgresql',
|
|
2218
|
+
`Import UID error: "${e}"`,
|
|
2219
|
+
);
|
|
2220
|
+
await this.rollback(`nymph-import-uid-${name}`);
|
|
2221
|
+
throw e;
|
|
2222
|
+
}
|
|
2269
2223
|
},
|
|
2270
2224
|
async () => {
|
|
2271
|
-
|
|
2225
|
+
if (transaction) {
|
|
2226
|
+
await this.internalTransaction('nymph-import');
|
|
2227
|
+
}
|
|
2272
2228
|
},
|
|
2273
2229
|
async () => {
|
|
2274
|
-
|
|
2275
|
-
|
|
2230
|
+
if (transaction) {
|
|
2231
|
+
await this.commit('nymph-import');
|
|
2232
|
+
}
|
|
2233
|
+
},
|
|
2276
2234
|
);
|
|
2277
2235
|
|
|
2278
2236
|
return result;
|
|
2279
2237
|
} catch (e: any) {
|
|
2280
|
-
|
|
2238
|
+
this.nymph.config.debugError('postgresql', `Import error: "${e}"`);
|
|
2239
|
+
if (transaction) {
|
|
2240
|
+
await this.rollback('nymph-import');
|
|
2241
|
+
}
|
|
2281
2242
|
return false;
|
|
2282
2243
|
}
|
|
2283
2244
|
}
|
|
@@ -2287,52 +2248,54 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
2287
2248
|
throw new InvalidParametersError('Name not given for UID.');
|
|
2288
2249
|
}
|
|
2289
2250
|
await this.internalTransaction('nymph-newuid');
|
|
2251
|
+
let curUid: number | undefined = undefined;
|
|
2290
2252
|
try {
|
|
2291
2253
|
const lock = await this.queryGet(
|
|
2292
2254
|
`SELECT "cur_uid" FROM ${PostgreSQLDriver.escape(
|
|
2293
|
-
`${this.prefix}uids
|
|
2255
|
+
`${this.prefix}uids`,
|
|
2294
2256
|
)} WHERE "name"=@name FOR UPDATE;`,
|
|
2295
2257
|
{
|
|
2296
2258
|
params: {
|
|
2297
2259
|
name,
|
|
2298
2260
|
},
|
|
2299
|
-
}
|
|
2261
|
+
},
|
|
2300
2262
|
);
|
|
2301
|
-
|
|
2302
|
-
lock?.cur_uid == null ? undefined : Number(lock.cur_uid);
|
|
2263
|
+
curUid = lock?.cur_uid == null ? undefined : Number(lock.cur_uid);
|
|
2303
2264
|
if (curUid == null) {
|
|
2304
2265
|
curUid = 1;
|
|
2305
2266
|
await this.queryRun(
|
|
2306
2267
|
`INSERT INTO ${PostgreSQLDriver.escape(
|
|
2307
|
-
`${this.prefix}uids
|
|
2268
|
+
`${this.prefix}uids`,
|
|
2308
2269
|
)} ("name", "cur_uid") VALUES (@name, @curUid);`,
|
|
2309
2270
|
{
|
|
2310
2271
|
params: {
|
|
2311
2272
|
name,
|
|
2312
2273
|
curUid,
|
|
2313
2274
|
},
|
|
2314
|
-
}
|
|
2275
|
+
},
|
|
2315
2276
|
);
|
|
2316
2277
|
} else {
|
|
2317
2278
|
curUid++;
|
|
2318
2279
|
await this.queryRun(
|
|
2319
2280
|
`UPDATE ${PostgreSQLDriver.escape(
|
|
2320
|
-
`${this.prefix}uids
|
|
2281
|
+
`${this.prefix}uids`,
|
|
2321
2282
|
)} SET "cur_uid"=@curUid WHERE "name"=@name;`,
|
|
2322
2283
|
{
|
|
2323
2284
|
params: {
|
|
2324
2285
|
name,
|
|
2325
2286
|
curUid,
|
|
2326
2287
|
},
|
|
2327
|
-
}
|
|
2288
|
+
},
|
|
2328
2289
|
);
|
|
2329
2290
|
}
|
|
2330
|
-
await this.commit('nymph-newuid');
|
|
2331
|
-
return curUid;
|
|
2332
2291
|
} catch (e: any) {
|
|
2292
|
+
this.nymph.config.debugError('postgresql', `New UID error: "${e}"`);
|
|
2333
2293
|
await this.rollback('nymph-newuid');
|
|
2334
2294
|
throw e;
|
|
2335
2295
|
}
|
|
2296
|
+
|
|
2297
|
+
await this.commit('nymph-newuid');
|
|
2298
|
+
return curUid;
|
|
2336
2299
|
}
|
|
2337
2300
|
|
|
2338
2301
|
public async renameUID(oldName: string, newName: string) {
|
|
@@ -2341,14 +2304,14 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
2341
2304
|
}
|
|
2342
2305
|
await this.queryRun(
|
|
2343
2306
|
`UPDATE ${PostgreSQLDriver.escape(
|
|
2344
|
-
`${this.prefix}uids
|
|
2307
|
+
`${this.prefix}uids`,
|
|
2345
2308
|
)} SET "name"=@newName WHERE "name"=@oldName;`,
|
|
2346
2309
|
{
|
|
2347
2310
|
params: {
|
|
2348
2311
|
newName,
|
|
2349
2312
|
oldName,
|
|
2350
2313
|
},
|
|
2351
|
-
}
|
|
2314
|
+
},
|
|
2352
2315
|
);
|
|
2353
2316
|
return true;
|
|
2354
2317
|
}
|
|
@@ -2356,7 +2319,7 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
2356
2319
|
public async rollback(name: string) {
|
|
2357
2320
|
if (name == null || typeof name !== 'string' || name.length === 0) {
|
|
2358
2321
|
throw new InvalidParametersError(
|
|
2359
|
-
'Transaction rollback attempted without a name.'
|
|
2322
|
+
'Transaction rollback attempted without a name.',
|
|
2360
2323
|
);
|
|
2361
2324
|
}
|
|
2362
2325
|
if (!this.transaction || this.transaction.count === 0) {
|
|
@@ -2364,7 +2327,7 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
2364
2327
|
return true;
|
|
2365
2328
|
}
|
|
2366
2329
|
await this.queryRun(
|
|
2367
|
-
`ROLLBACK TO SAVEPOINT ${PostgreSQLDriver.escape(name)}
|
|
2330
|
+
`ROLLBACK TO SAVEPOINT ${PostgreSQLDriver.escape(name)};`,
|
|
2368
2331
|
);
|
|
2369
2332
|
this.transaction.count--;
|
|
2370
2333
|
if (this.transaction.count === 0) {
|
|
@@ -2381,12 +2344,13 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
2381
2344
|
guid: string,
|
|
2382
2345
|
data: EntityData,
|
|
2383
2346
|
sdata: SerializedEntityData,
|
|
2384
|
-
|
|
2347
|
+
uniques: string[],
|
|
2348
|
+
etype: string,
|
|
2385
2349
|
) => {
|
|
2386
2350
|
const runInsertQuery = async (
|
|
2387
2351
|
name: string,
|
|
2388
2352
|
value: any,
|
|
2389
|
-
svalue: string
|
|
2353
|
+
svalue: string,
|
|
2390
2354
|
) => {
|
|
2391
2355
|
if (value === undefined) {
|
|
2392
2356
|
return;
|
|
@@ -2401,7 +2365,7 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
2401
2365
|
promises.push(
|
|
2402
2366
|
this.queryRun(
|
|
2403
2367
|
`INSERT INTO ${PostgreSQLDriver.escape(
|
|
2404
|
-
`${this.prefix}data_${etype}
|
|
2368
|
+
`${this.prefix}data_${etype}`,
|
|
2405
2369
|
)} ("guid", "name", "value") VALUES (decode(@guid, 'hex'), @name, @storageValue);`,
|
|
2406
2370
|
{
|
|
2407
2371
|
etypes: [etype],
|
|
@@ -2410,13 +2374,13 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
2410
2374
|
name,
|
|
2411
2375
|
storageValue,
|
|
2412
2376
|
},
|
|
2413
|
-
}
|
|
2414
|
-
)
|
|
2377
|
+
},
|
|
2378
|
+
),
|
|
2415
2379
|
);
|
|
2416
2380
|
promises.push(
|
|
2417
2381
|
this.queryRun(
|
|
2418
2382
|
`INSERT INTO ${PostgreSQLDriver.escape(
|
|
2419
|
-
`${this.prefix}comparisons_${etype}
|
|
2383
|
+
`${this.prefix}comparisons_${etype}`,
|
|
2420
2384
|
)} ("guid", "name", "truthy", "string", "number") VALUES (decode(@guid, 'hex'), @name, @truthy, @string, @number);`,
|
|
2421
2385
|
{
|
|
2422
2386
|
etypes: [etype],
|
|
@@ -2427,15 +2391,15 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
2427
2391
|
string: `${value}`,
|
|
2428
2392
|
number: isNaN(Number(value)) ? null : Number(value),
|
|
2429
2393
|
},
|
|
2430
|
-
}
|
|
2431
|
-
)
|
|
2394
|
+
},
|
|
2395
|
+
),
|
|
2432
2396
|
);
|
|
2433
2397
|
const references = this.findReferences(svalue);
|
|
2434
2398
|
for (const reference of references) {
|
|
2435
2399
|
promises.push(
|
|
2436
2400
|
this.queryRun(
|
|
2437
2401
|
`INSERT INTO ${PostgreSQLDriver.escape(
|
|
2438
|
-
`${this.prefix}references_${etype}
|
|
2402
|
+
`${this.prefix}references_${etype}`,
|
|
2439
2403
|
)} ("guid", "name", "reference") VALUES (decode(@guid, 'hex'), @name, decode(@reference, 'hex'));`,
|
|
2440
2404
|
{
|
|
2441
2405
|
etypes: [etype],
|
|
@@ -2444,12 +2408,36 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
2444
2408
|
name,
|
|
2445
2409
|
reference,
|
|
2446
2410
|
},
|
|
2447
|
-
}
|
|
2448
|
-
)
|
|
2411
|
+
},
|
|
2412
|
+
),
|
|
2449
2413
|
);
|
|
2450
2414
|
}
|
|
2451
2415
|
await Promise.all(promises);
|
|
2452
2416
|
};
|
|
2417
|
+
for (const unique of uniques) {
|
|
2418
|
+
try {
|
|
2419
|
+
await this.queryRun(
|
|
2420
|
+
`INSERT INTO ${PostgreSQLDriver.escape(
|
|
2421
|
+
`${this.prefix}uniques_${etype}`,
|
|
2422
|
+
)} ("guid", "unique") VALUES (decode(@guid, 'hex'), @unique);`,
|
|
2423
|
+
{
|
|
2424
|
+
etypes: [etype],
|
|
2425
|
+
params: {
|
|
2426
|
+
guid,
|
|
2427
|
+
unique,
|
|
2428
|
+
},
|
|
2429
|
+
},
|
|
2430
|
+
);
|
|
2431
|
+
} catch (e: any) {
|
|
2432
|
+
if (e instanceof EntityUniqueConstraintError) {
|
|
2433
|
+
this.nymph.config.debugError(
|
|
2434
|
+
'postgresql',
|
|
2435
|
+
`Save entity unique constraint violation for GUID "${guid}" on etype "${etype}": "${unique}"`,
|
|
2436
|
+
);
|
|
2437
|
+
}
|
|
2438
|
+
throw e;
|
|
2439
|
+
}
|
|
2440
|
+
}
|
|
2453
2441
|
for (const name in data) {
|
|
2454
2442
|
await runInsertQuery(name, data[name], JSON.stringify(data[name]));
|
|
2455
2443
|
}
|
|
@@ -2457,13 +2445,20 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
2457
2445
|
await runInsertQuery(name, JSON.parse(sdata[name]), sdata[name]);
|
|
2458
2446
|
}
|
|
2459
2447
|
};
|
|
2448
|
+
let inTransaction = false;
|
|
2460
2449
|
try {
|
|
2461
2450
|
const result = await this.saveEntityRowLike(
|
|
2462
2451
|
entity,
|
|
2463
|
-
async (
|
|
2452
|
+
async ({ guid, tags, data, sdata, uniques, cdate, etype }) => {
|
|
2453
|
+
if (
|
|
2454
|
+
Object.keys(data).length === 0 &&
|
|
2455
|
+
Object.keys(sdata).length === 0
|
|
2456
|
+
) {
|
|
2457
|
+
return false;
|
|
2458
|
+
}
|
|
2464
2459
|
await this.queryRun(
|
|
2465
2460
|
`INSERT INTO ${PostgreSQLDriver.escape(
|
|
2466
|
-
`${this.prefix}entities_${etype}
|
|
2461
|
+
`${this.prefix}entities_${etype}`,
|
|
2467
2462
|
)} ("guid", "tags", "cdate", "mdate") VALUES (decode(@guid, 'hex'), @tags, @cdate, @cdate);`,
|
|
2468
2463
|
{
|
|
2469
2464
|
etypes: [etype],
|
|
@@ -2472,69 +2467,88 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
2472
2467
|
tags,
|
|
2473
2468
|
cdate,
|
|
2474
2469
|
},
|
|
2475
|
-
}
|
|
2470
|
+
},
|
|
2476
2471
|
);
|
|
2477
|
-
await insertData(guid, data, sdata, etype);
|
|
2472
|
+
await insertData(guid, data, sdata, uniques, etype);
|
|
2478
2473
|
return true;
|
|
2479
2474
|
},
|
|
2480
|
-
async (entity, guid, tags, data, sdata, mdate, etype) => {
|
|
2475
|
+
async ({ entity, guid, tags, data, sdata, uniques, mdate, etype }) => {
|
|
2476
|
+
if (
|
|
2477
|
+
Object.keys(data).length === 0 &&
|
|
2478
|
+
Object.keys(sdata).length === 0
|
|
2479
|
+
) {
|
|
2480
|
+
return false;
|
|
2481
|
+
}
|
|
2481
2482
|
const promises = [];
|
|
2482
2483
|
promises.push(
|
|
2483
2484
|
this.queryRun(
|
|
2484
2485
|
`SELECT 1 FROM ${PostgreSQLDriver.escape(
|
|
2485
|
-
`${this.prefix}entities_${etype}
|
|
2486
|
+
`${this.prefix}entities_${etype}`,
|
|
2486
2487
|
)} WHERE "guid"=decode(@guid, 'hex') FOR UPDATE;`,
|
|
2487
2488
|
{
|
|
2488
2489
|
etypes: [etype],
|
|
2489
2490
|
params: {
|
|
2490
2491
|
guid,
|
|
2491
2492
|
},
|
|
2492
|
-
}
|
|
2493
|
-
)
|
|
2493
|
+
},
|
|
2494
|
+
),
|
|
2494
2495
|
);
|
|
2495
2496
|
promises.push(
|
|
2496
2497
|
this.queryRun(
|
|
2497
2498
|
`SELECT 1 FROM ${PostgreSQLDriver.escape(
|
|
2498
|
-
`${this.prefix}data_${etype}
|
|
2499
|
+
`${this.prefix}data_${etype}`,
|
|
2499
2500
|
)} WHERE "guid"=decode(@guid, 'hex') FOR UPDATE;`,
|
|
2500
2501
|
{
|
|
2501
2502
|
etypes: [etype],
|
|
2502
2503
|
params: {
|
|
2503
2504
|
guid,
|
|
2504
2505
|
},
|
|
2505
|
-
}
|
|
2506
|
-
)
|
|
2506
|
+
},
|
|
2507
|
+
),
|
|
2507
2508
|
);
|
|
2508
2509
|
promises.push(
|
|
2509
2510
|
this.queryRun(
|
|
2510
2511
|
`SELECT 1 FROM ${PostgreSQLDriver.escape(
|
|
2511
|
-
`${this.prefix}comparisons_${etype}
|
|
2512
|
+
`${this.prefix}comparisons_${etype}`,
|
|
2512
2513
|
)} WHERE "guid"=decode(@guid, 'hex') FOR UPDATE;`,
|
|
2513
2514
|
{
|
|
2514
2515
|
etypes: [etype],
|
|
2515
2516
|
params: {
|
|
2516
2517
|
guid,
|
|
2517
2518
|
},
|
|
2518
|
-
}
|
|
2519
|
-
)
|
|
2519
|
+
},
|
|
2520
|
+
),
|
|
2520
2521
|
);
|
|
2521
2522
|
promises.push(
|
|
2522
2523
|
this.queryRun(
|
|
2523
2524
|
`SELECT 1 FROM ${PostgreSQLDriver.escape(
|
|
2524
|
-
`${this.prefix}references_${etype}
|
|
2525
|
+
`${this.prefix}references_${etype}`,
|
|
2525
2526
|
)} WHERE "guid"=decode(@guid, 'hex') FOR UPDATE;`,
|
|
2526
2527
|
{
|
|
2527
2528
|
etypes: [etype],
|
|
2528
2529
|
params: {
|
|
2529
2530
|
guid,
|
|
2530
2531
|
},
|
|
2531
|
-
}
|
|
2532
|
-
)
|
|
2532
|
+
},
|
|
2533
|
+
),
|
|
2534
|
+
);
|
|
2535
|
+
promises.push(
|
|
2536
|
+
this.queryRun(
|
|
2537
|
+
`SELECT 1 FROM ${PostgreSQLDriver.escape(
|
|
2538
|
+
`${this.prefix}uniques_${etype}`,
|
|
2539
|
+
)} WHERE "guid"=decode(@guid, 'hex') FOR UPDATE;`,
|
|
2540
|
+
{
|
|
2541
|
+
etypes: [etype],
|
|
2542
|
+
params: {
|
|
2543
|
+
guid,
|
|
2544
|
+
},
|
|
2545
|
+
},
|
|
2546
|
+
),
|
|
2533
2547
|
);
|
|
2534
2548
|
await Promise.all(promises);
|
|
2535
2549
|
const info = await this.queryRun(
|
|
2536
2550
|
`UPDATE ${PostgreSQLDriver.escape(
|
|
2537
|
-
`${this.prefix}entities_${etype}
|
|
2551
|
+
`${this.prefix}entities_${etype}`,
|
|
2538
2552
|
)} SET "tags"=@tags, "mdate"=@mdate WHERE "guid"=decode(@guid, 'hex') AND "mdate" <= @emdate;`,
|
|
2539
2553
|
{
|
|
2540
2554
|
etypes: [etype],
|
|
@@ -2544,7 +2558,7 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
2544
2558
|
guid,
|
|
2545
2559
|
emdate: isNaN(Number(entity.mdate)) ? 0 : Number(entity.mdate),
|
|
2546
2560
|
},
|
|
2547
|
-
}
|
|
2561
|
+
},
|
|
2548
2562
|
);
|
|
2549
2563
|
let success = false;
|
|
2550
2564
|
if (info.rowCount === 1) {
|
|
@@ -2552,64 +2566,84 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
2552
2566
|
promises.push(
|
|
2553
2567
|
this.queryRun(
|
|
2554
2568
|
`DELETE FROM ${PostgreSQLDriver.escape(
|
|
2555
|
-
`${this.prefix}data_${etype}
|
|
2569
|
+
`${this.prefix}data_${etype}`,
|
|
2556
2570
|
)} WHERE "guid"=decode(@guid, 'hex');`,
|
|
2557
2571
|
{
|
|
2558
2572
|
etypes: [etype],
|
|
2559
2573
|
params: {
|
|
2560
2574
|
guid,
|
|
2561
2575
|
},
|
|
2562
|
-
}
|
|
2563
|
-
)
|
|
2576
|
+
},
|
|
2577
|
+
),
|
|
2564
2578
|
);
|
|
2565
2579
|
promises.push(
|
|
2566
2580
|
this.queryRun(
|
|
2567
2581
|
`DELETE FROM ${PostgreSQLDriver.escape(
|
|
2568
|
-
`${this.prefix}comparisons_${etype}
|
|
2582
|
+
`${this.prefix}comparisons_${etype}`,
|
|
2569
2583
|
)} WHERE "guid"=decode(@guid, 'hex');`,
|
|
2570
2584
|
{
|
|
2571
2585
|
etypes: [etype],
|
|
2572
2586
|
params: {
|
|
2573
2587
|
guid,
|
|
2574
2588
|
},
|
|
2575
|
-
}
|
|
2576
|
-
)
|
|
2589
|
+
},
|
|
2590
|
+
),
|
|
2577
2591
|
);
|
|
2578
2592
|
promises.push(
|
|
2579
2593
|
this.queryRun(
|
|
2580
2594
|
`DELETE FROM ${PostgreSQLDriver.escape(
|
|
2581
|
-
`${this.prefix}references_${etype}
|
|
2595
|
+
`${this.prefix}references_${etype}`,
|
|
2582
2596
|
)} WHERE "guid"=decode(@guid, 'hex');`,
|
|
2583
2597
|
{
|
|
2584
2598
|
etypes: [etype],
|
|
2585
2599
|
params: {
|
|
2586
2600
|
guid,
|
|
2587
2601
|
},
|
|
2588
|
-
}
|
|
2589
|
-
)
|
|
2602
|
+
},
|
|
2603
|
+
),
|
|
2604
|
+
);
|
|
2605
|
+
promises.push(
|
|
2606
|
+
this.queryRun(
|
|
2607
|
+
`DELETE FROM ${PostgreSQLDriver.escape(
|
|
2608
|
+
`${this.prefix}uniques_${etype}`,
|
|
2609
|
+
)} WHERE "guid"=decode(@guid, 'hex');`,
|
|
2610
|
+
{
|
|
2611
|
+
etypes: [etype],
|
|
2612
|
+
params: {
|
|
2613
|
+
guid,
|
|
2614
|
+
},
|
|
2615
|
+
},
|
|
2616
|
+
),
|
|
2590
2617
|
);
|
|
2591
2618
|
await Promise.all(promises);
|
|
2592
|
-
await insertData(guid, data, sdata, etype);
|
|
2619
|
+
await insertData(guid, data, sdata, uniques, etype);
|
|
2593
2620
|
success = true;
|
|
2594
2621
|
}
|
|
2595
2622
|
return success;
|
|
2596
2623
|
},
|
|
2597
2624
|
async () => {
|
|
2598
2625
|
await this.internalTransaction('nymph-save');
|
|
2626
|
+
inTransaction = true;
|
|
2599
2627
|
},
|
|
2600
2628
|
async (success) => {
|
|
2601
|
-
if (
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2629
|
+
if (inTransaction) {
|
|
2630
|
+
inTransaction = false;
|
|
2631
|
+
if (success) {
|
|
2632
|
+
await this.commit('nymph-save');
|
|
2633
|
+
} else {
|
|
2634
|
+
await this.rollback('nymph-save');
|
|
2635
|
+
}
|
|
2605
2636
|
}
|
|
2606
2637
|
return success;
|
|
2607
|
-
}
|
|
2638
|
+
},
|
|
2608
2639
|
);
|
|
2609
2640
|
|
|
2610
2641
|
return result;
|
|
2611
2642
|
} catch (e: any) {
|
|
2612
|
-
|
|
2643
|
+
this.nymph.config.debugError('postgresql', `Save entity error: "${e}"`);
|
|
2644
|
+
if (inTransaction) {
|
|
2645
|
+
await this.rollback('nymph-save');
|
|
2646
|
+
}
|
|
2613
2647
|
throw e;
|
|
2614
2648
|
}
|
|
2615
2649
|
}
|
|
@@ -2622,38 +2656,39 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
2622
2656
|
try {
|
|
2623
2657
|
await this.queryRun(
|
|
2624
2658
|
`DELETE FROM ${PostgreSQLDriver.escape(
|
|
2625
|
-
`${this.prefix}uids
|
|
2659
|
+
`${this.prefix}uids`,
|
|
2626
2660
|
)} WHERE "name"=@name;`,
|
|
2627
2661
|
{
|
|
2628
2662
|
params: {
|
|
2629
2663
|
name,
|
|
2630
2664
|
curUid,
|
|
2631
2665
|
},
|
|
2632
|
-
}
|
|
2666
|
+
},
|
|
2633
2667
|
);
|
|
2634
2668
|
await this.queryRun(
|
|
2635
2669
|
`INSERT INTO ${PostgreSQLDriver.escape(
|
|
2636
|
-
`${this.prefix}uids
|
|
2670
|
+
`${this.prefix}uids`,
|
|
2637
2671
|
)} ("name", "cur_uid") VALUES (@name, @curUid);`,
|
|
2638
2672
|
{
|
|
2639
2673
|
params: {
|
|
2640
2674
|
name,
|
|
2641
2675
|
curUid,
|
|
2642
2676
|
},
|
|
2643
|
-
}
|
|
2677
|
+
},
|
|
2644
2678
|
);
|
|
2645
|
-
await this.commit('nymph-setuid');
|
|
2646
|
-
return true;
|
|
2647
2679
|
} catch (e: any) {
|
|
2648
2680
|
await this.rollback('nymph-setuid');
|
|
2649
2681
|
throw e;
|
|
2650
2682
|
}
|
|
2683
|
+
|
|
2684
|
+
await this.commit('nymph-setuid');
|
|
2685
|
+
return true;
|
|
2651
2686
|
}
|
|
2652
2687
|
|
|
2653
2688
|
private async internalTransaction(name: string) {
|
|
2654
2689
|
if (name == null || typeof name !== 'string' || name.length === 0) {
|
|
2655
2690
|
throw new InvalidParametersError(
|
|
2656
|
-
'Transaction start attempted without a name.'
|
|
2691
|
+
'Transaction start attempted without a name.',
|
|
2657
2692
|
);
|
|
2658
2693
|
}
|
|
2659
2694
|
|
|
@@ -2675,15 +2710,14 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
2675
2710
|
}
|
|
2676
2711
|
|
|
2677
2712
|
public async startTransaction(name: string) {
|
|
2678
|
-
const inTransaction = this.inTransaction();
|
|
2713
|
+
const inTransaction = await this.inTransaction();
|
|
2679
2714
|
const transaction = await this.internalTransaction(name);
|
|
2680
2715
|
if (!inTransaction) {
|
|
2681
2716
|
this.transaction = null;
|
|
2682
2717
|
}
|
|
2683
2718
|
|
|
2684
2719
|
const nymph = this.nymph.clone();
|
|
2685
|
-
nymph.driver
|
|
2686
|
-
nymph.driver.init(nymph);
|
|
2720
|
+
(nymph.driver as PostgreSQLDriver).transaction = transaction;
|
|
2687
2721
|
|
|
2688
2722
|
return nymph;
|
|
2689
2723
|
}
|