@hedhog/pagination 0.0.17 → 0.0.22

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. package/dist/databases/abstract.database.d.ts +61 -0
  2. package/dist/databases/abstract.database.d.ts.map +1 -0
  3. package/dist/databases/abstract.database.js +643 -0
  4. package/dist/databases/abstract.database.js.map +1 -0
  5. package/dist/databases/database.d.ts +5 -0
  6. package/dist/databases/database.d.ts.map +1 -0
  7. package/dist/databases/database.factory.d.ts +7 -0
  8. package/dist/databases/database.factory.d.ts.map +1 -0
  9. package/dist/databases/database.factory.js +44 -0
  10. package/dist/databases/database.factory.js.map +1 -0
  11. package/dist/databases/database.js +9 -0
  12. package/dist/databases/database.js.map +1 -0
  13. package/dist/databases/index.d.ts +4 -0
  14. package/dist/databases/index.d.ts.map +1 -0
  15. package/dist/databases/index.js +20 -0
  16. package/dist/databases/index.js.map +1 -0
  17. package/dist/databases/mysql.database.d.ts +10 -0
  18. package/dist/databases/mysql.database.d.ts.map +1 -0
  19. package/dist/databases/mysql.database.js +17 -0
  20. package/dist/databases/mysql.database.js.map +1 -0
  21. package/dist/databases/postgres.database.d.ts +10 -0
  22. package/dist/databases/postgres.database.d.ts.map +1 -0
  23. package/dist/databases/postgres.database.js +17 -0
  24. package/dist/databases/postgres.database.js.map +1 -0
  25. package/dist/pagination.service.d.ts +18 -4
  26. package/dist/pagination.service.d.ts.map +1 -1
  27. package/dist/pagination.service.js +131 -5
  28. package/dist/pagination.service.js.map +1 -1
  29. package/dist/types/pagination.types.d.ts +1 -0
  30. package/dist/types/pagination.types.d.ts.map +1 -1
  31. package/dist/types/query-option.d.ts +5 -0
  32. package/dist/types/query-option.d.ts.map +1 -0
  33. package/dist/types/query-option.js +3 -0
  34. package/dist/types/query-option.js.map +1 -0
  35. package/dist/types/relation-n2n-result.d.ts +7 -0
  36. package/dist/types/relation-n2n-result.d.ts.map +1 -0
  37. package/dist/types/relation-n2n-result.js +3 -0
  38. package/dist/types/relation-n2n-result.js.map +1 -0
  39. package/dist/types/transaction-queries.d.ts +7 -0
  40. package/dist/types/transaction-queries.d.ts.map +1 -0
  41. package/dist/types/transaction-queries.js +3 -0
  42. package/dist/types/transaction-queries.js.map +1 -0
  43. package/package.json +6 -2
  44. package/src/databases/abstract.database.ts +833 -0
  45. package/src/databases/database.factory.ts +26 -0
  46. package/src/databases/database.ts +4 -0
  47. package/src/databases/index.ts +3 -0
  48. package/src/databases/mysql.database.ts +14 -0
  49. package/src/databases/postgres.database.ts +14 -0
  50. package/src/pagination.service.ts +229 -29
  51. package/src/types/pagination.types.ts +1 -0
  52. package/src/types/query-option.ts +4 -0
  53. package/src/types/relation-n2n-result.ts +6 -0
  54. package/src/types/transaction-queries.ts +7 -0
@@ -0,0 +1,643 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.AbstractDatabase = void 0;
27
+ const typeorm_1 = require("typeorm");
28
+ const database_1 = require("./database");
29
+ const EventEmitter = require("events");
30
+ class AbstractDatabase {
31
+ constructor(type, host, user, password, database, port) {
32
+ this.type = type;
33
+ this.host = host;
34
+ this.user = user;
35
+ this.password = password;
36
+ this.database = database;
37
+ this.port = port;
38
+ this.client = null;
39
+ this.foreignKeys = {};
40
+ this.foreignKeysByTable = {};
41
+ this.primaryKeys = {};
42
+ this.columnNameFromRelation = {};
43
+ this.relationN2N = {};
44
+ this.relation1N = {};
45
+ this.columnComment = {};
46
+ this.tableHasColumnOrder = {};
47
+ this.eventEmitter = new EventEmitter();
48
+ this.autoClose = true;
49
+ }
50
+ getDataSource() {
51
+ return new typeorm_1.DataSource({
52
+ type: this.type,
53
+ host: this.host,
54
+ port: this.port,
55
+ username: this.user,
56
+ password: this.password,
57
+ database: this.database,
58
+ synchronize: true,
59
+ logging: false,
60
+ entities: [],
61
+ subscribers: [],
62
+ migrations: [],
63
+ });
64
+ }
65
+ disableAutoClose() {
66
+ this.autoClose = false;
67
+ }
68
+ close() {
69
+ var _a;
70
+ return (_a = this.client) === null || _a === void 0 ? void 0 : _a.end();
71
+ }
72
+ on(event, listener) {
73
+ return this.eventEmitter.on(event, listener);
74
+ }
75
+ getArrayType(values) {
76
+ return [...new Set(values.map((value) => typeof value))][0];
77
+ }
78
+ getWhereWithIn(columnName, operator, values) {
79
+ switch (this.type) {
80
+ case database_1.Database.POSTGRES:
81
+ if (operator === 'in') {
82
+ return `${this.getColumnNameWithScaping(columnName)} = ANY(?::${this.getArrayType(values) === 'number' ? 'int' : 'text'}[])`;
83
+ }
84
+ else {
85
+ return `${this.getColumnNameWithScaping(columnName)} <> ALL(?::${this.getArrayType(values) === 'number' ? 'int' : 'text'}[])`;
86
+ }
87
+ case database_1.Database.MYSQL:
88
+ return `${this.getColumnNameWithScaping(columnName)} ${operator === 'in' ? 'IN' : 'NOT IN'}(${values.map((value) => AbstractDatabase.addSimpleQuotes(value)).join(', ')})`;
89
+ }
90
+ }
91
+ static addSimpleQuotes(value) {
92
+ if (typeof value === 'string') {
93
+ return `'${value}'`;
94
+ }
95
+ return value;
96
+ }
97
+ replacePlaceholders(query) {
98
+ let index = 1;
99
+ return query.replace(/\?/g, () => {
100
+ return `$${index++}`;
101
+ });
102
+ }
103
+ getColumnNameWithScaping(columnName) {
104
+ switch (this.type) {
105
+ case database_1.Database.POSTGRES:
106
+ return `"${columnName}"`;
107
+ case database_1.Database.MYSQL:
108
+ return `\`${columnName}\``;
109
+ }
110
+ }
111
+ getLimit(offset, limit) {
112
+ switch (this.type) {
113
+ case database_1.Database.POSTGRES:
114
+ return `LIMIT ${offset} OFFSET ${limit}`;
115
+ case database_1.Database.MYSQL:
116
+ return `LIMIT ${offset}, ${limit}`;
117
+ }
118
+ }
119
+ getTableNameFromQuery(query) {
120
+ const match = query.match(/INSERT INTO\s+([`"]?[\w-]+[`"]?)/i);
121
+ if (match && match[1]) {
122
+ return match[1].replace(/[`"]/g, '');
123
+ }
124
+ return null;
125
+ }
126
+ async hasTableColumnOrder(tableName) {
127
+ if (this.tableHasColumnOrder[tableName]) {
128
+ return this.tableHasColumnOrder[tableName];
129
+ }
130
+ return (this.tableHasColumnOrder[tableName] =
131
+ (await this.getColumnComment(tableName, 'order')) === 'order');
132
+ }
133
+ async getColumnComment(tableName, columnName) {
134
+ if (this.columnComment[`${tableName}.${columnName}`]) {
135
+ return this.columnComment[`${tableName}.${columnName}`];
136
+ }
137
+ switch (this.type) {
138
+ case database_1.Database.POSTGRES:
139
+ const resultPg = await this.query(`SELECT a.attname AS column_name,
140
+ col_description(a.attrelid, a.attnum) AS column_comment
141
+ FROM pg_class AS c
142
+ JOIN pg_attribute AS a ON a.attrelid = c.oid
143
+ WHERE c.relname = ?
144
+ AND a.attname = ?;`, [tableName, columnName]);
145
+ return resultPg.length > 0
146
+ ? (this.columnComment[`${tableName}.${columnName}`] =
147
+ resultPg[0].column_comment)
148
+ : '';
149
+ case database_1.Database.MYSQL:
150
+ const resultMysql = await this.query(`SELECT COLUMN_NAME, COLUMN_COMMENT
151
+ FROM information_schema.COLUMNS
152
+ WHERE TABLE_NAME = ?
153
+ AND COLUMN_NAME = ?;`, [tableName, columnName]);
154
+ return resultMysql.length > 0
155
+ ? (this.columnComment[`${tableName}.${columnName}`] =
156
+ resultMysql[0].COLUMN_COMMENT)
157
+ : '';
158
+ }
159
+ }
160
+ async getTableNameFromForeignKey(tableName, foreignKey) {
161
+ if (this.foreignKeys[`${tableName}.${foreignKey}`]) {
162
+ return this.foreignKeys[`${tableName}.${foreignKey}`];
163
+ }
164
+ switch (this.type) {
165
+ case database_1.Database.POSTGRES:
166
+ const resultPg = await this.query(`SELECT
167
+ ccu.table_name
168
+ FROM
169
+ information_schema.table_constraints AS tc
170
+ JOIN information_schema.key_column_usage AS kcu
171
+ ON tc.constraint_name = kcu.constraint_name
172
+ AND tc.table_schema = kcu.table_schema
173
+ JOIN information_schema.constraint_column_usage AS ccu
174
+ ON ccu.constraint_name = tc.constraint_name
175
+ AND ccu.table_schema = tc.table_schema
176
+ WHERE tc.constraint_type = 'FOREIGN KEY' AND tc.table_name = ? AND kcu.column_name = ?;`, [tableName, foreignKey]);
177
+ if (resultPg.length === 0) {
178
+ throw new Error(`Foreign key ${tableName}.${foreignKey} not found in database.`);
179
+ }
180
+ return (this.foreignKeys[`${tableName}.${foreignKey}`] =
181
+ resultPg[0].table_name);
182
+ case database_1.Database.MYSQL:
183
+ const resultMysql = await this.query(`SELECT kcu.REFERENCED_TABLE_NAME as table_name
184
+ FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu
185
+ JOIN information_schema.table_constraints AS tc
186
+ ON tc.constraint_name = kcu.constraint_name
187
+ AND tc.table_schema = kcu.table_schema
188
+ WHERE kcu.TABLE_NAME = ? AND kcu.COLUMN_NAME = ? AND tc.CONSTRAINT_TYPE = 'FOREIGN KEY'`, [tableName, foreignKey]);
189
+ if (resultMysql.length === 0) {
190
+ throw new Error(`Foreign key ${tableName}.${foreignKey} not found in database.`);
191
+ }
192
+ return (this.foreignKeys[`${tableName}.${foreignKey}`] =
193
+ resultMysql[0].table_name);
194
+ }
195
+ }
196
+ shouldHandleReturning(options) {
197
+ return (options === null || options === void 0 ? void 0 : options.returning) !== undefined;
198
+ }
199
+ isReturningSingleField(options) {
200
+ return ((options === null || options === void 0 ? void 0 : options.returning) instanceof Array && options.returning.length === 1);
201
+ }
202
+ isReturningIdWithoutPrimaryKeys(options) {
203
+ return (options === null || options === void 0 ? void 0 : options.returning) === 'id' && !options.primaryKeys;
204
+ }
205
+ isMissingPrimaryKeys(options) {
206
+ return !(options === null || options === void 0 ? void 0 : options.primaryKeys);
207
+ }
208
+ hasPrimaryKeys(options) {
209
+ return typeof (options === null || options === void 0 ? void 0 : options.primaryKeys) === 'string';
210
+ }
211
+ hasReturning(options) {
212
+ return typeof (options === null || options === void 0 ? void 0 : options.returning) === 'string';
213
+ }
214
+ formatOptions(options) {
215
+ if (options && this.shouldHandleReturning(options)) {
216
+ if (this.isReturningSingleField(options)) {
217
+ options.returning = options.returning[0];
218
+ }
219
+ if (this.isReturningIdWithoutPrimaryKeys(options)) {
220
+ options.primaryKeys = options.returning;
221
+ }
222
+ if (this.isMissingPrimaryKeys(options)) {
223
+ throw new Error('Primary key is required when using returning.');
224
+ }
225
+ if (this.hasPrimaryKeys(options)) {
226
+ options.primaryKeys = [options.primaryKeys];
227
+ }
228
+ if (this.hasReturning(options)) {
229
+ options.returning = [options.returning];
230
+ }
231
+ }
232
+ return options;
233
+ }
234
+ addReturningToQuery(query, options) {
235
+ if (this.type === database_1.Database.POSTGRES &&
236
+ this.shouldHandleReturning(options)) {
237
+ return `${query} RETURNING ${(options === null || options === void 0 ? void 0 : options.returning).join(', ')}`;
238
+ }
239
+ return query;
240
+ }
241
+ async getResult(query, result, options) {
242
+ var _a, _b;
243
+ switch (this.type) {
244
+ case database_1.Database.POSTGRES:
245
+ return result.rows;
246
+ case database_1.Database.MYSQL:
247
+ result = result[0];
248
+ if (this.shouldHandleReturning(options)) {
249
+ const resultArray = [
250
+ {
251
+ id: result.insertId,
252
+ },
253
+ ];
254
+ result = resultArray;
255
+ if ((Array.isArray(options === null || options === void 0 ? void 0 : options.returning) &&
256
+ options.returning.length > 1) ||
257
+ (((_a = options === null || options === void 0 ? void 0 : options.returning) === null || _a === void 0 ? void 0 : _a.length) === 1 &&
258
+ (options === null || options === void 0 ? void 0 : options.primaryKeys) &&
259
+ (options === null || options === void 0 ? void 0 : options.returning[0]) !== (options === null || options === void 0 ? void 0 : options.primaryKeys[0]))) {
260
+ const where = ((_b = options === null || options === void 0 ? void 0 : options.primaryKeys) !== null && _b !== void 0 ? _b : [])
261
+ .map((pk) => `${pk} = ?`)
262
+ .join(' AND ');
263
+ const selectReturningQuery = `SELECT ${(options === null || options === void 0 ? void 0 : options.returning).join(', ')} FROM ${this.getTableNameFromQuery(query)} WHERE ${where}`;
264
+ const returningResult = await this.client.query(selectReturningQuery, [resultArray[0].id]);
265
+ result = returningResult;
266
+ }
267
+ }
268
+ else if (result === null || result === void 0 ? void 0 : result.insertId) {
269
+ result = [
270
+ {
271
+ id: result.insertId,
272
+ },
273
+ ];
274
+ }
275
+ return result;
276
+ }
277
+ }
278
+ async getClient() {
279
+ switch (this.type) {
280
+ case database_1.Database.POSTGRES:
281
+ const { Client } = await Promise.resolve().then(() => __importStar(require('pg')));
282
+ this.client = new Client({
283
+ host: this.host,
284
+ user: this.user,
285
+ password: this.password,
286
+ database: this.database,
287
+ port: this.port,
288
+ });
289
+ await this.client.connect();
290
+ return this.client;
291
+ case database_1.Database.MYSQL:
292
+ const mysql = await Promise.resolve().then(() => __importStar(require('mysql2/promise')));
293
+ this.client = await mysql.createConnection({
294
+ host: this.host,
295
+ user: this.user,
296
+ password: this.password,
297
+ database: this.database,
298
+ port: this.port,
299
+ });
300
+ return this.client;
301
+ }
302
+ }
303
+ async testDatabaseConnection() {
304
+ try {
305
+ switch (this.type) {
306
+ case database_1.Database.POSTGRES:
307
+ case database_1.Database.MYSQL:
308
+ await this.query('SELECT NOW()');
309
+ break;
310
+ }
311
+ }
312
+ catch (error) {
313
+ return false;
314
+ }
315
+ return true;
316
+ }
317
+ async getPrimaryKeys(tableName) {
318
+ if (this.primaryKeys[tableName]) {
319
+ return this.primaryKeys[tableName];
320
+ }
321
+ let primaryKeys = [];
322
+ switch (this.type) {
323
+ case database_1.Database.POSTGRES:
324
+ const resultPg = await this.query(`SELECT column_name
325
+ FROM information_schema.table_constraints tc
326
+ JOIN information_schema.key_column_usage kcu
327
+ ON tc.constraint_name = kcu.constraint_name
328
+ WHERE constraint_type = 'PRIMARY KEY'
329
+ AND tc.table_name = ?`, [tableName]);
330
+ primaryKeys = resultPg.map((row) => row.column_name);
331
+ if (primaryKeys.length > 0) {
332
+ this.primaryKeys[tableName] = primaryKeys;
333
+ }
334
+ return primaryKeys;
335
+ case database_1.Database.MYSQL:
336
+ const resultMysql = await this.query(`SELECT COLUMN_NAME
337
+ FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
338
+ WHERE TABLE_NAME = ? AND CONSTRAINT_NAME = 'PRIMARY'`, [tableName]);
339
+ primaryKeys = resultMysql.map((row) => row.COLUMN_NAME);
340
+ if (primaryKeys.length > 0) {
341
+ this.primaryKeys[tableName] = primaryKeys;
342
+ }
343
+ return primaryKeys;
344
+ }
345
+ }
346
+ async getForeignKeys(tableName) {
347
+ if (this.foreignKeysByTable[tableName]) {
348
+ return this.foreignKeysByTable[tableName];
349
+ }
350
+ switch (this.type) {
351
+ case database_1.Database.POSTGRES:
352
+ const resultPg = await this.query(`SELECT kcu.column_name
353
+ FROM
354
+ information_schema.table_constraints AS tc
355
+ JOIN information_schema.key_column_usage AS kcu
356
+ ON tc.constraint_name = kcu.constraint_name
357
+ AND tc.table_schema = kcu.table_schema
358
+ JOIN information_schema.constraint_column_usage AS ccu
359
+ ON ccu.constraint_name = tc.constraint_name
360
+ AND ccu.table_schema = tc.table_schema
361
+ WHERE tc.constraint_type = 'FOREIGN KEY' AND tc.table_name = ?;`, [tableName]);
362
+ return (this.foreignKeysByTable[tableName] = resultPg.map((row) => row.column_name));
363
+ case database_1.Database.MYSQL:
364
+ const resultMysql = await this.query(`SELECT COLUMN_NAME
365
+ FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
366
+ WHERE TABLE_NAME = ? AND CONSTRAINT_NAME != 'PRIMARY'`, [tableName]);
367
+ return (this.foreignKeysByTable[tableName] = resultMysql.map((row) => row.COLUMN_NAME));
368
+ }
369
+ }
370
+ async getColumnNameFromRelation(tableNameOrigin, tableNameDestination) {
371
+ if (this.columnNameFromRelation[`${tableNameOrigin}.${tableNameDestination}`]) {
372
+ return this.columnNameFromRelation[`${tableNameOrigin}.${tableNameDestination}`];
373
+ }
374
+ switch (this.type) {
375
+ case database_1.Database.POSTGRES:
376
+ const resultPg = await this.query(`SELECT
377
+ tc.table_name, kcu.column_name, ccu.table_name AS foreign_table_name, ccu.column_name AS foreign_column_name
378
+ FROM
379
+ information_schema.table_constraints AS tc
380
+ JOIN information_schema.key_column_usage AS kcu
381
+ ON tc.constraint_name = kcu.constraint_name
382
+ AND tc.table_schema = kcu.table_schema
383
+ JOIN information_schema.constraint_column_usage AS ccu
384
+ ON ccu.constraint_name = tc.constraint_name
385
+ AND ccu.table_schema = tc.table_schema
386
+ WHERE tc.constraint_type = 'FOREIGN KEY' AND ccu.table_name = ? AND tc.table_name = ?;`, [tableNameOrigin, tableNameDestination]);
387
+ if (!resultPg.length) {
388
+ throw new Error(`Foreign key ${tableNameOrigin}.${tableNameDestination} not found in database. [getColumnNameFromRelation]`);
389
+ }
390
+ return (this.columnNameFromRelation[`${tableNameOrigin}.${tableNameDestination}`] = resultPg[0].column_name);
391
+ case database_1.Database.MYSQL:
392
+ const resultMysql = await this.query(`SELECT
393
+ TABLE_NAME, COLUMN_NAME, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME
394
+ FROM
395
+ INFORMATION_SCHEMA.KEY_COLUMN_USAGE
396
+ WHERE TABLE_SCHEMA = DATABASE() AND REFERENCED_TABLE_NAME = ? AND TABLE_NAME = ?;`, [tableNameOrigin, tableNameDestination]);
397
+ if (!resultMysql.length) {
398
+ throw new Error(`Foreign key ${tableNameOrigin}.${tableNameDestination} not found in database. [getColumnNameFromRelation]`);
399
+ }
400
+ return (this.columnNameFromRelation[`${tableNameOrigin}.${tableNameDestination}`] = resultMysql[0].COLUMN_NAME);
401
+ default:
402
+ throw new Error(`Unsupported database type: ${this.type}`);
403
+ }
404
+ }
405
+ async getRelation1N(tableNameOrigin, tableNameDestination) {
406
+ if (this.relation1N[`${tableNameOrigin}.${tableNameDestination}`]) {
407
+ return this.relation1N[`${tableNameOrigin}.${tableNameDestination}`];
408
+ }
409
+ switch (this.type) {
410
+ case database_1.Database.POSTGRES:
411
+ const resultPg = await this.query(`SELECT
412
+ tc.table_name, kcu.column_name, ccu.table_name AS foreign_table_name, ccu.column_name AS foreign_column_name
413
+ FROM
414
+ information_schema.table_constraints AS tc
415
+ JOIN information_schema.key_column_usage AS kcu
416
+ ON tc.constraint_name = kcu.constraint_name
417
+ AND tc.table_schema = kcu.table_schema
418
+ JOIN information_schema.constraint_column_usage AS ccu
419
+ ON ccu.constraint_name = tc.constraint_name
420
+ AND ccu.table_schema = tc.table_schema
421
+ WHERE tc.constraint_type = 'FOREIGN KEY' AND ccu.table_name = ? AND tc.table_name = ?;`, [tableNameOrigin, tableNameDestination]);
422
+ if (!resultPg.length) {
423
+ throw new Error(`Foreign key ${tableNameOrigin}.${tableNameDestination} not found in database. [getRelation1N]`);
424
+ }
425
+ return (this.relation1N[`${tableNameOrigin}.${tableNameDestination}`] =
426
+ resultPg[0].column_name);
427
+ case database_1.Database.MYSQL:
428
+ const resultMysql = await this.query(`SELECT
429
+ TABLE_NAME, COLUMN_NAME, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME
430
+ FROM
431
+ INFORMATION_SCHEMA.KEY_COLUMN_USAGE
432
+ WHERE TABLE_SCHEMA = DATABASE() AND REFERENCED_TABLE_NAME = ? AND TABLE_NAME = ?;`, [tableNameOrigin, tableNameDestination]);
433
+ if (!resultMysql.length) {
434
+ throw new Error(`Foreign key ${tableNameOrigin}.${tableNameDestination} not found in database. [getRelation1N]`);
435
+ }
436
+ return (this.relation1N[`${tableNameOrigin}.${tableNameDestination}`] =
437
+ resultMysql[0].COLUMN_NAME);
438
+ }
439
+ }
440
+ async getRelationN2N(tableNameOrigin, tableNameDestination) {
441
+ if (this.relationN2N[`${tableNameOrigin}.${tableNameDestination}`]) {
442
+ return this.relationN2N[`${tableNameOrigin}.${tableNameDestination}`];
443
+ }
444
+ let tableNameIntermediate = '';
445
+ let columnNameOrigin = '';
446
+ let columnNameDestination = '';
447
+ let primaryKeyDestination = '';
448
+ switch (this.type) {
449
+ case database_1.Database.POSTGRES:
450
+ const resultPg1 = await this.query(`SELECT
451
+ tc.table_name, kcu.column_name
452
+ FROM
453
+ information_schema.table_constraints AS tc
454
+ JOIN information_schema.key_column_usage AS kcu
455
+ ON tc.constraint_name = kcu.constraint_name
456
+ AND tc.table_schema = kcu.table_schema
457
+ JOIN information_schema.constraint_column_usage AS ccu
458
+ ON ccu.constraint_name = tc.constraint_name
459
+ AND ccu.table_schema = tc.table_schema
460
+ WHERE tc.constraint_type = 'FOREIGN KEY' AND ccu.table_name = ?;`, [tableNameOrigin]);
461
+ for (const row of resultPg1) {
462
+ const resultPg2 = await this.query(`SELECT
463
+ tc.table_name, kcu.column_name, ccu.table_name AS foreign_table_name, ccu.column_name AS foreign_column_name
464
+ FROM
465
+ information_schema.table_constraints AS tc
466
+ JOIN information_schema.key_column_usage AS kcu
467
+ ON tc.constraint_name = kcu.constraint_name
468
+ AND tc.table_schema = kcu.table_schema
469
+ JOIN information_schema.constraint_column_usage AS ccu
470
+ ON ccu.constraint_name = tc.constraint_name
471
+ AND ccu.table_schema = tc.table_schema
472
+ WHERE tc.constraint_type = 'FOREIGN KEY' AND tc.table_name = ?;`, [row['table_name']]);
473
+ for (const row2 of resultPg2) {
474
+ if (row2['foreign_table_name'] === tableNameDestination) {
475
+ tableNameIntermediate = row['table_name'];
476
+ columnNameOrigin = row['column_name'];
477
+ columnNameDestination = row2['column_name'];
478
+ primaryKeyDestination = row2['foreign_column_name'];
479
+ break;
480
+ }
481
+ }
482
+ }
483
+ return (this.relationN2N[`${tableNameOrigin}.${tableNameDestination}`] =
484
+ {
485
+ tableNameIntermediate,
486
+ columnNameOrigin,
487
+ columnNameDestination,
488
+ primaryKeyDestination,
489
+ });
490
+ case database_1.Database.MYSQL:
491
+ const resultMysql1 = await this.query(`SELECT
492
+ kcu.TABLE_NAME,
493
+ kcu.COLUMN_NAME,
494
+ kcu.REFERENCED_TABLE_NAME AS foreign_table_name,
495
+ kcu.REFERENCED_COLUMN_NAME AS foreign_column_name
496
+ FROM
497
+ information_schema.KEY_COLUMN_USAGE AS kcu
498
+ WHERE
499
+ kcu.REFERENCED_TABLE_NAME = ?
500
+ AND kcu.TABLE_SCHEMA = DATABASE();`, [tableNameOrigin]);
501
+ for (const row of resultMysql1) {
502
+ const resultMysql2 = await this.query(`SELECT
503
+ kcu.TABLE_NAME,
504
+ kcu.COLUMN_NAME,
505
+ kcu.REFERENCED_TABLE_NAME AS foreign_table_name,
506
+ kcu.REFERENCED_COLUMN_NAME AS foreign_column_name
507
+ FROM
508
+ information_schema.KEY_COLUMN_USAGE AS kcu
509
+ WHERE
510
+ kcu.TABLE_NAME = ?
511
+ AND kcu.REFERENCED_TABLE_NAME IS NOT NULL
512
+ AND kcu.TABLE_SCHEMA = DATABASE();`, [row['TABLE_NAME']]);
513
+ for (const row2 of resultMysql2) {
514
+ if (row2['foreign_table_name'] === tableNameDestination) {
515
+ tableNameIntermediate = row['TABLE_NAME'];
516
+ columnNameOrigin = row['COLUMN_NAME'];
517
+ columnNameDestination = row2['COLUMN_NAME'];
518
+ primaryKeyDestination = row2['foreign_column_name'];
519
+ break;
520
+ }
521
+ }
522
+ }
523
+ return (this.relationN2N[`${tableNameOrigin}.${tableNameDestination}`] =
524
+ {
525
+ tableNameIntermediate,
526
+ columnNameOrigin,
527
+ columnNameDestination,
528
+ primaryKeyDestination,
529
+ });
530
+ default:
531
+ throw new Error(`Unsupported database type: ${this.type}`);
532
+ }
533
+ }
534
+ static parseQueryValue(value) {
535
+ switch (typeof value) {
536
+ case 'number':
537
+ case 'boolean':
538
+ return value;
539
+ default:
540
+ return `'${value}'`;
541
+ }
542
+ }
543
+ static objectToWhereClause(obj) {
544
+ let whereClause = '';
545
+ for (const key in obj) {
546
+ if (typeof obj[key] === 'object') {
547
+ whereClause += `${key} ${obj[key].operator} ${AbstractDatabase.parseQueryValue(obj[key].value)}`;
548
+ }
549
+ else {
550
+ whereClause += `${key} = ${AbstractDatabase.parseQueryValue(obj[key])}`;
551
+ }
552
+ }
553
+ return whereClause;
554
+ }
555
+ async transaction(queries) {
556
+ var _a;
557
+ this.eventEmitter.emit('transaction', { queries });
558
+ if (!this.client) {
559
+ await this.getClient();
560
+ }
561
+ const results = [];
562
+ for (let i = 0; i < queries.length; i++) {
563
+ queries[i].options = this.formatOptions(queries[i].options);
564
+ queries[i].query = this.addReturningToQuery(queries[i].query, queries[i].options);
565
+ }
566
+ try {
567
+ switch (this.type) {
568
+ case database_1.Database.POSTGRES:
569
+ await this.client.query('BEGIN');
570
+ for (const { query, values, options } of queries) {
571
+ const resultPg = await this.client.query(this.replacePlaceholders(query), values);
572
+ results.push(this.getResult(query, resultPg, options));
573
+ }
574
+ await this.client.query('COMMIT');
575
+ break;
576
+ case database_1.Database.MYSQL:
577
+ await this.client.beginTransaction();
578
+ for (const { query, values, options } of queries) {
579
+ const resultMySQL = await this.client.query(query, values);
580
+ results.push(this.getResult(query, resultMySQL, options));
581
+ }
582
+ await this.client.commit();
583
+ break;
584
+ }
585
+ }
586
+ catch (error) {
587
+ switch (this.type) {
588
+ case database_1.Database.POSTGRES:
589
+ await this.client.query('ROLLBACK');
590
+ break;
591
+ case database_1.Database.MYSQL:
592
+ await this.client.rollback();
593
+ break;
594
+ }
595
+ throw error;
596
+ }
597
+ finally {
598
+ if (this.autoClose) {
599
+ await ((_a = this.client) === null || _a === void 0 ? void 0 : _a.end());
600
+ this.client = null;
601
+ }
602
+ }
603
+ return results;
604
+ }
605
+ async query(query, values, options) {
606
+ var _a;
607
+ this.eventEmitter.emit('query', { query, values, options });
608
+ if (!this.client) {
609
+ await this.getClient();
610
+ }
611
+ let result;
612
+ options = this.formatOptions(options);
613
+ query = this.addReturningToQuery(query, options);
614
+ try {
615
+ switch (this.type) {
616
+ case database_1.Database.POSTGRES:
617
+ result = await this.client.query(this.replacePlaceholders(query), values);
618
+ break;
619
+ case database_1.Database.MYSQL:
620
+ result = await this.client.query(query, values);
621
+ break;
622
+ }
623
+ }
624
+ catch (error) {
625
+ console.error({
626
+ error,
627
+ query,
628
+ values,
629
+ options,
630
+ });
631
+ this.eventEmitter.emit('error', { error, query, values, options });
632
+ }
633
+ result = await this.getResult(query, result, options);
634
+ this.eventEmitter.emit('query', { result });
635
+ if (this.autoClose) {
636
+ await ((_a = this.client) === null || _a === void 0 ? void 0 : _a.end());
637
+ this.client = null;
638
+ }
639
+ return result;
640
+ }
641
+ }
642
+ exports.AbstractDatabase = AbstractDatabase;
643
+ //# sourceMappingURL=abstract.database.js.map