@dbcube/core 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.
package/dist/index.js ADDED
@@ -0,0 +1,1389 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined") return require.apply(this, arguments);
5
+ throw Error('Dynamic require of "' + x + '" is not supported');
6
+ });
7
+
8
+ // src/lib/Engine.ts
9
+ import path from "path";
10
+
11
+ // src/lib/Arquitecture.ts
12
+ import * as os from "os";
13
+ var Arquitecture = class {
14
+ systemInfo;
15
+ constructor() {
16
+ this.systemInfo = this.detectSystemInfo();
17
+ }
18
+ /**
19
+ * Detecta información completa del sistema
20
+ */
21
+ detectSystemInfo() {
22
+ return {
23
+ platform: os.platform(),
24
+ arch: os.arch(),
25
+ release: os.release(),
26
+ type: os.type(),
27
+ endianness: os.endianness(),
28
+ cpus: os.cpus().length
29
+ };
30
+ }
31
+ /**
32
+ * Obtiene la plataforma normalizada
33
+ */
34
+ getPlatform() {
35
+ const platform2 = this.systemInfo.platform;
36
+ switch (platform2) {
37
+ case "win32":
38
+ return "windows";
39
+ case "darwin":
40
+ return "macos";
41
+ case "linux":
42
+ return "linux";
43
+ case "freebsd":
44
+ return "freebsd";
45
+ case "openbsd":
46
+ return "openbsd";
47
+ case "sunos":
48
+ return "solaris";
49
+ default:
50
+ return platform2;
51
+ }
52
+ }
53
+ /**
54
+ * Obtiene la arquitectura normalizada
55
+ */
56
+ getArchitecture() {
57
+ const arch2 = this.systemInfo.arch;
58
+ switch (arch2) {
59
+ case "x64":
60
+ return "x86_64";
61
+ case "x32":
62
+ case "ia32":
63
+ return "i686";
64
+ case "arm64":
65
+ return "aarch64";
66
+ case "arm":
67
+ return "armv7";
68
+ case "ppc64":
69
+ return "powerpc64";
70
+ case "ppc":
71
+ return "powerpc";
72
+ case "s390x":
73
+ return "s390x";
74
+ case "mips":
75
+ return "mips";
76
+ case "mipsel":
77
+ return "mipsel";
78
+ default:
79
+ return arch2;
80
+ }
81
+ }
82
+ /**
83
+ * Genera el nombre del binario basado en la arquitectura
84
+ */
85
+ getBinaryName(baseName) {
86
+ const platform2 = this.getPlatform();
87
+ const arch2 = this.getArchitecture();
88
+ const extension = platform2 === "windows" ? ".exe" : "";
89
+ return `${baseName}-${platform2}-${arch2}${extension}`;
90
+ }
91
+ /**
92
+ * Obtiene información completa del sistema
93
+ */
94
+ getSystemInfo() {
95
+ return { ...this.systemInfo };
96
+ }
97
+ /**
98
+ * Obtiene el triple de destino (target triple) para Rust
99
+ */
100
+ getRustTargetTriple() {
101
+ const platform2 = this.getPlatform();
102
+ const arch2 = this.getArchitecture();
103
+ const targetMap = {
104
+ "linux-x86_64": "x86_64-unknown-linux-gnu",
105
+ "linux-i686": "i686-unknown-linux-gnu",
106
+ "linux-aarch64": "aarch64-unknown-linux-gnu",
107
+ "linux-armv7": "armv7-unknown-linux-gnueabihf",
108
+ "macos-x86_64": "x86_64-apple-darwin",
109
+ "macos-aarch64": "aarch64-apple-darwin",
110
+ "windows-x86_64": "x86_64-pc-windows-msvc",
111
+ "windows-i686": "i686-pc-windows-msvc",
112
+ "windows-aarch64": "aarch64-pc-windows-msvc",
113
+ "freebsd-x86_64": "x86_64-unknown-freebsd"
114
+ };
115
+ const key = `${platform2}-${arch2}`;
116
+ return targetMap[key] || `${arch2}-unknown-${platform2}`;
117
+ }
118
+ /**
119
+ * Muestra información detallada del sistema
120
+ */
121
+ printSystemInfo() {
122
+ console.log("\u{1F5A5}\uFE0F System Information:");
123
+ console.log("\u251C\u2500 Platform:", this.getPlatform());
124
+ console.log("\u251C\u2500 Arquitecture:", this.getArchitecture());
125
+ console.log("\u251C\u2500 OS Type:", this.systemInfo.type);
126
+ console.log("\u251C\u2500 OS Release:", this.systemInfo.release);
127
+ console.log("\u251C\u2500 Endianness:", this.systemInfo.endianness);
128
+ console.log("\u251C\u2500 CPUs:", this.systemInfo.cpus);
129
+ console.log("\u2514\u2500 Rust Target:", this.getRustTargetTriple());
130
+ }
131
+ };
132
+
133
+ // src/lib/Binary.ts
134
+ var Binary = class {
135
+ static get() {
136
+ const arch2 = new Arquitecture();
137
+ const platform2 = arch2.getPlatform();
138
+ const architecture = arch2.getArchitecture();
139
+ switch (platform2) {
140
+ case "windows":
141
+ if (architecture == "x86_64") {
142
+ return {
143
+ query_engine: "query-engine-windows-x64.exe",
144
+ schema_engine: "schema-engine-windows-x64.exe"
145
+ };
146
+ }
147
+ break;
148
+ }
149
+ return {
150
+ query_engine: "",
151
+ schema_engine: ""
152
+ };
153
+ }
154
+ };
155
+
156
+ // src/lib/Config.ts
157
+ var Config = class {
158
+ data = {};
159
+ databases = {};
160
+ /**
161
+ * Establece la configuración
162
+ * @param configData - Datos de configuración
163
+ */
164
+ set(configData) {
165
+ this.data = configData;
166
+ if (configData.databases) {
167
+ this.databases = configData.databases;
168
+ }
169
+ }
170
+ /**
171
+ * Obtiene un valor de configuración
172
+ * @param key - Clave de configuración
173
+ * @returns Valor de configuración
174
+ */
175
+ get(key) {
176
+ return this.data[key];
177
+ }
178
+ /**
179
+ * Obtiene la configuración de una base de datos específica
180
+ * @param dbName - Nombre de la base de datos
181
+ * @returns Configuración de la base de datos o null
182
+ */
183
+ getDatabase(dbName) {
184
+ return this.databases[dbName] || null;
185
+ }
186
+ /**
187
+ * Obtiene todas las bases de datos configuradas
188
+ * @returns Todas las configuraciones de bases de datos
189
+ */
190
+ getAllDatabases() {
191
+ return this.databases;
192
+ }
193
+ };
194
+
195
+ // src/lib/Engine.ts
196
+ import { spawn } from "child_process";
197
+ var Engine = class {
198
+ name;
199
+ config;
200
+ arguments;
201
+ binary;
202
+ timeout;
203
+ constructor(name, timeout = 3e4) {
204
+ this.name = name;
205
+ this.config = this.setConfig(name);
206
+ const binary = Binary.get();
207
+ this.binary = {
208
+ query_engine: path.resolve(__dirname, "../bin", binary.query_engine),
209
+ schema_engine: path.resolve(__dirname, "../bin", binary.schema_engine)
210
+ };
211
+ this.arguments = this.setArguments();
212
+ this.timeout = timeout;
213
+ }
214
+ setArguments() {
215
+ let args = [];
216
+ if (this.config.type == "sqlite") {
217
+ args = [
218
+ "--id",
219
+ "dbcube-" + this.name,
220
+ "--database-ref",
221
+ this.name,
222
+ "--database",
223
+ this.config.config.DATABASE + ".db",
224
+ "--motor",
225
+ this.config.type
226
+ ];
227
+ } else {
228
+ args = [
229
+ "--id",
230
+ "dbcube-" + this.name,
231
+ "--database-ref",
232
+ this.name,
233
+ "--database",
234
+ this.config.config.DATABASE,
235
+ "--host",
236
+ this.config.config.HOST,
237
+ "--port",
238
+ this.config.config.PORT,
239
+ "--user",
240
+ this.config.config.USER,
241
+ "--password",
242
+ this.config.config.PASSWORD,
243
+ "--motor",
244
+ this.config.type
245
+ ];
246
+ }
247
+ return args;
248
+ }
249
+ setConfig(name) {
250
+ const configInstance = new Config();
251
+ const configFilePath = path.resolve(process.cwd(), "dbcube.config.js");
252
+ const configFn = __require(configFilePath);
253
+ if (typeof configFn === "function") {
254
+ configFn(configInstance);
255
+ } else {
256
+ console.error("\u274C El archivo dbcube.config.js no exporta una funci\xF3n.");
257
+ }
258
+ return configInstance.getDatabase(name);
259
+ }
260
+ getConfig() {
261
+ return this.config;
262
+ }
263
+ async run(binary, args) {
264
+ return new Promise((resolve2, reject) => {
265
+ const child = spawn(this.binary[binary], [...this.arguments, ...args]);
266
+ let stdoutBuffer = "";
267
+ let stderrBuffer = "";
268
+ let isResolved = false;
269
+ const timeoutId = setTimeout(() => {
270
+ if (!isResolved) {
271
+ isResolved = true;
272
+ child.kill();
273
+ reject(new Error("Process timeout"));
274
+ }
275
+ }, this.timeout);
276
+ const resolveOnce = (response) => {
277
+ if (!isResolved) {
278
+ isResolved = true;
279
+ clearTimeout(timeoutId);
280
+ resolve2(response);
281
+ }
282
+ };
283
+ child.stdout.on("data", (data) => {
284
+ stdoutBuffer += data.toString();
285
+ const match = stdoutBuffer.match(/PROCESS_RESPONSE:(\{.*\})/);
286
+ if (match) {
287
+ try {
288
+ const response = JSON.parse(match[1]);
289
+ resolveOnce({
290
+ status: response.status,
291
+ message: response.message,
292
+ data: response.data
293
+ });
294
+ } catch (error) {
295
+ resolveOnce({
296
+ status: 500,
297
+ message: "Failed to parse response JSON",
298
+ data: null
299
+ });
300
+ }
301
+ }
302
+ });
303
+ child.stderr.on("data", (data) => {
304
+ stderrBuffer += data.toString();
305
+ const match = stderrBuffer.match(/PROCESS_RESPONSE:(\{.*\})/);
306
+ if (match) {
307
+ try {
308
+ const response = JSON.parse(match[1]);
309
+ resolveOnce({
310
+ status: response.status,
311
+ message: response.message,
312
+ data: response.data
313
+ });
314
+ } catch (error) {
315
+ resolveOnce({
316
+ status: 500,
317
+ message: "Failed to parse response JSON",
318
+ data: null
319
+ });
320
+ }
321
+ }
322
+ });
323
+ child.on("close", (code) => {
324
+ clearTimeout(timeoutId);
325
+ if (!isResolved) {
326
+ resolveOnce({
327
+ status: code === 0 ? 200 : 500,
328
+ message: code === 0 ? "Process completed" : `Process exited with code ${code}`,
329
+ data: null
330
+ });
331
+ }
332
+ });
333
+ child.on("error", (error) => {
334
+ clearTimeout(timeoutId);
335
+ if (!isResolved) {
336
+ resolveOnce({
337
+ status: 500,
338
+ message: `Process error: ${error.message}`,
339
+ data: null
340
+ });
341
+ }
342
+ });
343
+ child.unref();
344
+ });
345
+ }
346
+ };
347
+
348
+ // src/lib/DbConfig.ts
349
+ import * as sqlite3 from "sqlite3";
350
+ import * as path2 from "path";
351
+ import fs from "fs";
352
+ var rootPath = path2.resolve(process.cwd(), "dbcube");
353
+ var SQLite = class {
354
+ db = null;
355
+ database;
356
+ constructor(config) {
357
+ this.database = config.DATABASE;
358
+ }
359
+ ifExist() {
360
+ if (this.database) {
361
+ const dbPath = this.database || ":memory:";
362
+ const configPath = path2.join(rootPath, dbPath + ".db");
363
+ if (fs.existsSync(configPath)) {
364
+ return true;
365
+ }
366
+ }
367
+ return false;
368
+ }
369
+ async connect() {
370
+ if (!this.db) {
371
+ try {
372
+ const dbPath = this.database || ":memory:";
373
+ const configPath = path2.join(rootPath, dbPath + ".db");
374
+ this.db = new sqlite3.Database(configPath, (err) => {
375
+ if (err) throw err;
376
+ });
377
+ } catch (error) {
378
+ throw error;
379
+ }
380
+ }
381
+ return this.db;
382
+ }
383
+ async disconnect() {
384
+ if (this.db) {
385
+ return new Promise((resolve2, reject) => {
386
+ this.db.close((err) => {
387
+ if (err) {
388
+ return reject(err);
389
+ }
390
+ this.db = null;
391
+ resolve2();
392
+ });
393
+ });
394
+ }
395
+ }
396
+ /**
397
+ * Executes a SQL query on the currently set database.
398
+ *
399
+ * @param {string} sqlQuery - The SQL query to execute.
400
+ * @returns {Promise<QueryResult>} - Returns a JSON object with the status, message, and data (if any).
401
+ *
402
+ * @example
403
+ * const result = await db.query('SELECT * FROM users;');
404
+ * console.log(result);
405
+ * // { status: 'success', message: 'Query executed successfully', data: [{ id: 1, name: 'John' }, { id: 2, name: 'Jane' }] }
406
+ *
407
+ * @example
408
+ * const result = await db.query('INVALID SQL QUERY;');
409
+ * console.log(result);
410
+ * // { status: 'error', message: 'SQL syntax error', data: null }
411
+ */
412
+ async query(sqlQuery) {
413
+ if (typeof sqlQuery !== "string") {
414
+ throw new Error("The SQL query must be a string.");
415
+ }
416
+ const sqlCommands = sqlQuery.split(";").filter((cmd) => cmd.trim().length > 0);
417
+ return new Promise((resolve2) => {
418
+ try {
419
+ if (!this.db) {
420
+ throw new Error("Database connection is not available.");
421
+ }
422
+ const results = [];
423
+ let commandsProcessed = 0;
424
+ for (const command of sqlCommands) {
425
+ const query = `${command};`;
426
+ const isSelect = query.trim().toLowerCase().startsWith("select");
427
+ if (isSelect) {
428
+ this.db.all(query, [], (err, rows) => {
429
+ if (err) {
430
+ throw err;
431
+ }
432
+ results.push(rows);
433
+ commandsProcessed++;
434
+ if (commandsProcessed === sqlCommands.length) {
435
+ resolve2({
436
+ status: "success",
437
+ message: "Query executed successfully",
438
+ data: results.length === 1 ? results[0] : results
439
+ });
440
+ }
441
+ });
442
+ } else {
443
+ this.db.run(query, [], function(err) {
444
+ if (err) {
445
+ throw err;
446
+ }
447
+ results.push({ changes: this.changes, lastID: this.lastID });
448
+ commandsProcessed++;
449
+ if (commandsProcessed === sqlCommands.length) {
450
+ resolve2({
451
+ status: "success",
452
+ message: "Query executed successfully",
453
+ data: results.length === 1 ? results[0] : results
454
+ });
455
+ }
456
+ });
457
+ }
458
+ }
459
+ } catch (error) {
460
+ resolve2({
461
+ status: "error",
462
+ message: error.message || "An error occurred while executing the query.",
463
+ data: null
464
+ });
465
+ }
466
+ });
467
+ }
468
+ /**
469
+ * Executes a SQL query with parameters on the currently set database.
470
+ *
471
+ * @param {string} sqlQuery - The SQL query to execute with placeholders (?).
472
+ * @param {any[]} params - Array of parameters to bind to the query placeholders.
473
+ * @returns {Promise<QueryResult>} - Returns a JSON object with the status, message, and data (if any).
474
+ *
475
+ * @example
476
+ * const result = await db.queryWithParameters('INSERT INTO users (name, email) VALUES (?, ?)', ['John', 'john@example.com']);
477
+ * console.log(result);
478
+ * // { status: 'success', message: 'Query executed successfully', data: { changes: 1, lastID: 3 } }
479
+ */
480
+ async queryWithParameters(sqlQuery, params = []) {
481
+ if (typeof sqlQuery !== "string") {
482
+ throw new Error("The SQL query must be a string.");
483
+ }
484
+ if (!Array.isArray(params)) {
485
+ throw new Error("Parameters must be an array.");
486
+ }
487
+ return new Promise((resolve2) => {
488
+ try {
489
+ if (!this.db) {
490
+ throw new Error("Database connection is not available.");
491
+ }
492
+ const isSelect = sqlQuery.trim().toLowerCase().startsWith("select");
493
+ if (isSelect) {
494
+ this.db.all(sqlQuery, params, (err, rows) => {
495
+ if (err) {
496
+ throw err;
497
+ }
498
+ resolve2({
499
+ status: "success",
500
+ message: "Query executed successfully",
501
+ data: rows
502
+ });
503
+ });
504
+ } else {
505
+ this.db.run(sqlQuery, params, function(err) {
506
+ if (err) {
507
+ throw err;
508
+ }
509
+ resolve2({
510
+ status: "success",
511
+ message: "Query executed successfully",
512
+ data: { changes: this.changes, lastID: this.lastID }
513
+ });
514
+ });
515
+ }
516
+ } catch (error) {
517
+ console.log(error);
518
+ resolve2({
519
+ status: "error",
520
+ message: error.message || "An error occurred while executing the query.",
521
+ data: null
522
+ });
523
+ }
524
+ });
525
+ }
526
+ convertToParameterizedQuery(sql) {
527
+ const normalizedSql = sql.replace(/\s+/g, " ").trim();
528
+ const baseQueryMatch = normalizedSql.match(/^(.+?)\s+VALUES\s*\(/i);
529
+ if (!baseQueryMatch) {
530
+ throw new Error("No se pudo encontrar la estructura VALUES en la consulta");
531
+ }
532
+ const baseQuery = baseQueryMatch[1];
533
+ const valuesStartIndex = normalizedSql.toUpperCase().indexOf("VALUES");
534
+ const valuesSection = normalizedSql.substring(valuesStartIndex);
535
+ const valuesMatch = valuesSection.match(/VALUES\s*\((.+)\)\s*;?\s*$/i);
536
+ if (!valuesMatch) {
537
+ throw new Error("No se pudieron extraer los valores de la consulta");
538
+ }
539
+ const valuesString = valuesMatch[1];
540
+ function parseValues(str) {
541
+ const values = [];
542
+ let currentValue = "";
543
+ let inQuotes = false;
544
+ let quoteChar = "";
545
+ let inCompute = false;
546
+ let computeDepth = 0;
547
+ for (let i = 0; i < str.length; i++) {
548
+ const char = str[i];
549
+ const prevChar = str[i - 1];
550
+ if (!inQuotes && str.substring(i, i + 8) === "@compute") {
551
+ inCompute = true;
552
+ }
553
+ if (inCompute && char === "(") {
554
+ computeDepth++;
555
+ } else if (inCompute && char === ")") {
556
+ computeDepth--;
557
+ if (computeDepth === 0) {
558
+ inCompute = false;
559
+ }
560
+ }
561
+ if (!inCompute && (char === '"' || char === "'") && prevChar !== "\\") {
562
+ if (!inQuotes) {
563
+ inQuotes = true;
564
+ quoteChar = char;
565
+ } else if (char === quoteChar) {
566
+ if (str[i + 1] === quoteChar) {
567
+ currentValue += char + char;
568
+ i++;
569
+ continue;
570
+ } else {
571
+ inQuotes = false;
572
+ quoteChar = "";
573
+ }
574
+ }
575
+ }
576
+ if (!inQuotes && !inCompute && char === ",") {
577
+ values.push(cleanValue(currentValue.trim()));
578
+ currentValue = "";
579
+ continue;
580
+ }
581
+ currentValue += char;
582
+ }
583
+ if (currentValue.trim()) {
584
+ values.push(cleanValue(currentValue.trim()));
585
+ }
586
+ return values;
587
+ }
588
+ function cleanValue(value) {
589
+ value = value.trim();
590
+ if (value.startsWith("@compute")) {
591
+ return value;
592
+ }
593
+ if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
594
+ value = value.slice(1, -1);
595
+ value = value.replace(/''/g, "'").replace(/""/g, '"');
596
+ }
597
+ return value;
598
+ }
599
+ const parameters = parseValues(valuesString);
600
+ const placeholders = parameters.map(() => "?").join(", ");
601
+ const parametrizedQuery = `${baseQuery} VALUES (${placeholders});`;
602
+ return {
603
+ query: parametrizedQuery,
604
+ parameters
605
+ };
606
+ }
607
+ };
608
+ var DbConfig = new SQLite({ DATABASE: "config" });
609
+ var DbConfig_default = DbConfig;
610
+
611
+ // src/lib/FileLogger.ts
612
+ import * as fs2 from "fs";
613
+ import * as path3 from "path";
614
+ import { EventEmitter } from "events";
615
+ var FileLogger = class _FileLogger extends EventEmitter {
616
+ static watchers = /* @__PURE__ */ new Map();
617
+ // Store listener functions
618
+ static buffers = /* @__PURE__ */ new Map();
619
+ /**
620
+ * Escribe un log en el archivo especificado
621
+ * @param filePath - Ruta del archivo de log
622
+ * @param message - Mensaje a escribir
623
+ * @param level - Nivel del log (INFO, ERROR, WARN, DEBUG)
624
+ * @param append - Si debe agregar al final del archivo (default: true)
625
+ */
626
+ static async write(filePath, message, level = "INFO", append = true) {
627
+ try {
628
+ const dir = path3.dirname(filePath);
629
+ if (!fs2.existsSync(dir)) {
630
+ fs2.mkdirSync(dir, { recursive: true });
631
+ }
632
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
633
+ const formattedMessage = `[${timestamp}] [${level}] ${message}
634
+ `;
635
+ if (_FileLogger.buffers.has(filePath)) {
636
+ _FileLogger.buffers.get(filePath).push(formattedMessage);
637
+ return true;
638
+ }
639
+ if (append) {
640
+ await fs2.promises.appendFile(filePath, formattedMessage, "utf8");
641
+ } else {
642
+ await fs2.promises.writeFile(filePath, formattedMessage, "utf8");
643
+ }
644
+ return true;
645
+ } catch (error) {
646
+ console.error("Error escribiendo log:", error);
647
+ throw error;
648
+ }
649
+ }
650
+ /**
651
+ * Inicia un buffer temporal para un archivo de log
652
+ * @param filePath - Ruta del archivo de log
653
+ */
654
+ static startBuffer(filePath) {
655
+ if (!_FileLogger.buffers.has(filePath)) {
656
+ _FileLogger.buffers.set(filePath, []);
657
+ }
658
+ }
659
+ /**
660
+ * Confirma y escribe todos los logs del buffer al archivo
661
+ * @param filePath - Ruta del archivo de log
662
+ */
663
+ static async commitBuffer(filePath) {
664
+ const buffer = _FileLogger.buffers.get(filePath);
665
+ if (buffer && buffer.length > 0) {
666
+ try {
667
+ const dir = path3.dirname(filePath);
668
+ if (!fs2.existsSync(dir)) {
669
+ fs2.mkdirSync(dir, { recursive: true });
670
+ }
671
+ const content = buffer.join("");
672
+ await fs2.promises.appendFile(filePath, content, "utf8");
673
+ _FileLogger.buffers.delete(filePath);
674
+ return true;
675
+ } catch (error) {
676
+ console.error("Error confirmando buffer:", error);
677
+ throw error;
678
+ }
679
+ }
680
+ _FileLogger.buffers.delete(filePath);
681
+ return false;
682
+ }
683
+ /**
684
+ * Descarta todos los logs del buffer sin escribirlos
685
+ * @param filePath - Ruta del archivo de log
686
+ */
687
+ static discardBuffer(filePath) {
688
+ if (_FileLogger.buffers.has(filePath)) {
689
+ const discardedCount = _FileLogger.buffers.get(filePath).length;
690
+ _FileLogger.buffers.delete(filePath);
691
+ return discardedCount;
692
+ }
693
+ return 0;
694
+ }
695
+ /**
696
+ * Verifica si existe un buffer activo para un archivo
697
+ * @param filePath - Ruta del archivo de log
698
+ */
699
+ static hasBuffer(filePath) {
700
+ return _FileLogger.buffers.has(filePath);
701
+ }
702
+ /**
703
+ * Obtiene el número de logs en el buffer
704
+ * @param filePath - Ruta del archivo de log
705
+ */
706
+ static getBufferSize(filePath) {
707
+ const buffer = _FileLogger.buffers.get(filePath);
708
+ return buffer ? buffer.length : 0;
709
+ }
710
+ /**
711
+ * Intercepta console.log y console.error para escribir a archivo
712
+ * @param filePath - Ruta del archivo de log
713
+ * @param options - Opciones de interceptación
714
+ */
715
+ static interceptConsole(filePath, options = {}) {
716
+ const {
717
+ interceptLog = true,
718
+ interceptError = true,
719
+ interceptWarn = true,
720
+ keepOriginal = true,
721
+ // Mantener el comportamiento original de console
722
+ useBuffer = false
723
+ // Usar buffer temporal
724
+ } = options;
725
+ if (useBuffer) {
726
+ _FileLogger.startBuffer(filePath);
727
+ }
728
+ const originalLog = console.log;
729
+ const originalError = console.error;
730
+ const originalWarn = console.warn;
731
+ if (interceptLog) {
732
+ console.log = function(...args) {
733
+ const message = args.map(
734
+ (arg) => typeof arg === "object" ? JSON.stringify(arg) : String(arg)
735
+ ).join(" ");
736
+ _FileLogger.write(filePath, message, "INFO").catch((err) => {
737
+ originalError("Error escribiendo log:", err);
738
+ });
739
+ if (keepOriginal) {
740
+ originalLog.apply(console, args);
741
+ }
742
+ };
743
+ }
744
+ if (interceptError) {
745
+ console.error = function(...args) {
746
+ const message = args.map(
747
+ (arg) => typeof arg === "object" ? JSON.stringify(arg) : String(arg)
748
+ ).join(" ");
749
+ _FileLogger.write(filePath, message, "ERROR").catch((err) => {
750
+ originalError("Error escribiendo error log:", err);
751
+ });
752
+ if (keepOriginal) {
753
+ originalError.apply(console, args);
754
+ }
755
+ };
756
+ }
757
+ if (interceptWarn) {
758
+ console.warn = function(...args) {
759
+ const message = args.map(
760
+ (arg) => typeof arg === "object" ? JSON.stringify(arg) : String(arg)
761
+ ).join(" ");
762
+ _FileLogger.write(filePath, message, "WARN").catch((err) => {
763
+ originalError("Error escribiendo warn log:", err);
764
+ });
765
+ if (keepOriginal) {
766
+ originalWarn.apply(console, args);
767
+ }
768
+ };
769
+ }
770
+ return {
771
+ restore: () => {
772
+ if (interceptLog) console.log = originalLog;
773
+ if (interceptError) console.error = originalError;
774
+ if (interceptWarn) console.warn = originalWarn;
775
+ },
776
+ commit: async () => {
777
+ if (useBuffer) {
778
+ return await _FileLogger.commitBuffer(filePath);
779
+ }
780
+ return false;
781
+ },
782
+ discard: () => {
783
+ if (useBuffer) {
784
+ return _FileLogger.discardBuffer(filePath);
785
+ }
786
+ return 0;
787
+ },
788
+ hasBuffer: () => _FileLogger.hasBuffer(filePath),
789
+ getBufferSize: () => _FileLogger.getBufferSize(filePath)
790
+ };
791
+ }
792
+ /**
793
+ * Lee el contenido completo del archivo de log
794
+ * @param filePath - Ruta del archivo de log
795
+ * @param options - Opciones de lectura
796
+ * @returns Contenido del archivo
797
+ */
798
+ static async read(filePath, options = {}) {
799
+ const {
800
+ lines = null,
801
+ // Número de líneas a leer (null = todas)
802
+ fromEnd = false,
803
+ // Si debe leer desde el final
804
+ asArray = false
805
+ // Si debe retornar como array de líneas
806
+ } = options;
807
+ try {
808
+ if (!fs2.existsSync(filePath)) {
809
+ return asArray ? [] : "";
810
+ }
811
+ let content = await fs2.promises.readFile(filePath, "utf8");
812
+ if (asArray) {
813
+ let linesArray = content.split("\n").filter((line) => line.trim() !== "");
814
+ if (lines !== null) {
815
+ if (fromEnd) {
816
+ linesArray = linesArray.slice(-lines);
817
+ } else {
818
+ linesArray = linesArray.slice(0, lines);
819
+ }
820
+ }
821
+ return linesArray;
822
+ }
823
+ if (lines !== null) {
824
+ let linesArray = content.split("\n").filter((line) => line.trim() !== "");
825
+ if (fromEnd) {
826
+ linesArray = linesArray.slice(-lines);
827
+ } else {
828
+ linesArray = linesArray.slice(0, lines);
829
+ }
830
+ content = linesArray.join("\n");
831
+ }
832
+ return content;
833
+ } catch (error) {
834
+ console.error("Error leyendo log:", error);
835
+ throw error;
836
+ }
837
+ }
838
+ /**
839
+ * Observa un archivo de log en tiempo real
840
+ * @param filePath - Ruta del archivo de log
841
+ * @param callback - Función callback para nuevas líneas
842
+ * @param options - Opciones del watcher
843
+ * @returns Objeto con métodos para controlar el watcher
844
+ */
845
+ static watch(filePath, callback, options = {}) {
846
+ const {
847
+ persistent = true,
848
+ interval = 100,
849
+ fromEnd = true
850
+ // Empezar desde el final del archivo
851
+ } = options;
852
+ let lastSize = 0;
853
+ let lastPosition = 0;
854
+ if (fs2.existsSync(filePath)) {
855
+ const stats = fs2.statSync(filePath);
856
+ lastSize = stats.size;
857
+ lastPosition = fromEnd ? stats.size : 0;
858
+ }
859
+ const listener = async (curr, prev) => {
860
+ try {
861
+ if (curr.size > lastSize) {
862
+ const stream = fs2.createReadStream(filePath, {
863
+ start: lastPosition,
864
+ end: curr.size - 1,
865
+ encoding: "utf8"
866
+ });
867
+ let buffer = "";
868
+ stream.on("data", (chunk) => {
869
+ buffer += chunk;
870
+ const lines = buffer.split("\n");
871
+ for (let i = 0; i < lines.length - 1; i++) {
872
+ if (lines[i].trim()) {
873
+ callback(lines[i].trim(), filePath);
874
+ }
875
+ }
876
+ buffer = lines[lines.length - 1];
877
+ });
878
+ stream.on("end", () => {
879
+ if (buffer.trim()) {
880
+ callback(buffer.trim(), filePath);
881
+ }
882
+ });
883
+ lastSize = curr.size;
884
+ lastPosition = curr.size;
885
+ }
886
+ } catch (error) {
887
+ console.error("Error en watcher:", error);
888
+ }
889
+ };
890
+ fs2.watchFile(filePath, { persistent, interval }, listener);
891
+ const watcherId = `${filePath}_${Date.now()}`;
892
+ _FileLogger.watchers.set(watcherId, listener);
893
+ return {
894
+ id: watcherId,
895
+ stop: () => {
896
+ const storedListener = _FileLogger.watchers.get(watcherId);
897
+ if (storedListener) {
898
+ fs2.unwatchFile(filePath, storedListener);
899
+ _FileLogger.watchers.delete(watcherId);
900
+ }
901
+ },
902
+ isWatching: () => _FileLogger.watchers.has(watcherId)
903
+ };
904
+ }
905
+ /**
906
+ * Detiene todos los watchers activos
907
+ */
908
+ static stopAllWatchers() {
909
+ for (const [watcherId] of _FileLogger.watchers) {
910
+ const filePath = watcherId.split("_")[0];
911
+ fs2.unwatchFile(filePath);
912
+ }
913
+ _FileLogger.watchers.clear();
914
+ }
915
+ /**
916
+ * Métodos de conveniencia para diferentes niveles de log
917
+ */
918
+ static async info(filePath, message) {
919
+ return this.write(filePath, message, "INFO");
920
+ }
921
+ static async error(filePath, message) {
922
+ return this.write(filePath, message, "ERROR");
923
+ }
924
+ static async warn(filePath, message) {
925
+ return this.write(filePath, message, "WARN");
926
+ }
927
+ static async debug(filePath, message) {
928
+ return this.write(filePath, message, "DEBUG");
929
+ }
930
+ /**
931
+ * Limpia logs antiguos
932
+ * @param filePath - Ruta del archivo de log
933
+ * @param maxLines - Máximo número de líneas a mantener
934
+ */
935
+ static async cleanup(filePath, maxLines = 1e3) {
936
+ try {
937
+ const lines = await this.read(filePath, { asArray: true });
938
+ if (lines.length > maxLines) {
939
+ const keepLines = lines.slice(-maxLines);
940
+ const content = keepLines.join("\n") + "\n";
941
+ await fs2.promises.writeFile(filePath, content, "utf8");
942
+ return lines.length - maxLines;
943
+ }
944
+ return 0;
945
+ } catch (error) {
946
+ console.error("Error limpiando logs:", error);
947
+ throw error;
948
+ }
949
+ }
950
+ /**
951
+ * Elimina un archivo de log
952
+ * @param filePath - Ruta del archivo de log a eliminar
953
+ */
954
+ static async deleteLogFile(filePath) {
955
+ try {
956
+ if (fs2.existsSync(filePath)) {
957
+ await fs2.promises.unlink(filePath);
958
+ return true;
959
+ }
960
+ return false;
961
+ } catch (error) {
962
+ console.error("Error eliminando archivo de log:", error);
963
+ throw error;
964
+ }
965
+ }
966
+ /**
967
+ * Elimina múltiples archivos de log
968
+ * @param filePaths - Array de rutas de archivos de log a eliminar
969
+ */
970
+ static async deleteLogFiles(filePaths) {
971
+ const results = [];
972
+ for (const filePath of filePaths) {
973
+ try {
974
+ const deleted = await this.deleteLogFile(filePath);
975
+ results.push({ filePath, deleted, error: null });
976
+ } catch (error) {
977
+ results.push({ filePath, deleted: false, error: error.message });
978
+ }
979
+ }
980
+ return results;
981
+ }
982
+ };
983
+
984
+ // src/lib/Processors.ts
985
+ var ComputedFieldProcessor = class {
986
+ static async getComputedFields(name) {
987
+ let computedFields = [];
988
+ if (DbConfig_default.ifExist()) {
989
+ await DbConfig_default.connect();
990
+ try {
991
+ const tableExistsQuery = `SELECT name FROM sqlite_master WHERE type='table' AND name='dbcube_computes_config'`;
992
+ const tableExistsResult = await DbConfig_default.query(tableExistsQuery);
993
+ if (tableExistsResult.status === "success" && tableExistsResult.data && tableExistsResult.data.length > 0) {
994
+ const queryComputes = await DbConfig_default.query(`SELECT * FROM dbcube_computes_config WHERE database_ref='${name}'`);
995
+ computedFields = queryComputes.data;
996
+ } else {
997
+ computedFields = [];
998
+ }
999
+ } catch (error) {
1000
+ console.error("Error fetching computed fields:", error);
1001
+ computedFields = [];
1002
+ }
1003
+ await DbConfig_default.disconnect();
1004
+ }
1005
+ return computedFields;
1006
+ }
1007
+ /**
1008
+ * Processes computed field instruction and returns the computed value
1009
+ * @param instruction - The @compute instruction
1010
+ * @param rowData - The row data containing column values
1011
+ * @returns The computed value or null if there's an error
1012
+ */
1013
+ static processInstruction(instruction, rowData) {
1014
+ try {
1015
+ const functionMatch = instruction.match(/@compute\s*\(\s*\(\s*\)\s*=>\s*{([\s\S]*?)}\s*\)/);
1016
+ if (!functionMatch) {
1017
+ throw new Error("Invalid @compute instruction format");
1018
+ }
1019
+ let functionBody = functionMatch[1].trim();
1020
+ if (functionBody.endsWith(";")) {
1021
+ functionBody = functionBody.slice(0, -1).trim();
1022
+ }
1023
+ functionBody = functionBody.replace(/@column\(([^)]+)\)/g, (_match, columnName) => {
1024
+ const cleanColumnName = columnName.trim().replace(/['"]/g, "");
1025
+ const value = rowData[cleanColumnName];
1026
+ if (value === null || value === void 0) {
1027
+ return "null";
1028
+ } else if (typeof value === "string") {
1029
+ return `"${value.replace(/"/g, '\\"')}"`;
1030
+ } else if (typeof value === "number" || typeof value === "boolean") {
1031
+ return value.toString();
1032
+ } else if (value instanceof Date) {
1033
+ return `new Date("${value.toISOString()}")`;
1034
+ } else {
1035
+ return JSON.stringify(value);
1036
+ }
1037
+ });
1038
+ const computeFunction = new Function(functionBody);
1039
+ return computeFunction();
1040
+ } catch (error) {
1041
+ console.error("Error processing computed field:", error);
1042
+ return null;
1043
+ }
1044
+ }
1045
+ /**
1046
+ * Extracts column dependencies from a computed field instruction
1047
+ * @param instruction - The @compute instruction
1048
+ * @returns Array of column names that this computed field depends on
1049
+ */
1050
+ static extractDependencies(instruction) {
1051
+ const dependencies = [];
1052
+ const columnMatches = instruction.match(/@column\(([^)]+)\)/g);
1053
+ if (columnMatches) {
1054
+ for (const match of columnMatches) {
1055
+ const innerMatch = match.match(/@column\(([^)]+)\)/);
1056
+ if (innerMatch) {
1057
+ const columnName = innerMatch[1].trim().replace(/['"]/g, "");
1058
+ if (!dependencies.includes(columnName)) {
1059
+ dependencies.push(columnName);
1060
+ }
1061
+ }
1062
+ }
1063
+ }
1064
+ return dependencies;
1065
+ }
1066
+ /**
1067
+ * Adds computed fields to an array of data objects based on configuration array
1068
+ * @param data - Array of data objects
1069
+ * @param computedConfigs - Array of computed field configurations
1070
+ * @returns Array with the new computed fields added
1071
+ */
1072
+ static computedFields(data, computedConfigs) {
1073
+ return data.map((item, index) => {
1074
+ let processedItem = { ...item };
1075
+ computedConfigs.forEach((config) => {
1076
+ try {
1077
+ const { column: fieldName, type: type2, instruction } = config;
1078
+ let processedExpression = instruction.replace(
1079
+ /@column\(([^)]+)\)/g,
1080
+ (match, columnName) => {
1081
+ const cleanColumnName = columnName.replace(/['"]/g, "");
1082
+ const value = processedItem[cleanColumnName];
1083
+ if (typeof value === "string") {
1084
+ return `"${value}"`;
1085
+ } else if (value === null || value === void 0) {
1086
+ return "null";
1087
+ } else {
1088
+ return String(value);
1089
+ }
1090
+ }
1091
+ );
1092
+ const computeMatch = processedExpression.match(/@compute\s*\(\s*\(\s*\)\s*=>\s*\{(.*)\}\s*\)/s);
1093
+ if (!computeMatch) {
1094
+ throw new Error(`Formato de @compute inv\xE1lido para campo ${fieldName}`);
1095
+ }
1096
+ const functionBody = computeMatch[1];
1097
+ const computeFunction = new Function(functionBody);
1098
+ let result = computeFunction();
1099
+ result = convertToType(result, type2);
1100
+ processedItem[fieldName] = result;
1101
+ } catch (error) {
1102
+ console.error(`Error procesando campo ${config.column} en item ${index}:`, error);
1103
+ processedItem[config.column] = null;
1104
+ }
1105
+ });
1106
+ return processedItem;
1107
+ });
1108
+ }
1109
+ };
1110
+ var TableProcessor = class {
1111
+ static async generateAlterQueries(nowQuery, dbType, tableName, database_ref) {
1112
+ function parseCreateTableQuery(query, dbType2) {
1113
+ const cleanQuery = query.trim().replace(/\s+/g, " ");
1114
+ const tableNameMatch = cleanQuery.match(/CREATE TABLE (?:IF NOT EXISTS )?(\w+)/i);
1115
+ if (!tableNameMatch) {
1116
+ throw new Error("No se pudo extraer el nombre de la tabla");
1117
+ }
1118
+ const tableName2 = tableNameMatch[1];
1119
+ const columnsMatch = cleanQuery.match(/\((.+)\)/);
1120
+ if (!columnsMatch) {
1121
+ throw new Error("No se pudieron extraer las definiciones de columnas");
1122
+ }
1123
+ const columnsString = columnsMatch[1];
1124
+ const columnDefinitions = columnsString.split(",").map((def) => def.trim());
1125
+ const columns = [];
1126
+ for (const def of columnDefinitions) {
1127
+ if (def.toUpperCase().startsWith("PRIMARY KEY") || def.toUpperCase().startsWith("FOREIGN KEY") || def.toUpperCase().startsWith("CONSTRAINT")) {
1128
+ continue;
1129
+ }
1130
+ const parts = def.split(/\s+/);
1131
+ if (parts.length < 2) continue;
1132
+ const columnName = parts[0];
1133
+ const columnType = parts[1];
1134
+ const column = {
1135
+ name: columnName,
1136
+ type: columnType,
1137
+ nullable: !def.toUpperCase().includes("NOT NULL"),
1138
+ primaryKey: def.toUpperCase().includes("PRIMARY KEY"),
1139
+ autoIncrement: def.toUpperCase().includes("AUTOINCREMENT") || def.toUpperCase().includes("AUTO_INCREMENT")
1140
+ };
1141
+ columns.push(column);
1142
+ }
1143
+ return { tableName: tableName2, columns };
1144
+ }
1145
+ function generateMySQLQueries(nowColumns, oldColumns, tableName2) {
1146
+ const queries = [];
1147
+ for (const [columnName] of oldColumns) {
1148
+ if (!nowColumns.has(columnName)) {
1149
+ queries.push(`ALTER TABLE ${tableName2} DROP COLUMN ${columnName};`);
1150
+ }
1151
+ }
1152
+ for (const [columnName, column] of nowColumns) {
1153
+ const oldColumn = oldColumns.get(columnName);
1154
+ if (!oldColumn) {
1155
+ const columnDef = buildColumnDefinition(column, "mysql");
1156
+ queries.push(`ALTER TABLE ${tableName2} ADD COLUMN ${columnDef};`);
1157
+ } else if (!columnsEqual(column, oldColumn)) {
1158
+ const columnDef = buildColumnDefinition(column, "mysql");
1159
+ queries.push(`ALTER TABLE ${tableName2} MODIFY COLUMN ${columnDef};`);
1160
+ }
1161
+ }
1162
+ return queries;
1163
+ }
1164
+ function generatePostgreSQLQueries(nowColumns, oldColumns, tableName2) {
1165
+ const queries = [];
1166
+ for (const [columnName] of oldColumns) {
1167
+ if (!nowColumns.has(columnName)) {
1168
+ queries.push(`ALTER TABLE ${tableName2} DROP COLUMN ${columnName};`);
1169
+ }
1170
+ }
1171
+ for (const [columnName, column] of nowColumns) {
1172
+ const oldColumn = oldColumns.get(columnName);
1173
+ if (!oldColumn) {
1174
+ const columnDef = buildColumnDefinition(column, "postgres");
1175
+ queries.push(`ALTER TABLE ${tableName2} ADD COLUMN ${columnDef};`);
1176
+ } else if (!columnsEqual(column, oldColumn)) {
1177
+ if (column.type !== oldColumn.type) {
1178
+ const pgType = column.type.replace("INTEGER", "INT").replace("TEXT", "VARCHAR");
1179
+ queries.push(`ALTER TABLE ${tableName2} ALTER COLUMN ${columnName} TYPE ${pgType};`);
1180
+ }
1181
+ if (column.nullable !== oldColumn.nullable) {
1182
+ const constraint = column.nullable ? "DROP NOT NULL" : "SET NOT NULL";
1183
+ queries.push(`ALTER TABLE ${tableName2} ALTER COLUMN ${columnName} ${constraint};`);
1184
+ }
1185
+ }
1186
+ }
1187
+ return queries;
1188
+ }
1189
+ function generateSQLiteQueries(nowSchema, oldSchema, tableName2) {
1190
+ const queries = [];
1191
+ if (schemasEqual(nowSchema, oldSchema)) {
1192
+ return queries;
1193
+ }
1194
+ const tempTableName = `${tableName2}_temp_${Date.now()}`;
1195
+ const createTempQuery = buildCreateTableQuery(nowSchema, "sqlite", tempTableName);
1196
+ queries.push(createTempQuery);
1197
+ const commonColumns = nowSchema.columns.filter((col) => oldSchema.columns.some((oldCol) => oldCol.name.toLowerCase() === col.name.toLowerCase())).map((col) => col.name);
1198
+ if (commonColumns.length > 0) {
1199
+ const columnsList = commonColumns.join(", ");
1200
+ queries.push(`INSERT INTO ${tempTableName} (${columnsList}) SELECT ${columnsList} FROM ${tableName2};`);
1201
+ }
1202
+ queries.push(`DROP TABLE ${tableName2};`);
1203
+ queries.push(`ALTER TABLE ${tempTableName} RENAME TO ${tableName2};`);
1204
+ return queries;
1205
+ }
1206
+ function generateMongoDBQueries(nowColumns, oldColumns, collectionName) {
1207
+ const queries = [];
1208
+ const fieldsToRemove = [];
1209
+ for (const [fieldName] of oldColumns) {
1210
+ if (!nowColumns.has(fieldName)) {
1211
+ fieldsToRemove.push(fieldName);
1212
+ }
1213
+ }
1214
+ if (fieldsToRemove.length > 0) {
1215
+ const unsetFields = fieldsToRemove.reduce((acc, field) => {
1216
+ acc[field] = "";
1217
+ return acc;
1218
+ }, {});
1219
+ queries.push(`db.${collectionName}.updateMany({}, { $unset: ${JSON.stringify(unsetFields)} });`);
1220
+ }
1221
+ const fieldsToAdd = {};
1222
+ for (const [fieldName, column] of nowColumns) {
1223
+ if (!oldColumns.has(fieldName)) {
1224
+ let defaultValue = null;
1225
+ if (!column.nullable) {
1226
+ switch (column.type.toUpperCase()) {
1227
+ case "INTEGER":
1228
+ defaultValue = 0;
1229
+ break;
1230
+ case "TEXT":
1231
+ case "VARCHAR":
1232
+ defaultValue = "";
1233
+ break;
1234
+ default:
1235
+ defaultValue = null;
1236
+ }
1237
+ }
1238
+ fieldsToAdd[fieldName] = defaultValue;
1239
+ }
1240
+ }
1241
+ if (Object.keys(fieldsToAdd).length > 0) {
1242
+ queries.push(`db.${collectionName}.updateMany({}, { $set: ${JSON.stringify(fieldsToAdd)} });`);
1243
+ }
1244
+ return queries;
1245
+ }
1246
+ function buildColumnDefinition(column, dbType2) {
1247
+ let def = `${column.name} ${column.type}`;
1248
+ if (column.primaryKey) {
1249
+ def += " PRIMARY KEY";
1250
+ }
1251
+ if (column.autoIncrement) {
1252
+ if (dbType2 === "mysql") {
1253
+ def += " AUTO_INCREMENT";
1254
+ } else if (dbType2 === "sqlite") {
1255
+ def += " AUTOINCREMENT";
1256
+ } else if (dbType2 === "postgres") {
1257
+ def = def.replace(column.type, "SERIAL");
1258
+ }
1259
+ }
1260
+ if (!column.nullable) {
1261
+ def += " NOT NULL";
1262
+ }
1263
+ return def;
1264
+ }
1265
+ function buildCreateTableQuery(schema, dbType2, tableName2) {
1266
+ const name = tableName2 || schema.tableName;
1267
+ const columnDefs = schema.columns.map((col) => buildColumnDefinition(col, dbType2));
1268
+ return `CREATE TABLE ${name} (${columnDefs.join(", ")});`;
1269
+ }
1270
+ function columnsEqual(col1, col2) {
1271
+ return col1.name.toLowerCase() === col2.name.toLowerCase() && col1.type === col2.type && col1.nullable === col2.nullable && col1.primaryKey === col2.primaryKey && col1.autoIncrement === col2.autoIncrement;
1272
+ }
1273
+ function schemasEqual(schema1, schema2) {
1274
+ if (schema1.columns.length !== schema2.columns.length) {
1275
+ return false;
1276
+ }
1277
+ const cols1 = new Map(schema1.columns.map((col) => [col.name.toLowerCase(), col]));
1278
+ const cols2 = new Map(schema2.columns.map((col) => [col.name.toLowerCase(), col]));
1279
+ for (const [name, col1] of cols1) {
1280
+ const col2 = cols2.get(name);
1281
+ if (!col2 || !columnsEqual(col1, col2)) {
1282
+ return false;
1283
+ }
1284
+ }
1285
+ return true;
1286
+ }
1287
+ if (DbConfig_default.ifExist()) {
1288
+ await DbConfig_default.connect();
1289
+ try {
1290
+ const tableExistsQuery = `SELECT name FROM sqlite_master WHERE type='table' AND name='dbcube_computes_config'`;
1291
+ const tableExistsResult = await DbConfig_default.query(tableExistsQuery);
1292
+ if (tableExistsResult.status === "success" && tableExistsResult.data && tableExistsResult.data.length > 0) {
1293
+ const queryComputes = await DbConfig_default.query(`SELECT * FROM dbcube_schemas_config WHERE table_ref='${tableName}' AND database_ref='${database_ref}'`);
1294
+ const oldQuery = queryComputes.data[0];
1295
+ const nowSchema = parseCreateTableQuery(nowQuery, dbType);
1296
+ const oldSchema = parseCreateTableQuery(oldQuery.struct, dbType);
1297
+ if (nowSchema.tableName.toLowerCase() !== tableName.toLowerCase()) {
1298
+ throw new Error(`El nombre de tabla en la query (${nowSchema.tableName}) no coincide con el par\xE1metro (${tableName})`);
1299
+ }
1300
+ const nowColumns = new Map(nowSchema.columns.map((col) => [col.name.toLowerCase(), col]));
1301
+ const oldColumns = new Map(oldSchema.columns.map((col) => [col.name.toLowerCase(), col]));
1302
+ switch (dbType) {
1303
+ case "mysql":
1304
+ return generateMySQLQueries(nowColumns, oldColumns, tableName);
1305
+ case "postgres":
1306
+ return generatePostgreSQLQueries(nowColumns, oldColumns, tableName);
1307
+ case "sqlite":
1308
+ return generateSQLiteQueries(nowSchema, oldSchema, tableName);
1309
+ case "mongodb":
1310
+ return generateMongoDBQueries(nowColumns, oldColumns, tableName);
1311
+ default:
1312
+ throw new Error(`Tipo de base de datos no soportado: ${dbType}`);
1313
+ }
1314
+ }
1315
+ } catch (error) {
1316
+ console.error("Error fetching computed fields:", error);
1317
+ }
1318
+ await DbConfig_default.disconnect();
1319
+ return [nowQuery];
1320
+ } else {
1321
+ return [nowQuery];
1322
+ }
1323
+ }
1324
+ static async saveQuery(table_ref, database_ref, struct) {
1325
+ if (DbConfig_default.ifExist()) {
1326
+ await DbConfig_default.connect();
1327
+ try {
1328
+ await DbConfig_default.query(`DELETE FROM dbcube_schemas_config WHERE table_ref='${table_ref}' AND database_ref='${database_ref}'`);
1329
+ const tableExistsQuery = `INSERT INTO dbcube_schemas_config (table_ref, database_ref, struct) VALUES (?, ?, ?)`;
1330
+ await DbConfig_default.queryWithParameters(tableExistsQuery, [table_ref, database_ref, struct]);
1331
+ } catch (error) {
1332
+ console.error("Error fetching computed fields:", error);
1333
+ }
1334
+ await DbConfig_default.disconnect();
1335
+ }
1336
+ }
1337
+ };
1338
+ var TriggerProcessor = class {
1339
+ static async getTriggers(name) {
1340
+ let triggers = [];
1341
+ if (DbConfig_default.ifExist()) {
1342
+ await DbConfig_default.connect();
1343
+ try {
1344
+ const tableExistsQuery = `SELECT name FROM sqlite_master WHERE type='table' AND name='dbcube_triggers_config'`;
1345
+ const tableExistsResult = await DbConfig_default.query(tableExistsQuery);
1346
+ if (tableExistsResult.status === "success" && tableExistsResult.data && tableExistsResult.data.length > 0) {
1347
+ const queryComputes = await DbConfig_default.query(`SELECT * FROM dbcube_triggers_config WHERE database_ref='${name}'`);
1348
+ triggers = queryComputes.data;
1349
+ } else {
1350
+ triggers = [];
1351
+ }
1352
+ } catch (error) {
1353
+ console.error("Error fetching computed fields:", error);
1354
+ triggers = [];
1355
+ }
1356
+ await DbConfig_default.disconnect();
1357
+ }
1358
+ return triggers;
1359
+ }
1360
+ };
1361
+ function convertToType(value, type2) {
1362
+ switch (type2) {
1363
+ case "string":
1364
+ return String(value);
1365
+ case "number":
1366
+ const num = Number(value);
1367
+ return isNaN(num) ? 0 : num;
1368
+ case "boolean":
1369
+ return Boolean(value);
1370
+ case "date":
1371
+ return value instanceof Date ? value : new Date(value);
1372
+ case "object":
1373
+ return value;
1374
+ default:
1375
+ return value;
1376
+ }
1377
+ }
1378
+ export {
1379
+ Arquitecture,
1380
+ Binary,
1381
+ ComputedFieldProcessor,
1382
+ Config,
1383
+ DbConfig,
1384
+ Engine,
1385
+ FileLogger,
1386
+ TableProcessor,
1387
+ TriggerProcessor
1388
+ };
1389
+ //# sourceMappingURL=index.js.map