@nymphjs/driver-postgresql 1.0.0-beta.97 → 1.0.0-beta.99
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 +20 -0
- package/dist/PostgreSQLDriver.d.ts +18 -2
- package/dist/PostgreSQLDriver.js +454 -137
- package/dist/PostgreSQLDriver.js.map +1 -1
- package/package.json +5 -4
- package/src/PostgreSQLDriver.ts +1075 -426
package/dist/PostgreSQLDriver.js
CHANGED
|
@@ -164,32 +164,27 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
164
164
|
isConnected() {
|
|
165
165
|
return this.connected;
|
|
166
166
|
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
* @param etype The entity type to create a table for. If this is blank, the default tables are created.
|
|
171
|
-
* @returns True on success, false on failure.
|
|
172
|
-
*/
|
|
173
|
-
async createTables(etype = null) {
|
|
174
|
-
const connection = await this.getConnection(true);
|
|
175
|
-
if (etype != null) {
|
|
176
|
-
// Create the entity table.
|
|
177
|
-
await this.queryRun(`CREATE TABLE IF NOT EXISTS ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}`)} (
|
|
167
|
+
async createEntitiesTable(etype, connection) {
|
|
168
|
+
// Create the entity table.
|
|
169
|
+
await this.queryRun(`CREATE TABLE IF NOT EXISTS ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}`)} (
|
|
178
170
|
"guid" BYTEA NOT NULL,
|
|
179
171
|
"tags" TEXT[],
|
|
180
172
|
"cdate" DOUBLE PRECISION NOT NULL,
|
|
181
173
|
"mdate" DOUBLE PRECISION NOT NULL,
|
|
182
174
|
PRIMARY KEY ("guid")
|
|
183
175
|
) WITH ( OIDS=FALSE );`, { connection });
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
176
|
+
await this.queryRun(`ALTER TABLE ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}`)} OWNER TO ${PostgreSQLDriver.escape(this.config.user)};`, { connection });
|
|
177
|
+
await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}_id_cdate`)};`, { connection });
|
|
178
|
+
await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}_id_cdate`)} ON ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}`)} USING btree ("cdate");`, { connection });
|
|
179
|
+
await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}_id_mdate`)};`, { connection });
|
|
180
|
+
await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}_id_mdate`)} ON ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}`)} USING btree ("mdate");`, { connection });
|
|
181
|
+
await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}_id_tags`)};`, { connection });
|
|
182
|
+
await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}_id_tags`)} ON ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}`)} USING gin ("tags");`, { connection });
|
|
183
|
+
await this.queryRun(`ALTER TABLE ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}`)} SET ( autovacuum_vacuum_scale_factor = 0.05, autovacuum_analyze_scale_factor = 0.05 );`, { connection });
|
|
184
|
+
}
|
|
185
|
+
async createDataTable(etype, connection) {
|
|
186
|
+
// Create the data table.
|
|
187
|
+
await this.queryRun(`CREATE TABLE IF NOT EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} (
|
|
193
188
|
"guid" BYTEA NOT NULL,
|
|
194
189
|
"name" TEXT NOT NULL,
|
|
195
190
|
"value" CHARACTER(1) NOT NULL,
|
|
@@ -201,31 +196,46 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
201
196
|
FOREIGN KEY ("guid")
|
|
202
197
|
REFERENCES ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}`)} ("guid") MATCH SIMPLE ON UPDATE NO ACTION ON DELETE CASCADE
|
|
203
198
|
) WITH ( OIDS=FALSE );`, { connection });
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
199
|
+
await this.queryRun(`ALTER TABLE ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} OWNER TO ${PostgreSQLDriver.escape(this.config.user)};`, { connection });
|
|
200
|
+
await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_guid`)};`, { connection });
|
|
201
|
+
await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_guid`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING btree ("guid");`, { connection });
|
|
202
|
+
await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_guid_name`)};`, { connection });
|
|
203
|
+
await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_guid_name`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING btree ("guid", "name");`, { connection });
|
|
204
|
+
await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_guid_name__user`)};`, { connection });
|
|
205
|
+
await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_guid_name__user`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING btree ("guid") WHERE "name" = 'user'::text;`, { connection });
|
|
206
|
+
await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_guid_name__group`)};`, { connection });
|
|
207
|
+
await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_guid_name__group`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING btree ("guid") WHERE "name" = 'group'::text;`, { connection });
|
|
208
|
+
await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_name`)};`, { connection });
|
|
209
|
+
await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_name`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING btree ("name");`, { connection });
|
|
210
|
+
await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_name_string`)};`, { connection });
|
|
211
|
+
await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_name_string`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING btree ("name", LEFT("string", 512));`, { connection });
|
|
212
|
+
await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_name_number`)};`, { connection });
|
|
213
|
+
await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_name_number`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING btree ("name", "number");`, { connection });
|
|
214
|
+
await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_guid_name_number`)};`, { connection });
|
|
215
|
+
await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_guid_name_number`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING btree ("guid", "name", "number");`, { connection });
|
|
216
|
+
await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_name_truthy`)};`, { connection });
|
|
217
|
+
await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_name_truthy`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING btree ("name", "truthy");`, { connection });
|
|
218
|
+
await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_guid_name_truthy`)};`, { connection });
|
|
219
|
+
await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_guid_name_truthy`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING btree ("guid", "name", "truthy");`, { connection });
|
|
220
|
+
await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_string`)};`, { connection });
|
|
221
|
+
await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_string`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING gin ("string" gin_trgm_ops);`, { connection });
|
|
222
|
+
await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_json`)};`, { connection });
|
|
223
|
+
await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_json`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING gin ("json");`, { connection });
|
|
224
|
+
await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_acuserread`)};`, { connection });
|
|
225
|
+
await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_acuserread`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING btree ("guid") WHERE "name"='acUser' AND "number" >= 1;`, { connection });
|
|
226
|
+
await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_acgroupread`)};`, { connection });
|
|
227
|
+
await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_acgroupread`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING btree ("guid") WHERE "name"='acGroup' AND "number" >= 1;`, { connection });
|
|
228
|
+
await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_acotherread`)};`, { connection });
|
|
229
|
+
await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_acotherread`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING btree ("guid") WHERE "name"='acOther' AND "number" >= 1;`, { connection });
|
|
230
|
+
await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_acuser`)};`, { connection });
|
|
231
|
+
await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_acuser`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING btree ("guid") WHERE "name"='user';`, { connection });
|
|
232
|
+
await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_acgroup`)};`, { connection });
|
|
233
|
+
await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_acgroup`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING btree ("guid") WHERE "name"='group';`, { connection });
|
|
234
|
+
await this.queryRun(`ALTER TABLE ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} SET ( autovacuum_vacuum_scale_factor = 0.05, autovacuum_analyze_scale_factor = 0.05 );`, { connection });
|
|
235
|
+
}
|
|
236
|
+
async createReferencesTable(etype, connection) {
|
|
237
|
+
// Create the references table.
|
|
238
|
+
await this.queryRun(`CREATE TABLE IF NOT EXISTS ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}`)} (
|
|
229
239
|
"guid" BYTEA NOT NULL,
|
|
230
240
|
"name" TEXT NOT NULL,
|
|
231
241
|
"reference" BYTEA NOT NULL,
|
|
@@ -233,21 +243,69 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
233
243
|
FOREIGN KEY ("guid")
|
|
234
244
|
REFERENCES ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}`)} ("guid") MATCH SIMPLE ON UPDATE NO ACTION ON DELETE CASCADE
|
|
235
245
|
) WITH ( OIDS=FALSE );`, { connection });
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
246
|
+
await this.queryRun(`ALTER TABLE ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}`)} OWNER TO ${PostgreSQLDriver.escape(this.config.user)};`, { connection });
|
|
247
|
+
await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}_id_guid`)};`, { connection });
|
|
248
|
+
await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}_id_guid`)} ON ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}`)} USING btree ("guid");`, { connection });
|
|
249
|
+
await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}_id_name`)};`, { connection });
|
|
250
|
+
await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}_id_name`)} ON ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}`)} USING btree ("name");`, { connection });
|
|
251
|
+
await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}_id_name_reference`)};`, { connection });
|
|
252
|
+
await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}_id_name_reference`)} ON ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}`)} USING btree ("name", "reference");`, { connection });
|
|
253
|
+
await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}_id_reference`)};`, { connection });
|
|
254
|
+
await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}_id_reference`)} ON ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}`)} USING btree ("reference");`, { connection });
|
|
255
|
+
await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}_id_guid_name_reference`)};`, { connection });
|
|
256
|
+
await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}_id_guid_name_reference`)} ON ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}`)} USING btree ("guid", "name", "reference");`, { connection });
|
|
257
|
+
await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}_id_reference_name_guid`)};`, { connection });
|
|
258
|
+
await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}_id_reference_name_guid`)} ON ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}`)} USING btree ("reference", "name", "guid");`, { connection });
|
|
259
|
+
await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}_id_reference_guid_name`)};`, { connection });
|
|
260
|
+
await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}_id_reference_guid_name`)} ON ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}`)} USING btree ("reference", "guid", "name");`, { connection });
|
|
261
|
+
await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}_id_guid_reference_nameuser`)};`, { connection });
|
|
262
|
+
await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}_id_guid_reference_nameuser`)} ON ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}`)} USING btree ("guid", "reference") WHERE "name"='user';`, { connection });
|
|
263
|
+
await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}_id_guid_reference_namegroup`)};`, { connection });
|
|
264
|
+
await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}_id_guid_reference_namegroup`)} ON ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}`)} USING btree ("guid", "reference") WHERE "name"='group';`, { connection });
|
|
265
|
+
await this.queryRun(`ALTER TABLE ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}`)} SET ( autovacuum_vacuum_scale_factor = 0.05, autovacuum_analyze_scale_factor = 0.05 );`, { connection });
|
|
266
|
+
}
|
|
267
|
+
async createTokensTable(etype, connection) {
|
|
268
|
+
// Create the tokens table.
|
|
269
|
+
await this.queryRun(`CREATE TABLE IF NOT EXISTS ${PostgreSQLDriver.escape(`${this.prefix}tokens_${etype}`)} (
|
|
270
|
+
"guid" BYTEA NOT NULL,
|
|
271
|
+
"name" TEXT NOT NULL,
|
|
272
|
+
"token" INTEGER NOT NULL,
|
|
273
|
+
"position" INTEGER NOT NULL,
|
|
274
|
+
"stem" BOOLEAN NOT NULL,
|
|
275
|
+
PRIMARY KEY ("guid", "name", "token", "position"),
|
|
276
|
+
FOREIGN KEY ("guid")
|
|
277
|
+
REFERENCES ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}`)} ("guid") MATCH SIMPLE ON UPDATE NO ACTION ON DELETE CASCADE
|
|
278
|
+
) WITH ( OIDS=FALSE );`, { connection });
|
|
279
|
+
await this.queryRun(`ALTER TABLE ${PostgreSQLDriver.escape(`${this.prefix}tokens_${etype}`)} OWNER TO ${PostgreSQLDriver.escape(this.config.user)};`, { connection });
|
|
280
|
+
await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}tokens_${etype}_id_name_token`)};`, { connection });
|
|
281
|
+
await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}tokens_${etype}_id_name_token`)} ON ${PostgreSQLDriver.escape(`${this.prefix}tokens_${etype}`)} USING btree ("name", "token");`, { connection });
|
|
282
|
+
await this.queryRun(`ALTER TABLE ${PostgreSQLDriver.escape(`${this.prefix}tokens_${etype}`)} SET ( autovacuum_vacuum_scale_factor = 0.05, autovacuum_analyze_scale_factor = 0.05 );`, { connection });
|
|
283
|
+
}
|
|
284
|
+
async createUniquesTable(etype, connection) {
|
|
285
|
+
// Create the unique strings table.
|
|
286
|
+
await this.queryRun(`CREATE TABLE IF NOT EXISTS ${PostgreSQLDriver.escape(`${this.prefix}uniques_${etype}`)} (
|
|
245
287
|
"guid" BYTEA NOT NULL,
|
|
246
288
|
"unique" TEXT NOT NULL UNIQUE,
|
|
247
289
|
PRIMARY KEY ("guid", "unique"),
|
|
248
290
|
FOREIGN KEY ("guid")
|
|
249
291
|
REFERENCES ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}`)} ("guid") MATCH SIMPLE ON UPDATE NO ACTION ON DELETE CASCADE
|
|
250
292
|
) WITH ( OIDS=FALSE );`, { connection });
|
|
293
|
+
await this.queryRun(`ALTER TABLE ${PostgreSQLDriver.escape(`${this.prefix}uniques_${etype}`)} OWNER TO ${PostgreSQLDriver.escape(this.config.user)};`, { connection });
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Create entity tables in the database.
|
|
297
|
+
*
|
|
298
|
+
* @param etype The entity type to create a table for. If this is blank, the default tables are created.
|
|
299
|
+
* @returns True on success, false on failure.
|
|
300
|
+
*/
|
|
301
|
+
async createTables(etype = null) {
|
|
302
|
+
const connection = await this.getConnection(true);
|
|
303
|
+
if (etype != null) {
|
|
304
|
+
await this.createEntitiesTable(etype, connection);
|
|
305
|
+
await this.createDataTable(etype, connection);
|
|
306
|
+
await this.createReferencesTable(etype, connection);
|
|
307
|
+
await this.createTokensTable(etype, connection);
|
|
308
|
+
await this.createUniquesTable(etype, connection);
|
|
251
309
|
}
|
|
252
310
|
else {
|
|
253
311
|
// Add trigram extensions.
|
|
@@ -432,6 +490,12 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
432
490
|
guid,
|
|
433
491
|
},
|
|
434
492
|
});
|
|
493
|
+
await this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}tokens_${etype}`)} WHERE "guid"=decode(@guid, 'hex');`, {
|
|
494
|
+
etypes: [etype],
|
|
495
|
+
params: {
|
|
496
|
+
guid,
|
|
497
|
+
},
|
|
498
|
+
});
|
|
435
499
|
await this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}uniques_${etype}`)} WHERE "guid"=decode(@guid, 'hex');`, {
|
|
436
500
|
etypes: [etype],
|
|
437
501
|
params: {
|
|
@@ -462,6 +526,19 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
462
526
|
});
|
|
463
527
|
return true;
|
|
464
528
|
}
|
|
529
|
+
async getEtypes() {
|
|
530
|
+
const tables = await this.queryArray('SELECT "table_name" AS "table_name" FROM "information_schema"."tables" WHERE "table_catalog"=@db AND "table_schema"=\'public\' AND "table_name" LIKE @prefix;', {
|
|
531
|
+
params: {
|
|
532
|
+
db: this.config.database,
|
|
533
|
+
prefix: this.prefix + 'entities_' + '%',
|
|
534
|
+
},
|
|
535
|
+
});
|
|
536
|
+
const etypes = [];
|
|
537
|
+
for (const table of tables) {
|
|
538
|
+
etypes.push(table.table_name.substr((this.prefix + 'entities_').length));
|
|
539
|
+
}
|
|
540
|
+
return etypes;
|
|
541
|
+
}
|
|
465
542
|
async *exportDataIterator() {
|
|
466
543
|
if (yield {
|
|
467
544
|
type: 'comment',
|
|
@@ -506,16 +583,7 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
506
583
|
return;
|
|
507
584
|
}
|
|
508
585
|
// Get the etypes.
|
|
509
|
-
const
|
|
510
|
-
params: {
|
|
511
|
-
db: this.config.database,
|
|
512
|
-
prefix: this.prefix + 'entities_' + '%',
|
|
513
|
-
},
|
|
514
|
-
});
|
|
515
|
-
const etypes = [];
|
|
516
|
-
for (const table of tables) {
|
|
517
|
-
etypes.push(table.table_name.substr((this.prefix + 'entities_').length));
|
|
518
|
-
}
|
|
586
|
+
const etypes = await this.getEtypes();
|
|
519
587
|
for (const etype of etypes) {
|
|
520
588
|
// Export entities.
|
|
521
589
|
const dataIterator = await this.queryIter(`SELECT encode(e."guid", 'hex') AS "guid", e."tags", e."cdate", e."mdate", d."name", d."value", d."json", d."string", d."number"
|
|
@@ -839,6 +907,125 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
839
907
|
params[value] = PostgreSQLDriver.escapeNullSequences(svalue);
|
|
840
908
|
}
|
|
841
909
|
break;
|
|
910
|
+
case 'search':
|
|
911
|
+
case '!search':
|
|
912
|
+
if (curValue[0] === 'cdate' || curValue[0] === 'mdate') {
|
|
913
|
+
if (curQuery) {
|
|
914
|
+
curQuery += typeIsOr ? ' OR ' : ' AND ';
|
|
915
|
+
}
|
|
916
|
+
curQuery +=
|
|
917
|
+
(xor(typeIsNot, clauseNot) ? 'NOT ' : '') + '(FALSE)';
|
|
918
|
+
break;
|
|
919
|
+
}
|
|
920
|
+
else {
|
|
921
|
+
if (curQuery) {
|
|
922
|
+
curQuery += typeIsOr ? ' OR ' : ' AND ';
|
|
923
|
+
}
|
|
924
|
+
const name = `param${++count.i}`;
|
|
925
|
+
const queryPartToken = (term) => {
|
|
926
|
+
const value = `param${++count.i}`;
|
|
927
|
+
params[value] = term.token;
|
|
928
|
+
return ('EXISTS (SELECT "guid" FROM ' +
|
|
929
|
+
PostgreSQLDriver.escape(this.prefix + 'tokens_' + etype) +
|
|
930
|
+
' WHERE "guid"=' +
|
|
931
|
+
ieTable +
|
|
932
|
+
'."guid" AND "name"=@' +
|
|
933
|
+
name +
|
|
934
|
+
' AND "token"=@' +
|
|
935
|
+
value +
|
|
936
|
+
(term.nostemmed ? ' AND "stem"=FALSE' : '') +
|
|
937
|
+
')');
|
|
938
|
+
};
|
|
939
|
+
const queryPartSeries = (series) => {
|
|
940
|
+
const tokenTableSuffix = makeTableSuffix();
|
|
941
|
+
const tokenParts = series.tokens.map((token, i) => {
|
|
942
|
+
const value = `param${++count.i}`;
|
|
943
|
+
params[value] = token.token;
|
|
944
|
+
return {
|
|
945
|
+
fromClause: i === 0
|
|
946
|
+
? 'FROM ' +
|
|
947
|
+
PostgreSQLDriver.escape(this.prefix + 'tokens_' + etype) +
|
|
948
|
+
' t' +
|
|
949
|
+
tokenTableSuffix +
|
|
950
|
+
'0'
|
|
951
|
+
: 'JOIN ' +
|
|
952
|
+
PostgreSQLDriver.escape(this.prefix + 'tokens_' + etype) +
|
|
953
|
+
' t' +
|
|
954
|
+
tokenTableSuffix +
|
|
955
|
+
i +
|
|
956
|
+
' ON t' +
|
|
957
|
+
tokenTableSuffix +
|
|
958
|
+
i +
|
|
959
|
+
'."guid" = t' +
|
|
960
|
+
tokenTableSuffix +
|
|
961
|
+
'0."guid" AND t' +
|
|
962
|
+
tokenTableSuffix +
|
|
963
|
+
i +
|
|
964
|
+
'."name" = t' +
|
|
965
|
+
tokenTableSuffix +
|
|
966
|
+
'0."name" AND t' +
|
|
967
|
+
tokenTableSuffix +
|
|
968
|
+
i +
|
|
969
|
+
'."position" = t' +
|
|
970
|
+
tokenTableSuffix +
|
|
971
|
+
'0."position" + ' +
|
|
972
|
+
i,
|
|
973
|
+
whereClause: 't' +
|
|
974
|
+
tokenTableSuffix +
|
|
975
|
+
i +
|
|
976
|
+
'."token"=@' +
|
|
977
|
+
value +
|
|
978
|
+
(token.nostemmed
|
|
979
|
+
? ' AND t' + tokenTableSuffix + i + '."stem"=FALSE'
|
|
980
|
+
: ''),
|
|
981
|
+
};
|
|
982
|
+
});
|
|
983
|
+
return ('EXISTS (SELECT t' +
|
|
984
|
+
tokenTableSuffix +
|
|
985
|
+
'0."guid" ' +
|
|
986
|
+
tokenParts.map((part) => part.fromClause).join(' ') +
|
|
987
|
+
' WHERE t' +
|
|
988
|
+
tokenTableSuffix +
|
|
989
|
+
'0."guid"=' +
|
|
990
|
+
ieTable +
|
|
991
|
+
'."guid" AND t' +
|
|
992
|
+
tokenTableSuffix +
|
|
993
|
+
'0."name"=@' +
|
|
994
|
+
name +
|
|
995
|
+
' AND ' +
|
|
996
|
+
tokenParts.map((part) => part.whereClause).join(' AND ') +
|
|
997
|
+
')');
|
|
998
|
+
};
|
|
999
|
+
const queryPartTerm = (term) => {
|
|
1000
|
+
if (term.type === 'series') {
|
|
1001
|
+
return queryPartSeries(term);
|
|
1002
|
+
}
|
|
1003
|
+
else if (term.type === 'not') {
|
|
1004
|
+
return 'NOT ' + queryPartTerm(term.operand);
|
|
1005
|
+
}
|
|
1006
|
+
else if (term.type === 'or') {
|
|
1007
|
+
let queryParts = [];
|
|
1008
|
+
for (let operand of term.operands) {
|
|
1009
|
+
queryParts.push(queryPartTerm(operand));
|
|
1010
|
+
}
|
|
1011
|
+
return '(' + queryParts.join(' OR ') + ')';
|
|
1012
|
+
}
|
|
1013
|
+
return queryPartToken(term);
|
|
1014
|
+
};
|
|
1015
|
+
const parsedFTSQuery = this.tokenizer.parseSearchQuery(curValue[1]);
|
|
1016
|
+
// Run through the query and add terms.
|
|
1017
|
+
let termStrings = [];
|
|
1018
|
+
for (let term of parsedFTSQuery) {
|
|
1019
|
+
termStrings.push(queryPartTerm(term));
|
|
1020
|
+
}
|
|
1021
|
+
curQuery +=
|
|
1022
|
+
(xor(typeIsNot, clauseNot) ? 'NOT ' : '') +
|
|
1023
|
+
'(' +
|
|
1024
|
+
termStrings.join(' AND ') +
|
|
1025
|
+
')';
|
|
1026
|
+
params[name] = curValue[0];
|
|
1027
|
+
}
|
|
1028
|
+
break;
|
|
842
1029
|
case 'match':
|
|
843
1030
|
case '!match':
|
|
844
1031
|
if (curValue[0] === 'cdate') {
|
|
@@ -1584,100 +1771,163 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
1584
1771
|
});
|
|
1585
1772
|
return result?.cur_uid == null ? null : Number(result.cur_uid);
|
|
1586
1773
|
}
|
|
1587
|
-
async importEntity(
|
|
1774
|
+
async importEntity(entity) {
|
|
1775
|
+
return await this.importEntityInternal(entity, false);
|
|
1776
|
+
}
|
|
1777
|
+
async importEntityTokens(entity) {
|
|
1778
|
+
return await this.importEntityInternal(entity, true);
|
|
1779
|
+
}
|
|
1780
|
+
async importEntityInternal({ guid, cdate, mdate, tags, sdata, etype, }, onlyTokens) {
|
|
1588
1781
|
try {
|
|
1589
1782
|
let promises = [];
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1783
|
+
if (!onlyTokens) {
|
|
1784
|
+
promises.push(this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}`)} WHERE "guid"=decode(@guid, 'hex');`, {
|
|
1785
|
+
etypes: [etype],
|
|
1786
|
+
params: {
|
|
1787
|
+
guid,
|
|
1788
|
+
},
|
|
1789
|
+
}));
|
|
1790
|
+
promises.push(this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} WHERE "guid"=decode(@guid, 'hex');`, {
|
|
1791
|
+
etypes: [etype],
|
|
1792
|
+
params: {
|
|
1793
|
+
guid,
|
|
1794
|
+
},
|
|
1795
|
+
}));
|
|
1796
|
+
promises.push(this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}`)} WHERE "guid"=decode(@guid, 'hex');`, {
|
|
1797
|
+
etypes: [etype],
|
|
1798
|
+
params: {
|
|
1799
|
+
guid,
|
|
1800
|
+
},
|
|
1801
|
+
}));
|
|
1802
|
+
}
|
|
1803
|
+
promises.push(this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}tokens_${etype}`)} WHERE "guid"=decode(@guid, 'hex');`, {
|
|
1609
1804
|
etypes: [etype],
|
|
1610
1805
|
params: {
|
|
1611
1806
|
guid,
|
|
1612
1807
|
},
|
|
1613
1808
|
}));
|
|
1809
|
+
if (!onlyTokens) {
|
|
1810
|
+
promises.push(this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}uniques_${etype}`)} WHERE "guid"=decode(@guid, 'hex');`, {
|
|
1811
|
+
etypes: [etype],
|
|
1812
|
+
params: {
|
|
1813
|
+
guid,
|
|
1814
|
+
},
|
|
1815
|
+
}));
|
|
1816
|
+
}
|
|
1614
1817
|
await Promise.all(promises);
|
|
1615
1818
|
promises = [];
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
params: {
|
|
1619
|
-
guid,
|
|
1620
|
-
tags,
|
|
1621
|
-
cdate: isNaN(cdate) ? null : cdate,
|
|
1622
|
-
mdate: isNaN(mdate) ? null : mdate,
|
|
1623
|
-
},
|
|
1624
|
-
});
|
|
1625
|
-
for (const name in sdata) {
|
|
1626
|
-
const value = sdata[name];
|
|
1627
|
-
const uvalue = JSON.parse(value);
|
|
1628
|
-
if (value === undefined) {
|
|
1629
|
-
continue;
|
|
1630
|
-
}
|
|
1631
|
-
const storageValue = typeof uvalue === 'number'
|
|
1632
|
-
? 'N'
|
|
1633
|
-
: typeof uvalue === 'string'
|
|
1634
|
-
? 'S'
|
|
1635
|
-
: 'J';
|
|
1636
|
-
const jsonValue = storageValue === 'J'
|
|
1637
|
-
? PostgreSQLDriver.escapeNullSequences(value)
|
|
1638
|
-
: null;
|
|
1639
|
-
promises.push(this.queryRun(`INSERT INTO ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} ("guid", "name", "value", "json", "string", "number", "truthy") VALUES (decode(@guid, 'hex'), @name, @storageValue, @jsonValue, @string, @number, @truthy);`, {
|
|
1819
|
+
if (!onlyTokens) {
|
|
1820
|
+
await this.queryRun(`INSERT INTO ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}`)} ("guid", "tags", "cdate", "mdate") VALUES (decode(@guid, 'hex'), @tags, @cdate, @mdate);`, {
|
|
1640
1821
|
etypes: [etype],
|
|
1641
1822
|
params: {
|
|
1642
1823
|
guid,
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
string: storageValue === 'J'
|
|
1647
|
-
? null
|
|
1648
|
-
: PostgreSQLDriver.escapeNulls(`${uvalue}`),
|
|
1649
|
-
number: isNaN(Number(uvalue)) ? null : Number(uvalue),
|
|
1650
|
-
truthy: !!uvalue,
|
|
1824
|
+
tags,
|
|
1825
|
+
cdate: isNaN(cdate) ? null : cdate,
|
|
1826
|
+
mdate: isNaN(mdate) ? null : mdate,
|
|
1651
1827
|
},
|
|
1652
|
-
})
|
|
1653
|
-
const
|
|
1654
|
-
|
|
1655
|
-
|
|
1828
|
+
});
|
|
1829
|
+
for (const name in sdata) {
|
|
1830
|
+
const value = sdata[name];
|
|
1831
|
+
const uvalue = JSON.parse(value);
|
|
1832
|
+
if (value === undefined) {
|
|
1833
|
+
continue;
|
|
1834
|
+
}
|
|
1835
|
+
const storageValue = typeof uvalue === 'number'
|
|
1836
|
+
? 'N'
|
|
1837
|
+
: typeof uvalue === 'string'
|
|
1838
|
+
? 'S'
|
|
1839
|
+
: 'J';
|
|
1840
|
+
const jsonValue = storageValue === 'J'
|
|
1841
|
+
? PostgreSQLDriver.escapeNullSequences(value)
|
|
1842
|
+
: null;
|
|
1843
|
+
promises.push(this.queryRun(`INSERT INTO ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} ("guid", "name", "value", "json", "string", "number", "truthy") VALUES (decode(@guid, 'hex'), @name, @storageValue, @jsonValue, @string, @number, @truthy);`, {
|
|
1656
1844
|
etypes: [etype],
|
|
1657
1845
|
params: {
|
|
1658
1846
|
guid,
|
|
1659
1847
|
name,
|
|
1660
|
-
|
|
1848
|
+
storageValue,
|
|
1849
|
+
jsonValue,
|
|
1850
|
+
string: storageValue === 'J'
|
|
1851
|
+
? null
|
|
1852
|
+
: PostgreSQLDriver.escapeNulls(`${uvalue}`),
|
|
1853
|
+
number: isNaN(Number(uvalue)) ? null : Number(uvalue),
|
|
1854
|
+
truthy: !!uvalue,
|
|
1661
1855
|
},
|
|
1662
1856
|
}));
|
|
1857
|
+
const references = this.findReferences(value);
|
|
1858
|
+
for (const reference of references) {
|
|
1859
|
+
promises.push(this.queryRun(`INSERT INTO ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}`)} ("guid", "name", "reference") VALUES (decode(@guid, 'hex'), @name, decode(@reference, 'hex'));`, {
|
|
1860
|
+
etypes: [etype],
|
|
1861
|
+
params: {
|
|
1862
|
+
guid,
|
|
1863
|
+
name,
|
|
1864
|
+
reference,
|
|
1865
|
+
},
|
|
1866
|
+
}));
|
|
1867
|
+
}
|
|
1663
1868
|
}
|
|
1664
1869
|
}
|
|
1665
|
-
const
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1870
|
+
const EntityClass = this.nymph.getEntityClassByEtype(etype);
|
|
1871
|
+
for (let name in sdata) {
|
|
1872
|
+
let tokenString = null;
|
|
1873
|
+
try {
|
|
1874
|
+
tokenString = EntityClass.getFTSText(name, JSON.parse(sdata[name]));
|
|
1875
|
+
}
|
|
1876
|
+
catch (e) {
|
|
1877
|
+
// Ignore error.
|
|
1878
|
+
}
|
|
1879
|
+
if (tokenString != null) {
|
|
1880
|
+
const tokens = this.tokenizer.tokenize(tokenString);
|
|
1881
|
+
while (tokens.length) {
|
|
1882
|
+
const currentTokens = tokens.splice(0, 100);
|
|
1883
|
+
const params = {
|
|
1884
|
+
guid,
|
|
1885
|
+
name,
|
|
1886
|
+
};
|
|
1887
|
+
const values = [];
|
|
1888
|
+
for (let i = 0; i < currentTokens.length; i++) {
|
|
1889
|
+
const token = currentTokens[i];
|
|
1890
|
+
params['token' + i] = token.token;
|
|
1891
|
+
params['position' + i] = token.position;
|
|
1892
|
+
params['stem' + i] = token.stem;
|
|
1893
|
+
values.push("(decode(@guid, 'hex'), @name, @token" +
|
|
1894
|
+
i +
|
|
1895
|
+
', @position' +
|
|
1896
|
+
i +
|
|
1897
|
+
', @stem' +
|
|
1898
|
+
i +
|
|
1899
|
+
')');
|
|
1900
|
+
}
|
|
1901
|
+
promises.push(this.queryRun(`INSERT INTO ${PostgreSQLDriver.escape(`${this.prefix}tokens_${etype}`)} ("guid", "name", "token", "position", "stem") VALUES ${values.join(', ')};`, {
|
|
1902
|
+
etypes: [etype],
|
|
1903
|
+
params,
|
|
1904
|
+
}));
|
|
1678
1905
|
}
|
|
1679
|
-
|
|
1680
|
-
|
|
1906
|
+
}
|
|
1907
|
+
}
|
|
1908
|
+
if (!onlyTokens) {
|
|
1909
|
+
const uniques = await EntityClass.getUniques({
|
|
1910
|
+
guid,
|
|
1911
|
+
cdate,
|
|
1912
|
+
mdate,
|
|
1913
|
+
tags,
|
|
1914
|
+
data: {},
|
|
1915
|
+
sdata,
|
|
1916
|
+
});
|
|
1917
|
+
for (const unique of uniques) {
|
|
1918
|
+
promises.push(this.queryRun(`INSERT INTO ${PostgreSQLDriver.escape(`${this.prefix}uniques_${etype}`)} ("guid", "unique") VALUES (decode(@guid, 'hex'), @unique);`, {
|
|
1919
|
+
etypes: [etype],
|
|
1920
|
+
params: {
|
|
1921
|
+
guid,
|
|
1922
|
+
unique,
|
|
1923
|
+
},
|
|
1924
|
+
}).catch((e) => {
|
|
1925
|
+
if (e instanceof EntityUniqueConstraintError) {
|
|
1926
|
+
this.nymph.config.debugError('postgresql', `Import entity unique constraint violation for GUID "${guid}" on etype "${etype}": "${unique}"`);
|
|
1927
|
+
}
|
|
1928
|
+
return e;
|
|
1929
|
+
}));
|
|
1930
|
+
}
|
|
1681
1931
|
}
|
|
1682
1932
|
await Promise.all(promises);
|
|
1683
1933
|
}
|
|
@@ -1780,6 +2030,7 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
1780
2030
|
}
|
|
1781
2031
|
async saveEntity(entity) {
|
|
1782
2032
|
const insertData = async (guid, data, sdata, uniques, etype) => {
|
|
2033
|
+
const EntityClass = this.nymph.getEntityClassByEtype(etype);
|
|
1783
2034
|
const runInsertQuery = async (name, value, svalue) => {
|
|
1784
2035
|
if (value === undefined) {
|
|
1785
2036
|
return;
|
|
@@ -1818,6 +2069,41 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
1818
2069
|
},
|
|
1819
2070
|
}));
|
|
1820
2071
|
}
|
|
2072
|
+
let tokenString = null;
|
|
2073
|
+
try {
|
|
2074
|
+
tokenString = EntityClass.getFTSText(name, value);
|
|
2075
|
+
}
|
|
2076
|
+
catch (e) {
|
|
2077
|
+
// Ignore error.
|
|
2078
|
+
}
|
|
2079
|
+
if (tokenString != null) {
|
|
2080
|
+
const tokens = this.tokenizer.tokenize(tokenString);
|
|
2081
|
+
while (tokens.length) {
|
|
2082
|
+
const currentTokens = tokens.splice(0, 100);
|
|
2083
|
+
const params = {
|
|
2084
|
+
guid,
|
|
2085
|
+
name,
|
|
2086
|
+
};
|
|
2087
|
+
const values = [];
|
|
2088
|
+
for (let i = 0; i < currentTokens.length; i++) {
|
|
2089
|
+
const token = currentTokens[i];
|
|
2090
|
+
params['token' + i] = token.token;
|
|
2091
|
+
params['position' + i] = token.position;
|
|
2092
|
+
params['stem' + i] = token.stem;
|
|
2093
|
+
values.push("(decode(@guid, 'hex'), @name, @token" +
|
|
2094
|
+
i +
|
|
2095
|
+
', @position' +
|
|
2096
|
+
i +
|
|
2097
|
+
', @stem' +
|
|
2098
|
+
i +
|
|
2099
|
+
')');
|
|
2100
|
+
}
|
|
2101
|
+
promises.push(this.queryRun(`INSERT INTO ${PostgreSQLDriver.escape(`${this.prefix}tokens_${etype}`)} ("guid", "name", "token", "position", "stem") VALUES ${values.join(', ')};`, {
|
|
2102
|
+
etypes: [etype],
|
|
2103
|
+
params,
|
|
2104
|
+
}));
|
|
2105
|
+
}
|
|
2106
|
+
}
|
|
1821
2107
|
await Promise.all(promises);
|
|
1822
2108
|
};
|
|
1823
2109
|
for (const unique of uniques) {
|
|
@@ -1885,6 +2171,12 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
1885
2171
|
guid,
|
|
1886
2172
|
},
|
|
1887
2173
|
}));
|
|
2174
|
+
promises.push(this.queryRun(`SELECT 1 FROM ${PostgreSQLDriver.escape(`${this.prefix}tokens_${etype}`)} WHERE "guid"=decode(@guid, 'hex') FOR UPDATE;`, {
|
|
2175
|
+
etypes: [etype],
|
|
2176
|
+
params: {
|
|
2177
|
+
guid,
|
|
2178
|
+
},
|
|
2179
|
+
}));
|
|
1888
2180
|
promises.push(this.queryRun(`SELECT 1 FROM ${PostgreSQLDriver.escape(`${this.prefix}uniques_${etype}`)} WHERE "guid"=decode(@guid, 'hex') FOR UPDATE;`, {
|
|
1889
2181
|
etypes: [etype],
|
|
1890
2182
|
params: {
|
|
@@ -1916,6 +2208,12 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
1916
2208
|
guid,
|
|
1917
2209
|
},
|
|
1918
2210
|
}));
|
|
2211
|
+
promises.push(this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}tokens_${etype}`)} WHERE "guid"=decode(@guid, 'hex');`, {
|
|
2212
|
+
etypes: [etype],
|
|
2213
|
+
params: {
|
|
2214
|
+
guid,
|
|
2215
|
+
},
|
|
2216
|
+
}));
|
|
1919
2217
|
promises.push(this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}uniques_${etype}`)} WHERE "guid"=decode(@guid, 'hex');`, {
|
|
1920
2218
|
etypes: [etype],
|
|
1921
2219
|
params: {
|
|
@@ -2019,9 +2317,28 @@ export default class PostgreSQLDriver extends NymphDriver {
|
|
|
2019
2317
|
table: table.table_name,
|
|
2020
2318
|
},
|
|
2021
2319
|
});
|
|
2022
|
-
|
|
2320
|
+
if (!result?.exists) {
|
|
2321
|
+
return 'json';
|
|
2322
|
+
}
|
|
2323
|
+
}
|
|
2324
|
+
const table2 = await this.queryGet('SELECT "table_name" AS "table_name" FROM "information_schema"."tables" WHERE "table_catalog"=@db AND "table_schema"=\'public\' AND "table_name" LIKE @tokenTable LIMIT 1;', {
|
|
2325
|
+
params: {
|
|
2326
|
+
db: this.config.database,
|
|
2327
|
+
tokenTable: this.prefix + 'tokens_' + '%',
|
|
2328
|
+
},
|
|
2329
|
+
});
|
|
2330
|
+
if (!table2 || !table2.table_name) {
|
|
2331
|
+
return 'tokens';
|
|
2023
2332
|
}
|
|
2024
2333
|
return false;
|
|
2025
2334
|
}
|
|
2335
|
+
async liveMigration(_migrationType) {
|
|
2336
|
+
const etypes = await this.getEtypes();
|
|
2337
|
+
const connection = await this.getConnection(true);
|
|
2338
|
+
for (let etype of etypes) {
|
|
2339
|
+
await this.createTokensTable(etype, connection);
|
|
2340
|
+
}
|
|
2341
|
+
connection.done();
|
|
2342
|
+
}
|
|
2026
2343
|
}
|
|
2027
2344
|
//# sourceMappingURL=PostgreSQLDriver.js.map
|