@crane-technologies/database 2.1.0
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/README.md +475 -0
- package/dist/components/Database.d.ts +288 -0
- package/dist/components/Database.d.ts.map +1 -0
- package/dist/components/Database.js +554 -0
- package/dist/components/Database.js.map +1 -0
- package/dist/components/Logger.d.ts +63 -0
- package/dist/components/Logger.d.ts.map +1 -0
- package/dist/components/Logger.js +147 -0
- package/dist/components/Logger.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +39 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces/BulkInsertOptions.d.ts +20 -0
- package/dist/interfaces/BulkInsertOptions.d.ts.map +1 -0
- package/dist/interfaces/BulkInsertOptions.js +3 -0
- package/dist/interfaces/BulkInsertOptions.js.map +1 -0
- package/dist/interfaces/DatabaseConfig.d.ts +52 -0
- package/dist/interfaces/DatabaseConfig.d.ts.map +1 -0
- package/dist/interfaces/DatabaseConfig.js +3 -0
- package/dist/interfaces/DatabaseConfig.js.map +1 -0
- package/dist/interfaces/Dependancy.d.ts +15 -0
- package/dist/interfaces/Dependancy.d.ts.map +1 -0
- package/dist/interfaces/Dependancy.js +3 -0
- package/dist/interfaces/Dependancy.js.map +1 -0
- package/dist/interfaces/QueryList.d.ts +4 -0
- package/dist/interfaces/QueryList.d.ts.map +1 -0
- package/dist/interfaces/QueryList.js +3 -0
- package/dist/interfaces/QueryList.js.map +1 -0
- package/dist/utils/createQueries.d.ts +65 -0
- package/dist/utils/createQueries.d.ts.map +1 -0
- package/dist/utils/createQueries.js +121 -0
- package/dist/utils/createQueries.js.map +1 -0
- package/package.json +61 -0
|
@@ -0,0 +1,554 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const pg_1 = require("pg");
|
|
4
|
+
const pg_copy_streams_1 = require("pg-copy-streams");
|
|
5
|
+
const stream_1 = require("stream");
|
|
6
|
+
const Logger_1 = require("./Logger");
|
|
7
|
+
/**
|
|
8
|
+
* Database class implements the Singleton pattern to manage PostgreSQL connections.
|
|
9
|
+
* Provides methods for executing SQL queries, transactions and dependency handling.
|
|
10
|
+
* Supports QueryReference objects for autocomplete.
|
|
11
|
+
*
|
|
12
|
+
* @class Database
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* import Database, { createQueries } from '@crane-technologies/database';
|
|
16
|
+
*
|
|
17
|
+
* const queries = createQueries({
|
|
18
|
+
* users: {
|
|
19
|
+
* getById: "SELECT * FROM users WHERE id = $1"
|
|
20
|
+
* }
|
|
21
|
+
* });
|
|
22
|
+
*
|
|
23
|
+
* const db = Database.getInstance(config, queries);
|
|
24
|
+
*
|
|
25
|
+
* // ✅ Con autocompletado
|
|
26
|
+
* await db.query(queries.users.getById, [123]);
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
class Database {
|
|
30
|
+
/**
|
|
31
|
+
* Private constructor that implements the Singleton pattern.
|
|
32
|
+
* Use getInstance() to get the Database instance.
|
|
33
|
+
*
|
|
34
|
+
* @param {DatabaseConfig} config - Database configuration
|
|
35
|
+
* @param {Record<string, string>} flatMap - Flat map of queries
|
|
36
|
+
* @private
|
|
37
|
+
*/
|
|
38
|
+
constructor(config, flatMap) {
|
|
39
|
+
this.config = config;
|
|
40
|
+
this.queries = flatMap;
|
|
41
|
+
this.logger = new Logger_1.Logger(config.logLevel ?? 1, "[DATABASE]");
|
|
42
|
+
this.initializePool();
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Initializes the PostgreSQL connection pool using provided configuration.
|
|
46
|
+
* Executed only once when creating the first singleton instance.
|
|
47
|
+
*
|
|
48
|
+
* @private
|
|
49
|
+
* @returns {void}
|
|
50
|
+
* @throws {Error} If pool initialization fails
|
|
51
|
+
*/
|
|
52
|
+
initializePool() {
|
|
53
|
+
try {
|
|
54
|
+
this.pool = new pg_1.Pool(this.config);
|
|
55
|
+
this.pool.on("connect", () => {
|
|
56
|
+
this.logger.info("Nueva conexión establecida a la base de datos");
|
|
57
|
+
});
|
|
58
|
+
this.pool.on("error", (error) => {
|
|
59
|
+
this.logger.error("Error en el pool de conexiones", error);
|
|
60
|
+
});
|
|
61
|
+
this.pool.on("remove", () => {
|
|
62
|
+
this.logger.debug("Conexión removida del pool");
|
|
63
|
+
});
|
|
64
|
+
this.logger.info("Pool de conexiones inicializado correctamente");
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
this.logger.error("Error inicializando el pool", error);
|
|
68
|
+
throw new Error(`Failed to initialize connection pool: ${error}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Static method to get the unique Database instance (Singleton pattern).
|
|
73
|
+
* Accepts the result of createQueries() or a plain object with queries.
|
|
74
|
+
*
|
|
75
|
+
* @param {DatabaseConfig} config - Database configuration (required on first call)
|
|
76
|
+
* @param {any} queries - Result from createQueries() or plain query object
|
|
77
|
+
* @returns {Database} The unique Database instance
|
|
78
|
+
* @throws {Error} If config is not provided on first initialization
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```typescript
|
|
82
|
+
* // With createQueries (recommended)
|
|
83
|
+
* const queries = createQueries({
|
|
84
|
+
* users: { getById: "SELECT * FROM users WHERE id = $1" }
|
|
85
|
+
* });
|
|
86
|
+
* const db = Database.getInstance(config, queries);
|
|
87
|
+
* await db.query(queries.users.getById, [123]);
|
|
88
|
+
*
|
|
89
|
+
* // With plain object (backward compatible)
|
|
90
|
+
* const db = Database.getInstance(config, {
|
|
91
|
+
* getUser: "SELECT * FROM users WHERE id = $1"
|
|
92
|
+
* });
|
|
93
|
+
* await db.query("getUser", [123]);
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
static getInstance(config, queries) {
|
|
97
|
+
if (!Database.instance) {
|
|
98
|
+
if (!queries) {
|
|
99
|
+
throw new Error("Queries must be provided on first initialization");
|
|
100
|
+
}
|
|
101
|
+
// Detect if comes from createQueries() (has __flatMap)
|
|
102
|
+
const flatMap = queries.__flatMap || queries;
|
|
103
|
+
Database.instance = new Database(config, flatMap);
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
// Merge new queries if provided
|
|
107
|
+
if (queries) {
|
|
108
|
+
const flatMap = queries.__flatMap || queries;
|
|
109
|
+
if (Object.keys(flatMap).length > 0) {
|
|
110
|
+
Database.instance.queries = {
|
|
111
|
+
...Database.instance.queries,
|
|
112
|
+
...flatMap,
|
|
113
|
+
};
|
|
114
|
+
Database.instance.logger.debug("New queries added", {
|
|
115
|
+
count: Object.keys(flatMap).length,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return Database.instance;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Validates that the pool is active and ready to accept connections.
|
|
124
|
+
*
|
|
125
|
+
* @private
|
|
126
|
+
* @throws {Error} If pool is closed or not initialized
|
|
127
|
+
*/
|
|
128
|
+
ensurePoolActive() {
|
|
129
|
+
if (!this.pool || this.pool.ended) {
|
|
130
|
+
const error = new Error("Database pool is closed. Cannot execute queries.");
|
|
131
|
+
this.logger.error(error.message);
|
|
132
|
+
throw error;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Extracts the SQL from a QueryReference or string key.
|
|
137
|
+
*
|
|
138
|
+
* @private
|
|
139
|
+
* @param query - QueryReference, string key, or raw SQL
|
|
140
|
+
* @returns The SQL query string
|
|
141
|
+
* @throws {Error} If query is not found
|
|
142
|
+
*/
|
|
143
|
+
getQuery(query) {
|
|
144
|
+
// Case 1: It's a QueryReference
|
|
145
|
+
if (typeof query === "object" && query !== null && "__queryKey" in query) {
|
|
146
|
+
const queryKey = query.__queryKey;
|
|
147
|
+
const sql = this.queries[queryKey];
|
|
148
|
+
if (!sql) {
|
|
149
|
+
const error = new Error(`Query "${queryKey}" not found in queries dictionary. ` +
|
|
150
|
+
`Available queries: ${Object.keys(this.queries).join(", ")}`);
|
|
151
|
+
this.logger.error(error.message);
|
|
152
|
+
throw error;
|
|
153
|
+
}
|
|
154
|
+
return sql;
|
|
155
|
+
}
|
|
156
|
+
// CASE 2: It's a string
|
|
157
|
+
if (typeof query === "string") {
|
|
158
|
+
// Search in the dictionary
|
|
159
|
+
const sql = this.queries[query];
|
|
160
|
+
if (sql) {
|
|
161
|
+
return sql;
|
|
162
|
+
}
|
|
163
|
+
// If not found, treat as raw SQL
|
|
164
|
+
return query;
|
|
165
|
+
}
|
|
166
|
+
throw new Error("Invalid query type. Expected QueryReference or string.");
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Gets the SQL query string.
|
|
170
|
+
*
|
|
171
|
+
* @private
|
|
172
|
+
* @param query - QueryReference or string
|
|
173
|
+
* @returns The SQL query string
|
|
174
|
+
*/
|
|
175
|
+
getQueryName(query) {
|
|
176
|
+
if (typeof query === "object" && query !== null && "__queryKey" in query) {
|
|
177
|
+
return query.__queryKey;
|
|
178
|
+
}
|
|
179
|
+
if (typeof query === "string") {
|
|
180
|
+
return this.queries[query] ? query : "raw_sql";
|
|
181
|
+
}
|
|
182
|
+
return "unknown";
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Executes a predefined SQL query using QueryReference or string key.
|
|
186
|
+
* Gets a connection from the pool, executes the query and releases the connection.
|
|
187
|
+
*
|
|
188
|
+
* @param {string | QueryReference} query - QueryReference object or query key
|
|
189
|
+
* @param {any[]} params - Optional parameters for the SQL query
|
|
190
|
+
* @returns {Promise<QueryResult>} SQL query result
|
|
191
|
+
* @throws {Error} If the query doesn't exist or execution fails
|
|
192
|
+
*
|
|
193
|
+
* @example
|
|
194
|
+
* ```typescript
|
|
195
|
+
* // With QueryReference (autocomplete!)
|
|
196
|
+
* const result = await db.queryList(queries.users.getById, [123]);
|
|
197
|
+
*
|
|
198
|
+
* // With string key (backward compatible)
|
|
199
|
+
* const result = await db.queryList("users.getById", [123]);
|
|
200
|
+
* ```
|
|
201
|
+
*/
|
|
202
|
+
async queryList(query, params) {
|
|
203
|
+
this.ensurePoolActive();
|
|
204
|
+
const sqlText = this.getQuery(query);
|
|
205
|
+
const queryName = this.getQueryName(query);
|
|
206
|
+
const client = await this.pool.connect();
|
|
207
|
+
try {
|
|
208
|
+
this.logger.debug(`Executing query: ${queryName}`, { params });
|
|
209
|
+
const res = await client.query({
|
|
210
|
+
text: sqlText,
|
|
211
|
+
values: params,
|
|
212
|
+
});
|
|
213
|
+
this.logger.debug(`Query executed successfully: ${queryName}`, {
|
|
214
|
+
rowCount: res.rowCount,
|
|
215
|
+
});
|
|
216
|
+
return res;
|
|
217
|
+
}
|
|
218
|
+
catch (error) {
|
|
219
|
+
this.logger.error(`Error executing query: ${queryName}`, error);
|
|
220
|
+
throw error;
|
|
221
|
+
}
|
|
222
|
+
finally {
|
|
223
|
+
client.release();
|
|
224
|
+
this.logger.debug("Client released back to pool");
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Executes a direct SQL query (raw SQL text).
|
|
229
|
+
* Useful for dynamic queries that are not predefined in the dictionary.
|
|
230
|
+
* Gets a connection from the pool, executes the query and releases the connection.
|
|
231
|
+
*
|
|
232
|
+
* @param {string} sqlText - The complete SQL text of the query to execute
|
|
233
|
+
* @param {any[]} params - Optional parameters for the SQL query
|
|
234
|
+
* @returns {Promise<QueryResult>} SQL query result
|
|
235
|
+
* @throws {Error} If query execution fails
|
|
236
|
+
*
|
|
237
|
+
* @example
|
|
238
|
+
* ```typescript
|
|
239
|
+
* const result = await db.rawQuery("SELECT COUNT(*) FROM users WHERE active = $1", [true]);
|
|
240
|
+
* const count = result.rows[0].count;
|
|
241
|
+
* ```
|
|
242
|
+
*/
|
|
243
|
+
async rawQuery(sqlText, params) {
|
|
244
|
+
this.ensurePoolActive();
|
|
245
|
+
const client = await this.pool.connect();
|
|
246
|
+
try {
|
|
247
|
+
this.logger.debug("Executing raw query", { sqlText });
|
|
248
|
+
const res = await client.query({
|
|
249
|
+
text: sqlText,
|
|
250
|
+
values: params,
|
|
251
|
+
});
|
|
252
|
+
this.logger.debug("Raw query executed successfully", {
|
|
253
|
+
rowCount: res.rowCount,
|
|
254
|
+
});
|
|
255
|
+
return res;
|
|
256
|
+
}
|
|
257
|
+
catch (error) {
|
|
258
|
+
this.logger.error("Error executing raw query", error);
|
|
259
|
+
throw error;
|
|
260
|
+
}
|
|
261
|
+
finally {
|
|
262
|
+
client.release();
|
|
263
|
+
this.logger.debug("Client released back to pool");
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Performs a high-performance bulk insert using PostgreSQL's native COPY ... FROM STDIN.
|
|
268
|
+
* Accepts an array of rows and streams them as CSV to the database.
|
|
269
|
+
* This is significantly faster than multiple INSERT statements.
|
|
270
|
+
*
|
|
271
|
+
* @param {string} table - The target table name.
|
|
272
|
+
* @param {string[]} columns - Array of column names to insert into (order matters).
|
|
273
|
+
* @param {(string | number | boolean | Date | null | undefined)[][]} rows - Array of row arrays, each representing a record.
|
|
274
|
+
* @param {BulkInsertOptions} [options] - Optional CSV formatting options (delimiter, header).
|
|
275
|
+
* @returns {Promise<{ inserted: number }>} Number of rows successfully inserted.
|
|
276
|
+
* @throws {Error} If the operation fails or the pool is not active.
|
|
277
|
+
*
|
|
278
|
+
* @example
|
|
279
|
+
* ```typescript
|
|
280
|
+
* await db.bulkInsert(
|
|
281
|
+
* "users",
|
|
282
|
+
* ["name", "email"],
|
|
283
|
+
* [
|
|
284
|
+
* ["Alice", "alice@email.com"],
|
|
285
|
+
* ["Bob", "bob@email.com"]
|
|
286
|
+
* ],
|
|
287
|
+
* { header: false }
|
|
288
|
+
* );
|
|
289
|
+
* ```
|
|
290
|
+
*/
|
|
291
|
+
async bulkInsert(table, columns, rows, options) {
|
|
292
|
+
this.ensurePoolActive();
|
|
293
|
+
const delimiter = options?.delimiter ?? ",";
|
|
294
|
+
const includeHeader = options?.header ?? false;
|
|
295
|
+
// Use quoteIdentifier for table and columns
|
|
296
|
+
const quotedTable = this.quoteIdentifier(table);
|
|
297
|
+
const quotedColumns = columns
|
|
298
|
+
.map((col) => this.quoteIdentifier(col))
|
|
299
|
+
.join(", ");
|
|
300
|
+
const copySql = `COPY ${quotedTable} (${quotedColumns}) FROM STDIN WITH (FORMAT csv, DELIMITER '${delimiter}', HEADER ${includeHeader ? "true" : "false"})`;
|
|
301
|
+
const client = await this.pool.connect();
|
|
302
|
+
try {
|
|
303
|
+
const copyStream = client.query((0, pg_copy_streams_1.from)(copySql));
|
|
304
|
+
const csvStream = stream_1.Readable.from(this.generateCsvLines(columns, rows, delimiter, includeHeader));
|
|
305
|
+
await new Promise((resolve, reject) => {
|
|
306
|
+
csvStream.on("error", reject);
|
|
307
|
+
copyStream.on("error", reject);
|
|
308
|
+
copyStream.on("finish", resolve);
|
|
309
|
+
csvStream.pipe(copyStream);
|
|
310
|
+
});
|
|
311
|
+
this.logger.info("Bulk insert ejecutado", {
|
|
312
|
+
table,
|
|
313
|
+
rows: rows.length,
|
|
314
|
+
});
|
|
315
|
+
return { inserted: rows.length };
|
|
316
|
+
}
|
|
317
|
+
catch (error) {
|
|
318
|
+
this.logger.error("Error en bulk insert", error);
|
|
319
|
+
throw error;
|
|
320
|
+
}
|
|
321
|
+
finally {
|
|
322
|
+
client.release();
|
|
323
|
+
this.logger.debug("Client release tras bulk insert");
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Generator that yields CSV lines for bulk insert operations.
|
|
328
|
+
* Optionally includes a header row with column names.
|
|
329
|
+
* Each yielded value is a CSV-formatted string representing a row.
|
|
330
|
+
*
|
|
331
|
+
* @private
|
|
332
|
+
* @param {string[]} columns - Array of column names.
|
|
333
|
+
* @param {(string | number | boolean | Date | null | undefined)[][]} rows - Array of row arrays.
|
|
334
|
+
* @param {string} delimiter - CSV delimiter character.
|
|
335
|
+
* @param {boolean} includeHeader - Whether to include a header row.
|
|
336
|
+
* @yields {string} CSV-formatted line.
|
|
337
|
+
*/
|
|
338
|
+
*generateCsvLines(columns, rows, delimiter, includeHeader) {
|
|
339
|
+
if (includeHeader) {
|
|
340
|
+
yield columns.join(delimiter) + "\n";
|
|
341
|
+
}
|
|
342
|
+
for (const row of rows) {
|
|
343
|
+
const values = row
|
|
344
|
+
.map((value) => this.escapeCsvValue(value, delimiter))
|
|
345
|
+
.join(delimiter);
|
|
346
|
+
yield values + "\n";
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Escapes a single value for safe inclusion in a CSV line.
|
|
351
|
+
* Handles delimiters, quotes, and line breaks according to CSV rules.
|
|
352
|
+
*
|
|
353
|
+
* @private
|
|
354
|
+
* @param {string | number | boolean | Date | null | undefined} value - The value to escape.
|
|
355
|
+
* @param {string} delimiter - The CSV delimiter character.
|
|
356
|
+
* @returns {string} The escaped CSV value.
|
|
357
|
+
*/
|
|
358
|
+
escapeCsvValue(value, delimiter) {
|
|
359
|
+
if (value === null || value === undefined) {
|
|
360
|
+
return "";
|
|
361
|
+
}
|
|
362
|
+
const text = String(value).replace(/"/g, '""');
|
|
363
|
+
const needsQuotes = text.includes(delimiter) ||
|
|
364
|
+
text.includes("\n") ||
|
|
365
|
+
text.includes("\r") ||
|
|
366
|
+
text.includes('"');
|
|
367
|
+
return needsQuotes ? `"${text}"` : text;
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Safely quotes a SQL identifier (such as a table or column name) for use in queries.
|
|
371
|
+
* Escapes any double quotes within the identifier to prevent SQL injection or syntax errors.
|
|
372
|
+
*
|
|
373
|
+
* @private
|
|
374
|
+
* @param {string} identifier - The SQL identifier to quote (e.g., table or column name).
|
|
375
|
+
* @returns {string} The quoted and escaped identifier, safe for use in SQL statements.
|
|
376
|
+
*
|
|
377
|
+
* @example
|
|
378
|
+
* const quoted = db.quoteIdentifier('user"name');
|
|
379
|
+
* // quoted === '"user""name"'
|
|
380
|
+
*/
|
|
381
|
+
quoteIdentifier(identifier) {
|
|
382
|
+
return `"${identifier.replace(/"/g, '""')}"`;
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Smart method that executes queries automatically detecting the type.
|
|
386
|
+
* Supports QueryReference objects (from createQueries), string keys, or raw SQL.
|
|
387
|
+
*
|
|
388
|
+
* @param {string | QueryReference} query - QueryReference, query key, or raw SQL
|
|
389
|
+
* @param {any[]} params - Optional parameters for the SQL query
|
|
390
|
+
* @returns {Promise<QueryResult>} SQL query result
|
|
391
|
+
* @throws {Error} If query execution fails
|
|
392
|
+
*
|
|
393
|
+
* @example
|
|
394
|
+
* ```typescript
|
|
395
|
+
* // Using QueryReference (autocomplete!)
|
|
396
|
+
* const user = await db.query(queries.users.getById, [123]);
|
|
397
|
+
*
|
|
398
|
+
* // Using string key (backward compatible)
|
|
399
|
+
* const user = await db.query("users.getById", [123]);
|
|
400
|
+
*
|
|
401
|
+
* // Using raw SQL
|
|
402
|
+
* const products = await db.query("SELECT * FROM products WHERE price > $1", [100]);
|
|
403
|
+
* ```
|
|
404
|
+
*/
|
|
405
|
+
async query(query, params) {
|
|
406
|
+
this.ensurePoolActive();
|
|
407
|
+
try {
|
|
408
|
+
// If it's a QueryReference or a known key
|
|
409
|
+
if ((typeof query === "object" && "__queryKey" in query) ||
|
|
410
|
+
(typeof query === "string" && this.queries[query])) {
|
|
411
|
+
return await this.queryList(query, params);
|
|
412
|
+
}
|
|
413
|
+
else {
|
|
414
|
+
// Otherwise, treat as raw SQL
|
|
415
|
+
return await this.rawQuery(query, params);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
catch (error) {
|
|
419
|
+
this.logger.error("Error executing query", error);
|
|
420
|
+
throw error;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* Executes multiple SQL queries within an atomic transaction.
|
|
425
|
+
* All queries execute or fail together (ACID compliance).
|
|
426
|
+
* Supports dependencies between queries, where the result of one query
|
|
427
|
+
* can be used as a parameter in subsequent queries.
|
|
428
|
+
* Supports QueryReference objects with autocomplete.
|
|
429
|
+
*
|
|
430
|
+
* @param {(string | QueryReference)[]} queryArray - Array of QueryReferences or query keys
|
|
431
|
+
* @param {any[][]} paramsArray - Array of arrays with parameters for each query
|
|
432
|
+
* @param {Dependency[]} dependencies - Optional array of dependencies between queries
|
|
433
|
+
* @returns {Promise<QueryResult[]>} Array with the results of all queries
|
|
434
|
+
* @throws {Error} If any query fails, the entire transaction is rolled back
|
|
435
|
+
*
|
|
436
|
+
* @example
|
|
437
|
+
* ```typescript
|
|
438
|
+
* // With QueryReference (autocomplete!)
|
|
439
|
+
* const results = await db.transaction(
|
|
440
|
+
* [queries.users.create, queries.profiles.create],
|
|
441
|
+
* [
|
|
442
|
+
* ["John", "john@email.com"],
|
|
443
|
+
* [null, "Profile description"]
|
|
444
|
+
* ],
|
|
445
|
+
* [{ sourceIndex: 0, targetIndex: 1, targetParamIndex: 0 }]
|
|
446
|
+
* );
|
|
447
|
+
*
|
|
448
|
+
* // With string keys (backward compatible)
|
|
449
|
+
* const results = await db.transaction(
|
|
450
|
+
* ["users.create", "profiles.create"],
|
|
451
|
+
* [["John", "john@email.com"], [null, "Profile description"]],
|
|
452
|
+
* [{ sourceIndex: 0, targetIndex: 1, targetParamIndex: 0 }]
|
|
453
|
+
* );
|
|
454
|
+
* ```
|
|
455
|
+
*/
|
|
456
|
+
async transaction(queryArray, paramsArray, dependencies = []) {
|
|
457
|
+
this.ensurePoolActive();
|
|
458
|
+
if (queryArray.length !== paramsArray.length) {
|
|
459
|
+
const error = new Error("queryArray and paramsArray must have the same length");
|
|
460
|
+
this.logger.error(error.message);
|
|
461
|
+
throw error;
|
|
462
|
+
}
|
|
463
|
+
const client = await this.pool.connect();
|
|
464
|
+
try {
|
|
465
|
+
await client.query("BEGIN");
|
|
466
|
+
this.logger.info("Transaction started", {
|
|
467
|
+
queries: queryArray.length,
|
|
468
|
+
});
|
|
469
|
+
const results = [];
|
|
470
|
+
for (let i = 0; i < queryArray.length; i++) {
|
|
471
|
+
const queryInput = queryArray[i];
|
|
472
|
+
const sqlText = this.getQuery(queryInput);
|
|
473
|
+
const queryName = this.getQueryName(queryInput);
|
|
474
|
+
const params = paramsArray[i];
|
|
475
|
+
this.logger.debug(`Executing transaction query ${i + 1}/${queryArray.length}`, { query: queryName });
|
|
476
|
+
const res = await client.query(sqlText, params);
|
|
477
|
+
results.push(res);
|
|
478
|
+
// Handle dependencies: use the first value of the result as ID
|
|
479
|
+
if (res.rows[0] &&
|
|
480
|
+
typeof res.rows[0] === "object" &&
|
|
481
|
+
res.rows[0] !== null) {
|
|
482
|
+
const firstRow = res.rows[0];
|
|
483
|
+
const id = Object.values(firstRow)[0];
|
|
484
|
+
dependencies.forEach((dep) => {
|
|
485
|
+
if (dep.sourceIndex === i) {
|
|
486
|
+
paramsArray[dep.targetIndex][dep.targetParamIndex] = id;
|
|
487
|
+
this.logger.debug("Dependency resolved", {
|
|
488
|
+
from: i,
|
|
489
|
+
to: dep.targetIndex,
|
|
490
|
+
value: id,
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
await client.query("COMMIT");
|
|
497
|
+
this.logger.info("Transaction committed successfully", {
|
|
498
|
+
results: results.length,
|
|
499
|
+
});
|
|
500
|
+
return results;
|
|
501
|
+
}
|
|
502
|
+
catch (error) {
|
|
503
|
+
await client.query("ROLLBACK");
|
|
504
|
+
this.logger.warn("Transaction rolled back due to error");
|
|
505
|
+
this.logger.error("Error executing transaction", error);
|
|
506
|
+
throw error;
|
|
507
|
+
}
|
|
508
|
+
finally {
|
|
509
|
+
client.release();
|
|
510
|
+
this.logger.debug("Transaction client released");
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
/**
|
|
514
|
+
* Closes all connections in the pool and cleans up resources.
|
|
515
|
+
* Should be called before application shutdown or when the database is no longer needed.
|
|
516
|
+
* After calling this method, the singleton instance is reset and a new one can be created.
|
|
517
|
+
*
|
|
518
|
+
* @returns {Promise<void>}
|
|
519
|
+
* @throws {Error} If there's an error closing the pool
|
|
520
|
+
*
|
|
521
|
+
* @example
|
|
522
|
+
* ```typescript
|
|
523
|
+
* process.on('SIGTERM', async () => {
|
|
524
|
+
* const db = Database.getInstance();
|
|
525
|
+
* await db.close();
|
|
526
|
+
* process.exit(0);
|
|
527
|
+
* });
|
|
528
|
+
* ```
|
|
529
|
+
*/
|
|
530
|
+
async close() {
|
|
531
|
+
try {
|
|
532
|
+
if (this.pool && !this.pool.ended) {
|
|
533
|
+
await this.pool.end();
|
|
534
|
+
this.logger.info("Pool closed successfully");
|
|
535
|
+
}
|
|
536
|
+
// Reset singleton instance to allow recreation
|
|
537
|
+
Database.instance = null;
|
|
538
|
+
}
|
|
539
|
+
catch (error) {
|
|
540
|
+
this.logger.error("Error closing database pool:", error);
|
|
541
|
+
throw new Error(`Error closing database pool: ${error}`);
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
/**
|
|
545
|
+
* Updates the log level dynamically
|
|
546
|
+
* @param level - New log level (0-3)
|
|
547
|
+
*/
|
|
548
|
+
setLogLevel(level) {
|
|
549
|
+
this.logger.setLevel(level);
|
|
550
|
+
this.logger.info(`Log level changed to ${level}`);
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
exports.default = Database;
|
|
554
|
+
//# sourceMappingURL=Database.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Database.js","sourceRoot":"","sources":["../../components/Database.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { LogLevel } from "@/interfaces/DatabaseConfig";
|
|
2
|
+
/**
|
|
3
|
+
* Logger class that handles database operation logs based on configured log level.
|
|
4
|
+
*
|
|
5
|
+
* Log Levels:
|
|
6
|
+
* - 0 (NONE): No logging
|
|
7
|
+
* - 1 (ERROR): Only errors
|
|
8
|
+
* - 2 (DEBUG): Errors + debug information
|
|
9
|
+
* - 3 (ALL): Errors + debug + warnings + info
|
|
10
|
+
*
|
|
11
|
+
* @class Logger
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* const logger = new Logger(2); // ERROR + DEBUG
|
|
15
|
+
* logger.error("Connection failed", error);
|
|
16
|
+
* logger.debug("Query executed", { rowCount: 5 });
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export declare class Logger {
|
|
20
|
+
private level;
|
|
21
|
+
private prefix;
|
|
22
|
+
constructor(level?: LogLevel, prefix?: string);
|
|
23
|
+
/**
|
|
24
|
+
* Logs error messages (Level 1+)
|
|
25
|
+
* @param message - Error message
|
|
26
|
+
* @param error - Optional error object or additional data
|
|
27
|
+
*/
|
|
28
|
+
error(message: string, error?: unknown): void;
|
|
29
|
+
/**
|
|
30
|
+
* Logs debug information (Level 2+)
|
|
31
|
+
* @param message - Debug message
|
|
32
|
+
* @param data - Optional additional data
|
|
33
|
+
*/
|
|
34
|
+
debug(message: string, data?: unknown): void;
|
|
35
|
+
/**
|
|
36
|
+
* Logs warning messages (Level 3+)
|
|
37
|
+
* @param message - Warning message
|
|
38
|
+
* @param data - Optional additional data
|
|
39
|
+
*/
|
|
40
|
+
warn(message: string, data?: unknown): void;
|
|
41
|
+
/**
|
|
42
|
+
* Logs informational messages (Level 3+)
|
|
43
|
+
* @param message - Info message
|
|
44
|
+
* @param data - Optional additional data
|
|
45
|
+
*/
|
|
46
|
+
info(message: string, data?: unknown): void;
|
|
47
|
+
/**
|
|
48
|
+
* Limpia un objeto removiendo propiedades undefined, null o vacías
|
|
49
|
+
* @private
|
|
50
|
+
*/
|
|
51
|
+
private cleanObject;
|
|
52
|
+
/**
|
|
53
|
+
* Updates the log level dynamically
|
|
54
|
+
* @param level - New log level (0-3)
|
|
55
|
+
*/
|
|
56
|
+
setLevel(level: LogLevel): void;
|
|
57
|
+
/**
|
|
58
|
+
* Gets the current log level
|
|
59
|
+
* @returns Current log level
|
|
60
|
+
*/
|
|
61
|
+
getLevel(): LogLevel;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=Logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Logger.d.ts","sourceRoot":"","sources":["../../components/Logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAEvD;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,MAAM;IAGL,OAAO,CAAC,KAAK;IAFzB,OAAO,CAAC,MAAM,CAAS;gBAEH,KAAK,GAAE,QAAY,EAAE,MAAM,GAAE,MAAe;IAIhE;;;;OAIG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,IAAI;IAU7C;;;;OAIG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI;IAkB5C;;;;OAIG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI;IAiB3C;;;;OAIG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI;IAiB3C;;;OAGG;IACH,OAAO,CAAC,WAAW;IAenB;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;IAI/B;;;OAGG;IACH,QAAQ,IAAI,QAAQ;CAGrB"}
|