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