@hed-hog/api-pagination 0.0.1

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