@dbcube/core 5.1.13 → 5.2.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 CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/lib/Engine.ts
2
- import path3 from "path";
2
+ import path4 from "path";
3
3
 
4
4
  // src/lib/Arquitecture.ts
5
5
  import * as os from "os";
@@ -345,7 +345,7 @@ var Downloader = class {
345
345
  }
346
346
  this.mainSpinner.text = chalk.blue(`Updating ${binariesToDownload.length} binary(ies)...`);
347
347
  try {
348
- await Promise.all(binariesToDownload.map(async (binary) => {
348
+ const results = await Promise.allSettled(binariesToDownload.map(async (binary) => {
349
349
  const maxRetries = 3;
350
350
  let attempt = 0;
351
351
  while (attempt <= maxRetries) {
@@ -373,6 +373,11 @@ var Downloader = class {
373
373
  }
374
374
  }
375
375
  }));
376
+ const failures = results.filter((r) => r.status === "rejected");
377
+ if (failures.length > 0) {
378
+ const messages = failures.map((f) => f.reason instanceof Error ? f.reason.message : String(f.reason));
379
+ throw new Error(messages.join(" | "));
380
+ }
376
381
  this.mainSpinner.succeed(chalk.green("Binaries updated successfully"));
377
382
  } catch (error) {
378
383
  const errorMessage = error instanceof Error ? error.message : "Unknown error";
@@ -437,8 +442,7 @@ var Downloader = class {
437
442
  }
438
443
  });
439
444
  response.on("end", () => {
440
- file.end();
441
- resolve5();
445
+ file.end(() => resolve5());
442
446
  });
443
447
  response.on("error", (err) => {
444
448
  file.close();
@@ -664,7 +668,6 @@ var Config = class {
664
668
  /**
665
669
  * Obtiene un valor de configuración
666
670
  * @param key - Clave de configuración
667
- * @returns Valor de configuración
668
671
  */
669
672
  get(key) {
670
673
  return this.data[key];
@@ -672,14 +675,12 @@ var Config = class {
672
675
  /**
673
676
  * Obtiene la configuración de una base de datos específica
674
677
  * @param dbName - Nombre de la base de datos
675
- * @returns Configuración de la base de datos o null
676
678
  */
677
679
  getDatabase(dbName) {
678
680
  return this.databases[dbName] || null;
679
681
  }
680
682
  /**
681
683
  * Obtiene todas las bases de datos configuradas
682
- * @returns Todas las configuraciones de bases de datos
683
684
  */
684
685
  getAllDatabases() {
685
686
  return this.databases;
@@ -687,14 +688,258 @@ var Config = class {
687
688
  };
688
689
 
689
690
  // src/lib/Engine.ts
690
- import { spawn } from "child_process";
691
+ import { spawn as spawn2 } from "child_process";
691
692
  import { createRequire } from "module";
693
+
694
+ // src/lib/DaemonClient.ts
695
+ import net from "net";
696
+ import fs3 from "fs";
697
+ import path3 from "path";
698
+ import { spawn } from "child_process";
699
+ var DaemonClient = class _DaemonClient {
700
+ static registry = /* @__PURE__ */ new Map();
701
+ name;
702
+ binaryPath;
703
+ engineArgs;
704
+ socket = null;
705
+ buffer = "";
706
+ pending = [];
707
+ starting = null;
708
+ requestTimeout;
709
+ constructor(name, binaryPath, engineArgs, requestTimeout = 3e4) {
710
+ this.name = name;
711
+ this.binaryPath = binaryPath;
712
+ this.engineArgs = engineArgs;
713
+ this.requestTimeout = requestTimeout;
714
+ }
715
+ static get(name, binaryPath, engineArgs) {
716
+ let client = this.registry.get(name);
717
+ if (!client) {
718
+ client = new _DaemonClient(name, binaryPath, engineArgs);
719
+ this.registry.set(name, client);
720
+ }
721
+ return client;
722
+ }
723
+ static isEnabled() {
724
+ const flag = process.env.DBCUBE_DAEMON;
725
+ if (flag === "0" || flag === "false") return false;
726
+ return true;
727
+ }
728
+ portfilePath() {
729
+ return path3.join(process.cwd(), ".dbcube", "daemon", `${this.name}.json`);
730
+ }
731
+ lockfilePath() {
732
+ return path3.join(process.cwd(), ".dbcube", "daemon", `${this.name}.lock`);
733
+ }
734
+ /**
735
+ * Exclusive-create lock so two processes never spawn two daemons for the
736
+ * same database at once. Stale locks (crashed starter) expire after 15s.
737
+ */
738
+ acquireSpawnLock() {
739
+ const lockPath = this.lockfilePath();
740
+ try {
741
+ fs3.mkdirSync(path3.dirname(lockPath), { recursive: true });
742
+ const fd = fs3.openSync(lockPath, "wx");
743
+ fs3.writeSync(fd, String(process.pid));
744
+ fs3.closeSync(fd);
745
+ return true;
746
+ } catch {
747
+ try {
748
+ const age = Date.now() - fs3.statSync(lockPath).mtimeMs;
749
+ if (age > 15e3) {
750
+ fs3.unlinkSync(lockPath);
751
+ return this.acquireSpawnLock();
752
+ }
753
+ } catch {
754
+ }
755
+ return false;
756
+ }
757
+ }
758
+ releaseSpawnLock() {
759
+ try {
760
+ fs3.unlinkSync(this.lockfilePath());
761
+ } catch {
762
+ }
763
+ }
764
+ /**
765
+ * Ensures a usable daemon connection. Returns false when the daemon
766
+ * can't be used (old binary, startup failure) so callers fall back
767
+ * to one-shot spawn mode.
768
+ */
769
+ async ensure() {
770
+ if (this.socket && !this.socket.destroyed) return true;
771
+ if (this.starting) return this.starting;
772
+ this.starting = this.connectOrStart().catch(() => false);
773
+ const result = await this.starting;
774
+ this.starting = null;
775
+ return result;
776
+ }
777
+ async connectOrStart() {
778
+ const port = this.readPortfile();
779
+ if (port && await this.tryConnect(port)) return true;
780
+ const gotLock = this.acquireSpawnLock();
781
+ try {
782
+ if (gotLock) {
783
+ try {
784
+ fs3.unlinkSync(this.portfilePath());
785
+ } catch {
786
+ }
787
+ this.spawnDaemon();
788
+ }
789
+ const deadline = Date.now() + 1e4;
790
+ while (Date.now() < deadline) {
791
+ await new Promise((r) => setTimeout(r, 150));
792
+ const newPort = this.readPortfile();
793
+ if (newPort && await this.tryConnect(newPort)) return true;
794
+ }
795
+ return false;
796
+ } finally {
797
+ if (gotLock) this.releaseSpawnLock();
798
+ }
799
+ }
800
+ readPortfile() {
801
+ try {
802
+ const raw = fs3.readFileSync(this.portfilePath(), "utf8");
803
+ const info = JSON.parse(raw);
804
+ const port = info?.port;
805
+ return Number.isInteger(port) && port > 0 && port <= 65535 ? port : null;
806
+ } catch {
807
+ return null;
808
+ }
809
+ }
810
+ spawnDaemon() {
811
+ const child = spawn(this.binaryPath, [...this.engineArgs, "--action", "server", "--tcp-port", "9944"], {
812
+ detached: true,
813
+ stdio: "ignore",
814
+ cwd: process.cwd()
815
+ });
816
+ child.unref();
817
+ }
818
+ tryConnect(port) {
819
+ return new Promise((resolve5) => {
820
+ const socket = net.createConnection({ host: "127.0.0.1", port }, async () => {
821
+ socket.setNoDelay(true);
822
+ this.attach(socket);
823
+ try {
824
+ const pong = await this.send({ action: "ping" }, 2e3);
825
+ resolve5(pong.status === 200);
826
+ } catch {
827
+ this.detach();
828
+ resolve5(false);
829
+ }
830
+ });
831
+ socket.once("error", () => resolve5(false));
832
+ socket.setTimeout(3e3, () => {
833
+ socket.destroy();
834
+ resolve5(false);
835
+ });
836
+ });
837
+ }
838
+ attach(socket) {
839
+ this.socket = socket;
840
+ this.buffer = "";
841
+ socket.setTimeout(0);
842
+ socket.on("data", (chunk) => this.onData(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)));
843
+ socket.on("close", () => this.detach());
844
+ socket.on("error", () => this.detach());
845
+ }
846
+ detach() {
847
+ if (this.socket) {
848
+ this.socket.removeAllListeners();
849
+ this.socket.destroy();
850
+ this.socket = null;
851
+ }
852
+ for (const req of this.pending.splice(0)) {
853
+ clearTimeout(req.timer);
854
+ req.reject(new Error("Daemon connection lost"));
855
+ }
856
+ }
857
+ onData(chunk) {
858
+ this.buffer += chunk.toString("utf8");
859
+ let idx;
860
+ while ((idx = this.buffer.indexOf("\n")) !== -1) {
861
+ const line = this.buffer.slice(0, idx).trim();
862
+ this.buffer = this.buffer.slice(idx + 1);
863
+ if (!line) continue;
864
+ const marker = line.indexOf("PROCESS_RESPONSE:");
865
+ if (marker === -1) continue;
866
+ const jsonPart = line.slice(marker + "PROCESS_RESPONSE:".length);
867
+ const req = this.pending.shift();
868
+ if (!req) continue;
869
+ clearTimeout(req.timer);
870
+ try {
871
+ req.resolve(JSON.parse(jsonPart));
872
+ } catch (e) {
873
+ req.reject(new Error(`Invalid daemon response: ${e.message}`));
874
+ }
875
+ }
876
+ }
877
+ /**
878
+ * Sends a request to the daemon. Responses arrive in FIFO order on the
879
+ * single socket, so pending requests resolve in send order.
880
+ */
881
+ send(payload, timeoutMs) {
882
+ return new Promise((resolve5, reject) => {
883
+ if (!this.socket || this.socket.destroyed) {
884
+ reject(new Error("Daemon not connected"));
885
+ return;
886
+ }
887
+ const timer = setTimeout(() => {
888
+ const i = this.pending.findIndex((p) => p.timer === timer);
889
+ if (i !== -1) this.pending.splice(i, 1);
890
+ reject(new Error("Daemon request timeout"));
891
+ this.detach();
892
+ }, timeoutMs ?? this.requestTimeout);
893
+ this.pending.push({ resolve: resolve5, reject, timer });
894
+ this.socket.write(JSON.stringify(payload) + "\n");
895
+ });
896
+ }
897
+ async execute(dml, txId) {
898
+ const payload = { action: "execute", dml: JSON.stringify(dml) };
899
+ if (txId) payload.tx_id = txId;
900
+ return this.send(payload);
901
+ }
902
+ async raw(query, params = [], txId) {
903
+ const payload = { action: "raw", query, params };
904
+ if (txId) payload.tx_id = txId;
905
+ return this.send(payload);
906
+ }
907
+ async begin() {
908
+ const res = await this.send({ action: "begin" });
909
+ if (res.status !== 200 || !res.data?.tx_id) {
910
+ throw new Error(res.message || "Failed to begin transaction");
911
+ }
912
+ return res.data.tx_id;
913
+ }
914
+ async commit(txId) {
915
+ const res = await this.send({ action: "commit", tx_id: txId });
916
+ if (res.status !== 200) throw new Error(res.message || "Failed to commit transaction");
917
+ }
918
+ async rollback(txId) {
919
+ const res = await this.send({ action: "rollback", tx_id: txId });
920
+ if (res.status !== 200) throw new Error(res.message || "Failed to rollback transaction");
921
+ }
922
+ async shutdown() {
923
+ try {
924
+ await this.send({ action: "shutdown" });
925
+ } catch {
926
+ }
927
+ this.detach();
928
+ try {
929
+ fs3.unlinkSync(this.portfilePath());
930
+ } catch {
931
+ }
932
+ }
933
+ };
934
+
935
+ // src/lib/Engine.ts
692
936
  var Engine = class {
693
937
  name;
694
938
  config;
695
939
  arguments;
696
940
  binary = null;
697
941
  timeout;
942
+ daemonFailed = false;
698
943
  constructor(name, timeout = 3e4) {
699
944
  this.name = name;
700
945
  this.config = this.setConfig(name);
@@ -706,6 +951,77 @@ var Engine = class {
706
951
  this.binary = await Binary.get();
707
952
  }
708
953
  }
954
+ /**
955
+ * Returns a connected DaemonClient for this database, or null when
956
+ * daemon mode is disabled/unavailable (then callers use spawn mode).
957
+ */
958
+ async getDaemon() {
959
+ if (this.daemonFailed || !DaemonClient.isEnabled()) return null;
960
+ await this.initializeBinary();
961
+ if (!this.binary) return null;
962
+ const binaryPath = this.binary["query_engine"];
963
+ if (!binaryPath) return null;
964
+ const client = DaemonClient.get(this.name, binaryPath, this.arguments);
965
+ const ok = await client.ensure();
966
+ if (!ok) {
967
+ this.daemonFailed = true;
968
+ return null;
969
+ }
970
+ return client;
971
+ }
972
+ /**
973
+ * Executes a DML plan. Uses the persistent daemon (sub-millisecond
974
+ * overhead) when available; falls back to one-shot spawn otherwise.
975
+ */
976
+ async executeDml(dml, txId) {
977
+ const daemon = await this.getDaemon();
978
+ if (daemon) {
979
+ try {
980
+ return await daemon.execute(dml, txId);
981
+ } catch (error) {
982
+ if (txId) throw error;
983
+ }
984
+ }
985
+ if (txId) {
986
+ throw new Error("Transactions require daemon mode. Make sure the query-engine binary is up to date (npx dbcube update).");
987
+ }
988
+ return this.run("query_engine", ["--action", "execute", "--dml", JSON.stringify(dml)]);
989
+ }
990
+ /**
991
+ * Executes raw SQL (or a MongoDB command document) with bound parameters.
992
+ */
993
+ async rawQuery(query, params = [], txId) {
994
+ const daemon = await this.getDaemon();
995
+ if (daemon) {
996
+ try {
997
+ return await daemon.raw(query, params, txId);
998
+ } catch (error) {
999
+ if (txId) throw error;
1000
+ }
1001
+ }
1002
+ if (txId) {
1003
+ throw new Error("Transactions require daemon mode. Make sure the query-engine binary is up to date (npx dbcube update).");
1004
+ }
1005
+ return this.run("query_engine", ["--action", "raw", "--query", query, "--params", JSON.stringify(params)]);
1006
+ }
1007
+ /** Starts a transaction (daemon mode only). Returns the transaction id. */
1008
+ async beginTransaction() {
1009
+ const daemon = await this.getDaemon();
1010
+ if (!daemon) {
1011
+ throw new Error("Transactions require daemon mode. Make sure the query-engine binary is up to date (npx dbcube update).");
1012
+ }
1013
+ return daemon.begin();
1014
+ }
1015
+ async commitTransaction(txId) {
1016
+ const daemon = await this.getDaemon();
1017
+ if (!daemon) throw new Error("Daemon connection lost during transaction");
1018
+ return daemon.commit(txId);
1019
+ }
1020
+ async rollbackTransaction(txId) {
1021
+ const daemon = await this.getDaemon();
1022
+ if (!daemon) throw new Error("Daemon connection lost during transaction");
1023
+ return daemon.rollback(txId);
1024
+ }
709
1025
  setArguments() {
710
1026
  let args = [];
711
1027
  if (this.config.type == "sqlite") {
@@ -730,21 +1046,23 @@ var Engine = class {
730
1046
  "--host",
731
1047
  this.config.config.HOST,
732
1048
  "--port",
733
- this.config.config.PORT,
734
- "--user",
735
- this.config.config.USER,
736
- "--password",
737
- this.config.config.PASSWORD,
1049
+ String(this.config.config.PORT),
738
1050
  "--motor",
739
1051
  this.config.type
740
1052
  ];
1053
+ if (this.config.config.USER != null && this.config.config.USER !== "") {
1054
+ args.push("--user", this.config.config.USER);
1055
+ }
1056
+ if (this.config.config.PASSWORD != null && this.config.config.PASSWORD !== "") {
1057
+ args.push("--password", this.config.config.PASSWORD);
1058
+ }
741
1059
  }
742
1060
  return args;
743
1061
  }
744
1062
  setConfig(name) {
745
1063
  const configInstance = new Config();
746
1064
  try {
747
- const configFilePath = path3.resolve(process.cwd(), "dbcube.config.js");
1065
+ const configFilePath = path4.resolve(process.cwd(), "dbcube.config.js");
748
1066
  const requireUrl = typeof __filename !== "undefined" ? __filename : process.cwd();
749
1067
  const require2 = createRequire(requireUrl);
750
1068
  if (require2.cache && require2.resolve) {
@@ -777,7 +1095,7 @@ var Engine = class {
777
1095
  throw new Error("Binary not initialized");
778
1096
  }
779
1097
  return new Promise((resolve5, reject) => {
780
- const child = spawn(this.binary[binary], [...this.arguments, ...args]);
1098
+ const child = spawn2(this.binary[binary], [...this.arguments, ...args]);
781
1099
  let stdoutBuffer = "";
782
1100
  let stderrBuffer = "";
783
1101
  let isResolved = false;
@@ -796,8 +1114,10 @@ var Engine = class {
796
1114
  }
797
1115
  };
798
1116
  child.stdout.on("data", (data) => {
799
- stdoutBuffer += data.toString();
800
- console.log(stdoutBuffer);
1117
+ const text = data.toString();
1118
+ stdoutBuffer += text;
1119
+ const visible = text.split("\n").filter((l) => l.trim() && !l.includes("PROCESS_RESPONSE:")).join("\n");
1120
+ if (visible) console.log(visible);
801
1121
  const match = stdoutBuffer.match(/PROCESS_RESPONSE:(\{.*\})/);
802
1122
  if (match) {
803
1123
  try {
@@ -817,8 +1137,10 @@ var Engine = class {
817
1137
  }
818
1138
  });
819
1139
  child.stderr.on("data", (data) => {
820
- stderrBuffer += data.toString();
821
- console.log(stderrBuffer);
1140
+ const text = data.toString();
1141
+ stderrBuffer += text;
1142
+ const visible = text.split("\n").filter((l) => l.trim() && !l.includes("PROCESS_RESPONSE:")).join("\n");
1143
+ if (visible) console.log(visible);
822
1144
  const match = stderrBuffer.match(/PROCESS_RESPONSE:(\{.*\})/);
823
1145
  if (match) {
824
1146
  try {
@@ -863,16 +1185,15 @@ var Engine = class {
863
1185
  };
864
1186
 
865
1187
  // src/lib/QueryEngine.ts
866
- import path4 from "path";
1188
+ import path5 from "path";
867
1189
  import { createRequire as createRequire2 } from "module";
868
- import * as net from "net";
869
- import { spawn as spawn2 } from "child_process";
1190
+ import * as net2 from "net";
1191
+ import { spawn as spawn3 } from "child_process";
870
1192
  var globalTcpServers = /* @__PURE__ */ new Map();
871
1193
  var globalTcpConnections = /* @__PURE__ */ new Map();
872
1194
  var connectionQueues = /* @__PURE__ */ new Map();
873
1195
  var connectionProcessing = /* @__PURE__ */ new Map();
874
1196
  var queryCache = /* @__PURE__ */ new Map();
875
- var cacheSize = 0;
876
1197
  var MAX_CACHE_SIZE = 500;
877
1198
  var QueryEngine = class {
878
1199
  name;
@@ -886,7 +1207,7 @@ var QueryEngine = class {
886
1207
  this.name = name;
887
1208
  this.config = this.setConfig(name);
888
1209
  this.arguments = this.setArguments();
889
- this.timeout = timeout;
1210
+ this.timeout = this.config?.daemon?.requestTimeoutMs ?? timeout;
890
1211
  this.connectionId = `${name}_query_engine_${this.config.type}_${this.config.config.DATABASE}_${this.config.config.HOST || "localhost"}`;
891
1212
  this.tcpPort = this.generatePort();
892
1213
  }
@@ -903,7 +1224,7 @@ var QueryEngine = class {
903
1224
  }
904
1225
  isPortAvailable(port) {
905
1226
  return new Promise((resolve5) => {
906
- const tester = net.createServer();
1227
+ const tester = net2.createServer();
907
1228
  tester.once("error", () => resolve5(false));
908
1229
  tester.once("listening", () => {
909
1230
  tester.close();
@@ -941,21 +1262,34 @@ var QueryEngine = class {
941
1262
  "--host",
942
1263
  this.config.config.HOST,
943
1264
  "--port",
944
- this.config.config.PORT,
945
- "--user",
946
- this.config.config.USER,
947
- "--password",
948
- this.config.config.PASSWORD,
1265
+ String(this.config.config.PORT),
949
1266
  "--motor",
950
1267
  this.config.type
951
1268
  ];
1269
+ if (this.config.config.USER != null && this.config.config.USER !== "") {
1270
+ args.push("--user", this.config.config.USER);
1271
+ }
1272
+ if (this.config.config.PASSWORD != null && this.config.config.PASSWORD !== "") {
1273
+ args.push("--password", this.config.config.PASSWORD);
1274
+ }
952
1275
  }
1276
+ const pool = this.config.pool ?? {};
1277
+ if (pool.maxConnections != null) args.push("--max-connections", String(pool.maxConnections));
1278
+ if (pool.minConnections != null) args.push("--min-connections", String(pool.minConnections));
1279
+ if (pool.acquireTimeoutMs != null) args.push("--acquire-timeout-ms", String(pool.acquireTimeoutMs));
1280
+ if (pool.idleTimeoutMs != null) args.push("--idle-timeout-ms", String(pool.idleTimeoutMs));
953
1281
  return args;
954
1282
  }
1283
+ /** El daemon puede desactivarse por config (daemon.enabled=false) o por env (DBCUBE_DAEMON=0). */
1284
+ daemonEnabled() {
1285
+ const flag = process.env.DBCUBE_DAEMON;
1286
+ if (flag === "0" || flag === "false") return false;
1287
+ return this.config?.daemon?.enabled !== false;
1288
+ }
955
1289
  setConfig(name) {
956
1290
  const configInstance = new Config();
957
1291
  try {
958
- const configFilePath = path4.resolve(process.cwd(), "dbcube.config.js");
1292
+ const configFilePath = path5.resolve(process.cwd(), "dbcube.config.js");
959
1293
  const requireUrl = typeof __filename !== "undefined" ? __filename : process.cwd();
960
1294
  const require2 = createRequire2(requireUrl);
961
1295
  if (require2.cache && require2.resolve) {
@@ -987,18 +1321,71 @@ var QueryEngine = class {
987
1321
  const isExecuteAction = actionIndex !== -1 && args[actionIndex + 1] === "execute";
988
1322
  const isQueryEngine = binary === "query_engine";
989
1323
  if (isQueryEngine && isExecuteAction) {
990
- return this.executeWithTcpServer(args);
1324
+ return this.executeWithTcpServer(this.argsToCommand(args));
991
1325
  } else {
992
1326
  return this.createProcess(binary, args);
993
1327
  }
994
1328
  }
995
- async executeWithTcpServer(args) {
1329
+ argsToCommand(args) {
1330
+ const command = {};
1331
+ for (let i = 0; i < args.length; i += 2) {
1332
+ if (args[i].startsWith("--")) {
1333
+ command[args[i].substring(2)] = args[i + 1];
1334
+ }
1335
+ }
1336
+ return command;
1337
+ }
1338
+ /**
1339
+ * Executes a DML plan over the persistent TCP server.
1340
+ * Pass txId to run it inside an active transaction.
1341
+ */
1342
+ async executeDml(dml, txId) {
1343
+ const command = { action: "execute", dml: JSON.stringify(dml) };
1344
+ if (txId) command.tx_id = txId;
1345
+ return this.executeWithTcpServer(command);
1346
+ }
1347
+ /**
1348
+ * Executes raw SQL (or a MongoDB command document) with bound parameters
1349
+ * over the persistent TCP server.
1350
+ */
1351
+ async rawQuery(query, params = [], txId) {
1352
+ const command = { action: "raw", query, params };
1353
+ if (txId) command.tx_id = txId;
1354
+ return this.executeWithTcpServer(command);
1355
+ }
1356
+ /** Starts a server-side transaction and returns its id. */
1357
+ async beginTransaction() {
1358
+ const res = await this.executeWithTcpServer({ action: "begin" });
1359
+ if (res.status !== 200 || !res.data?.tx_id) {
1360
+ throw new Error(String(res.message || "Failed to begin transaction (update the query-engine binary: npx dbcube update)"));
1361
+ }
1362
+ return res.data.tx_id;
1363
+ }
1364
+ async commitTransaction(txId) {
1365
+ const res = await this.executeWithTcpServer({ action: "commit", tx_id: txId });
1366
+ if (res.status !== 200) throw new Error(String(res.message || "Failed to commit transaction"));
1367
+ }
1368
+ async rollbackTransaction(txId) {
1369
+ const res = await this.executeWithTcpServer({ action: "rollback", tx_id: txId });
1370
+ if (res.status !== 200) throw new Error(String(res.message || "Failed to rollback transaction"));
1371
+ }
1372
+ async executeWithTcpServer(command) {
1373
+ if (!this.daemonEnabled()) {
1374
+ if (command.tx_id || ["begin", "commit", "rollback"].includes(command.action)) {
1375
+ throw new Error("Transactions require daemon mode. Remove daemon.enabled=false from dbcube.config.js (or unset DBCUBE_DAEMON=0).");
1376
+ }
1377
+ const args = [];
1378
+ for (const [key, value] of Object.entries(command)) {
1379
+ args.push(`--${key.replace(/_/g, "-")}`, typeof value === "string" ? value : JSON.stringify(value));
1380
+ }
1381
+ return this.createProcess("query_engine", args);
1382
+ }
996
1383
  const serverInfo = globalTcpServers.get(this.connectionId);
997
1384
  if (!serverInfo || !serverInfo.process || serverInfo.process.killed) {
998
1385
  await this.startTcpServer();
999
1386
  await this.waitForServerReady();
1000
1387
  }
1001
- return this.sendTcpRequestFast(args);
1388
+ return this.sendTcpRequestFast(command);
1002
1389
  }
1003
1390
  async waitForServerReady() {
1004
1391
  const maxRetries = 10;
@@ -1017,7 +1404,7 @@ var QueryEngine = class {
1017
1404
  }
1018
1405
  async isServerResponding(port) {
1019
1406
  return new Promise((resolve5) => {
1020
- const client = new net.Socket();
1407
+ const client = new net2.Socket();
1021
1408
  const timeout = setTimeout(() => {
1022
1409
  client.destroy();
1023
1410
  resolve5(false);
@@ -1041,10 +1428,11 @@ var QueryEngine = class {
1041
1428
  return queryCache.get(dmlJson);
1042
1429
  }
1043
1430
  const parsed = JSON.parse(dmlJson);
1044
- if (cacheSize < MAX_CACHE_SIZE) {
1045
- queryCache.set(dmlJson, parsed);
1046
- cacheSize++;
1431
+ if (queryCache.size >= MAX_CACHE_SIZE) {
1432
+ const oldest = queryCache.keys().next().value;
1433
+ if (oldest !== void 0) queryCache.delete(oldest);
1047
1434
  }
1435
+ queryCache.set(dmlJson, parsed);
1048
1436
  return parsed;
1049
1437
  }
1050
1438
  async startTcpServer() {
@@ -1055,7 +1443,7 @@ var QueryEngine = class {
1055
1443
  this.tcpPort = await this.findAvailablePort(this.tcpPort);
1056
1444
  return new Promise((resolve5, reject) => {
1057
1445
  const serverArgs = [...this.arguments, "--action", "server", "--tcp-port", this.tcpPort.toString()];
1058
- const serverProcess = spawn2(this.binary["query_engine"], serverArgs);
1446
+ const serverProcess = spawn3(this.binary["query_engine"], serverArgs);
1059
1447
  let started = false;
1060
1448
  const timeout = setTimeout(() => {
1061
1449
  if (!started) {
@@ -1091,14 +1479,14 @@ var QueryEngine = class {
1091
1479
  });
1092
1480
  });
1093
1481
  }
1094
- async sendTcpRequestFast(args) {
1482
+ async sendTcpRequestFast(command) {
1095
1483
  return new Promise((resolve5, reject) => {
1096
1484
  let queue = connectionQueues.get(this.connectionId);
1097
1485
  if (!queue) {
1098
1486
  queue = [];
1099
1487
  connectionQueues.set(this.connectionId, queue);
1100
1488
  }
1101
- queue.push({ args, resolve: resolve5, reject });
1489
+ queue.push({ command, resolve: resolve5, reject });
1102
1490
  this.processQueue();
1103
1491
  });
1104
1492
  }
@@ -1125,9 +1513,16 @@ var QueryEngine = class {
1125
1513
  connection = await this.createNewConnection(serverInfo.port);
1126
1514
  globalTcpConnections.set(this.connectionId, connection);
1127
1515
  }
1128
- const result = await this.executeOnConnection(connection, request.args);
1516
+ const result = await this.executeOnConnection(connection, request.command);
1129
1517
  request.resolve(result);
1130
1518
  } catch (error) {
1519
+ const staleConnection = globalTcpConnections.get(this.connectionId);
1520
+ if (staleConnection) {
1521
+ try {
1522
+ staleConnection.destroy();
1523
+ } catch {
1524
+ }
1525
+ }
1131
1526
  globalTcpConnections.delete(this.connectionId);
1132
1527
  request.reject(error);
1133
1528
  }
@@ -1138,7 +1533,7 @@ var QueryEngine = class {
1138
1533
  }
1139
1534
  async createNewConnection(port) {
1140
1535
  return new Promise((resolve5, reject) => {
1141
- const client = new net.Socket();
1536
+ const client = new net2.Socket();
1142
1537
  client.setNoDelay(true);
1143
1538
  client.setKeepAlive(true, 6e4);
1144
1539
  const timeout = setTimeout(() => {
@@ -1155,16 +1550,8 @@ var QueryEngine = class {
1155
1550
  });
1156
1551
  });
1157
1552
  }
1158
- async executeOnConnection(connection, args) {
1553
+ async executeOnConnection(connection, command) {
1159
1554
  return new Promise((resolve5, reject) => {
1160
- const command = {};
1161
- for (let i = 0; i < args.length; i += 2) {
1162
- if (args[i].startsWith("--")) {
1163
- const key = args[i].substring(2);
1164
- const value = args[i + 1];
1165
- command[key] = value;
1166
- }
1167
- }
1168
1555
  let responseBuffer = "";
1169
1556
  let isResolved = false;
1170
1557
  const timeout = setTimeout(() => {
@@ -1206,7 +1593,7 @@ var QueryEngine = class {
1206
1593
  };
1207
1594
  connection.on("data", onData);
1208
1595
  connection.on("error", onError);
1209
- connection.write(JSON.stringify(command));
1596
+ connection.write(JSON.stringify(command) + "\n");
1210
1597
  });
1211
1598
  }
1212
1599
  async createProcess(binary, args) {
@@ -1215,7 +1602,7 @@ var QueryEngine = class {
1215
1602
  throw new Error("Binary not initialized");
1216
1603
  }
1217
1604
  return new Promise((resolve5, reject) => {
1218
- const child = spawn2(this.binary[binary], [...this.arguments, ...args]);
1605
+ const child = spawn3(this.binary[binary], [...this.arguments, ...args]);
1219
1606
  let stdoutBuffer = "";
1220
1607
  let stderrBuffer = "";
1221
1608
  let isResolved = false;
@@ -1323,8 +1710,8 @@ var QueryEngine = class {
1323
1710
 
1324
1711
  // src/lib/SqliteExecutor.ts
1325
1712
  import { exec } from "child_process";
1326
- import * as path5 from "path";
1327
- import * as fs3 from "fs";
1713
+ import * as path6 from "path";
1714
+ import * as fs4 from "fs";
1328
1715
  import { promisify } from "util";
1329
1716
  import { createRequire as createRequire3 } from "module";
1330
1717
  import { fileURLToPath as fileURLToPath3 } from "url";
@@ -1339,13 +1726,13 @@ var SqliteExecutor = class {
1339
1726
  }
1340
1727
  findVersionedBinary(binDir, platform2) {
1341
1728
  try {
1342
- const files = fs3.readdirSync(binDir);
1729
+ const files = fs4.readdirSync(binDir);
1343
1730
  const extension = platform2 === "win32" ? ".exe" : "";
1344
1731
  const platformName = platform2 === "win32" ? "windows" : platform2 === "darwin" ? "macos" : "linux";
1345
1732
  const pattern = new RegExp(`^sqlite-engine-v\\d+\\.\\d+\\.\\d+-${platformName}-x64${extension.replace(".", "\\.")}$`);
1346
1733
  const matchingFile = files.find((f) => pattern.test(f));
1347
1734
  if (matchingFile) {
1348
- return path5.join(binDir, matchingFile);
1735
+ return path6.join(binDir, matchingFile);
1349
1736
  }
1350
1737
  } catch (error) {
1351
1738
  }
@@ -1355,34 +1742,34 @@ var SqliteExecutor = class {
1355
1742
  const __filename2 = typeof import.meta !== "undefined" && import.meta.url ? fileURLToPath3(import.meta.url) : "";
1356
1743
  const __dirname = __filename2 ? dirname3(__filename2) : process.cwd();
1357
1744
  const possibleDirs = [
1358
- path5.resolve(process.cwd(), ".dbcube", "bin"),
1359
- path5.resolve(process.cwd(), "node_modules", ".dbcube", "bin"),
1360
- path5.resolve(__dirname, "..", "bin")
1745
+ path6.resolve(process.cwd(), ".dbcube", "bin"),
1746
+ path6.resolve(process.cwd(), "node_modules", ".dbcube", "bin"),
1747
+ path6.resolve(__dirname, "..", "bin")
1361
1748
  ];
1362
1749
  const platform2 = process.platform;
1363
1750
  const extension = platform2 === "win32" ? ".exe" : "";
1364
1751
  const platformName = platform2 === "win32" ? "windows" : platform2 === "darwin" ? "macos" : "linux";
1365
1752
  for (const dir of possibleDirs) {
1366
1753
  const versionedPath = this.findVersionedBinary(dir, platform2);
1367
- if (versionedPath && fs3.existsSync(versionedPath)) {
1754
+ if (versionedPath && fs4.existsSync(versionedPath)) {
1368
1755
  return versionedPath;
1369
1756
  }
1370
1757
  }
1371
1758
  const binaryName = `sqlite-engine-${platformName}-x64${extension}`;
1372
1759
  for (const dir of possibleDirs) {
1373
- const fullPath = path5.join(dir, binaryName);
1374
- if (fs3.existsSync(fullPath)) {
1760
+ const fullPath = path6.join(dir, binaryName);
1761
+ if (fs4.existsSync(fullPath)) {
1375
1762
  return fullPath;
1376
1763
  }
1377
1764
  }
1378
1765
  const fallbackName = `sqlite-engine${extension}`;
1379
1766
  for (const dir of possibleDirs) {
1380
- const fullPath = path5.join(dir, fallbackName);
1381
- if (fs3.existsSync(fullPath)) {
1767
+ const fullPath = path6.join(dir, fallbackName);
1768
+ if (fs4.existsSync(fullPath)) {
1382
1769
  return fullPath;
1383
1770
  }
1384
1771
  }
1385
- return path5.join(possibleDirs[0], binaryName);
1772
+ return path6.join(possibleDirs[0], binaryName);
1386
1773
  }
1387
1774
  async executeBinary(args) {
1388
1775
  const escapedArgs = args.map((arg) => {
@@ -1533,9 +1920,9 @@ var SqliteExecutor = class {
1533
1920
  };
1534
1921
 
1535
1922
  // src/lib/DbConfig.ts
1536
- import * as path6 from "path";
1537
- import fs4 from "fs";
1538
- var rootPath = path6.resolve(process.cwd(), ".dbcube");
1923
+ import * as path7 from "path";
1924
+ import fs5 from "fs";
1925
+ var rootPath = path7.resolve(process.cwd(), ".dbcube");
1539
1926
  var SQLite = class {
1540
1927
  executor = null;
1541
1928
  database;
@@ -1545,11 +1932,11 @@ var SQLite = class {
1545
1932
  async ifExist() {
1546
1933
  if (this.database) {
1547
1934
  const dbPath = this.database || ":memory:";
1548
- const configPath = path6.join(rootPath, dbPath + ".db");
1549
- if (!fs4.existsSync(rootPath)) {
1550
- fs4.mkdirSync(rootPath, { recursive: true });
1935
+ const configPath = path7.join(rootPath, dbPath + ".db");
1936
+ if (!fs5.existsSync(rootPath)) {
1937
+ fs5.mkdirSync(rootPath, { recursive: true });
1551
1938
  }
1552
- if (fs4.existsSync(configPath)) {
1939
+ if (fs5.existsSync(configPath)) {
1553
1940
  return true;
1554
1941
  }
1555
1942
  if (!this.executor) {
@@ -1564,9 +1951,9 @@ var SQLite = class {
1564
1951
  try {
1565
1952
  if (!this.executor) {
1566
1953
  const dbPath = this.database || ":memory:";
1567
- const configPath = path6.join(rootPath, dbPath + ".db");
1568
- if (!fs4.existsSync(rootPath)) {
1569
- fs4.mkdirSync(rootPath, { recursive: true });
1954
+ const configPath = path7.join(rootPath, dbPath + ".db");
1955
+ if (!fs5.existsSync(rootPath)) {
1956
+ fs5.mkdirSync(rootPath, { recursive: true });
1570
1957
  }
1571
1958
  this.executor = new SqliteExecutor(configPath);
1572
1959
  const connected = await this.executor.connect();
@@ -1748,8 +2135,8 @@ var DbConfig = new SQLite({ DATABASE: "config" });
1748
2135
  var DbConfig_default = DbConfig;
1749
2136
 
1750
2137
  // src/lib/FileLogger.ts
1751
- import * as fs5 from "fs";
1752
- import * as path7 from "path";
2138
+ import * as fs6 from "fs";
2139
+ import * as path8 from "path";
1753
2140
  import { EventEmitter } from "events";
1754
2141
  var FileLogger = class _FileLogger extends EventEmitter {
1755
2142
  static watchers = /* @__PURE__ */ new Map();
@@ -1764,9 +2151,9 @@ var FileLogger = class _FileLogger extends EventEmitter {
1764
2151
  */
1765
2152
  static async write(filePath, message, level = "INFO", append = true) {
1766
2153
  try {
1767
- const dir = path7.dirname(filePath);
1768
- if (!fs5.existsSync(dir)) {
1769
- fs5.mkdirSync(dir, { recursive: true });
2154
+ const dir = path8.dirname(filePath);
2155
+ if (!fs6.existsSync(dir)) {
2156
+ fs6.mkdirSync(dir, { recursive: true });
1770
2157
  }
1771
2158
  const timestamp = (/* @__PURE__ */ new Date()).toISOString();
1772
2159
  const formattedMessage = `[${timestamp}] [${level}] ${message}
@@ -1776,9 +2163,9 @@ var FileLogger = class _FileLogger extends EventEmitter {
1776
2163
  return true;
1777
2164
  }
1778
2165
  if (append) {
1779
- await fs5.promises.appendFile(filePath, formattedMessage, "utf8");
2166
+ await fs6.promises.appendFile(filePath, formattedMessage, "utf8");
1780
2167
  } else {
1781
- await fs5.promises.writeFile(filePath, formattedMessage, "utf8");
2168
+ await fs6.promises.writeFile(filePath, formattedMessage, "utf8");
1782
2169
  }
1783
2170
  return true;
1784
2171
  } catch (error) {
@@ -1803,12 +2190,12 @@ var FileLogger = class _FileLogger extends EventEmitter {
1803
2190
  const buffer = _FileLogger.buffers.get(filePath);
1804
2191
  if (buffer && buffer.length > 0) {
1805
2192
  try {
1806
- const dir = path7.dirname(filePath);
1807
- if (!fs5.existsSync(dir)) {
1808
- fs5.mkdirSync(dir, { recursive: true });
2193
+ const dir = path8.dirname(filePath);
2194
+ if (!fs6.existsSync(dir)) {
2195
+ fs6.mkdirSync(dir, { recursive: true });
1809
2196
  }
1810
2197
  const content = buffer.join("");
1811
- await fs5.promises.appendFile(filePath, content, "utf8");
2198
+ await fs6.promises.appendFile(filePath, content, "utf8");
1812
2199
  _FileLogger.buffers.delete(filePath);
1813
2200
  return true;
1814
2201
  } catch (error) {
@@ -1944,10 +2331,10 @@ var FileLogger = class _FileLogger extends EventEmitter {
1944
2331
  // Si debe retornar como array de líneas
1945
2332
  } = options;
1946
2333
  try {
1947
- if (!fs5.existsSync(filePath)) {
2334
+ if (!fs6.existsSync(filePath)) {
1948
2335
  return asArray ? [] : "";
1949
2336
  }
1950
- let content = await fs5.promises.readFile(filePath, "utf8");
2337
+ let content = await fs6.promises.readFile(filePath, "utf8");
1951
2338
  if (asArray) {
1952
2339
  let linesArray = content.split("\n").filter((line) => line.trim() !== "");
1953
2340
  if (lines !== null) {
@@ -1990,15 +2377,15 @@ var FileLogger = class _FileLogger extends EventEmitter {
1990
2377
  } = options;
1991
2378
  let lastSize = 0;
1992
2379
  let lastPosition = 0;
1993
- if (fs5.existsSync(filePath)) {
1994
- const stats = fs5.statSync(filePath);
2380
+ if (fs6.existsSync(filePath)) {
2381
+ const stats = fs6.statSync(filePath);
1995
2382
  lastSize = stats.size;
1996
2383
  lastPosition = fromEnd ? stats.size : 0;
1997
2384
  }
1998
2385
  const listener = async (curr, prev) => {
1999
2386
  try {
2000
2387
  if (curr.size > lastSize) {
2001
- const stream = fs5.createReadStream(filePath, {
2388
+ const stream = fs6.createReadStream(filePath, {
2002
2389
  start: lastPosition,
2003
2390
  end: curr.size - 1,
2004
2391
  encoding: "utf8"
@@ -2026,7 +2413,7 @@ var FileLogger = class _FileLogger extends EventEmitter {
2026
2413
  console.error("Error en watcher:", error);
2027
2414
  }
2028
2415
  };
2029
- fs5.watchFile(filePath, { persistent, interval }, listener);
2416
+ fs6.watchFile(filePath, { persistent, interval }, listener);
2030
2417
  const watcherId = `${filePath}_${Date.now()}`;
2031
2418
  _FileLogger.watchers.set(watcherId, listener);
2032
2419
  return {
@@ -2034,7 +2421,7 @@ var FileLogger = class _FileLogger extends EventEmitter {
2034
2421
  stop: () => {
2035
2422
  const storedListener = _FileLogger.watchers.get(watcherId);
2036
2423
  if (storedListener) {
2037
- fs5.unwatchFile(filePath, storedListener);
2424
+ fs6.unwatchFile(filePath, storedListener);
2038
2425
  _FileLogger.watchers.delete(watcherId);
2039
2426
  }
2040
2427
  },
@@ -2047,7 +2434,7 @@ var FileLogger = class _FileLogger extends EventEmitter {
2047
2434
  static stopAllWatchers() {
2048
2435
  for (const [watcherId] of _FileLogger.watchers) {
2049
2436
  const filePath = watcherId.split("_")[0];
2050
- fs5.unwatchFile(filePath);
2437
+ fs6.unwatchFile(filePath);
2051
2438
  }
2052
2439
  _FileLogger.watchers.clear();
2053
2440
  }
@@ -2077,7 +2464,7 @@ var FileLogger = class _FileLogger extends EventEmitter {
2077
2464
  if (lines.length > maxLines) {
2078
2465
  const keepLines = lines.slice(-maxLines);
2079
2466
  const content = keepLines.join("\n") + "\n";
2080
- await fs5.promises.writeFile(filePath, content, "utf8");
2467
+ await fs6.promises.writeFile(filePath, content, "utf8");
2081
2468
  return lines.length - maxLines;
2082
2469
  }
2083
2470
  return 0;
@@ -2092,8 +2479,8 @@ var FileLogger = class _FileLogger extends EventEmitter {
2092
2479
  */
2093
2480
  static async deleteLogFile(filePath) {
2094
2481
  try {
2095
- if (fs5.existsSync(filePath)) {
2096
- await fs5.promises.unlink(filePath);
2482
+ if (fs6.existsSync(filePath)) {
2483
+ await fs6.promises.unlink(filePath);
2097
2484
  return true;
2098
2485
  }
2099
2486
  return false;
@@ -2130,7 +2517,7 @@ var ComputedFieldProcessor = class {
2130
2517
  const tableExistsQuery = `SELECT name FROM sqlite_master WHERE type='table' AND name='dbcube_computes_config'`;
2131
2518
  const tableExistsResult = await DbConfig_default.query(tableExistsQuery);
2132
2519
  if (tableExistsResult.status === "success" && tableExistsResult.data && tableExistsResult.data.length > 0) {
2133
- const queryComputes = await DbConfig_default.query(`SELECT * FROM dbcube_computes_config WHERE database_ref='${name}'`);
2520
+ const queryComputes = await DbConfig_default.queryWithParameters(`SELECT * FROM dbcube_computes_config WHERE database_ref=?`, [name]);
2134
2521
  computedFields = queryComputes.data;
2135
2522
  } else {
2136
2523
  computedFields = [];
@@ -2161,21 +2548,10 @@ var ComputedFieldProcessor = class {
2161
2548
  }
2162
2549
  functionBody = functionBody.replace(/@column\(([^)]+)\)/g, (_match, columnName) => {
2163
2550
  const cleanColumnName = columnName.trim().replace(/['"]/g, "");
2164
- const value = rowData[cleanColumnName];
2165
- if (value === null || value === void 0) {
2166
- return "null";
2167
- } else if (typeof value === "string") {
2168
- return `"${value.replace(/"/g, '\\"')}"`;
2169
- } else if (typeof value === "number" || typeof value === "boolean") {
2170
- return value.toString();
2171
- } else if (value instanceof Date) {
2172
- return `new Date("${value.toISOString()}")`;
2173
- } else {
2174
- return JSON.stringify(value);
2175
- }
2551
+ return `__row[${JSON.stringify(cleanColumnName)}]`;
2176
2552
  });
2177
- const computeFunction = new Function(functionBody);
2178
- return computeFunction();
2553
+ const computeFunction = new Function("__row", functionBody);
2554
+ return computeFunction(rowData);
2179
2555
  } catch (error) {
2180
2556
  console.error("Error processing computed field:", error);
2181
2557
  return null;
@@ -2218,14 +2594,7 @@ var ComputedFieldProcessor = class {
2218
2594
  /@column\(([^)]+)\)/g,
2219
2595
  (match, columnName) => {
2220
2596
  const cleanColumnName = columnName.replace(/['"]/g, "");
2221
- const value = processedItem[cleanColumnName];
2222
- if (typeof value === "string") {
2223
- return `"${value}"`;
2224
- } else if (value === null || value === void 0) {
2225
- return "null";
2226
- } else {
2227
- return String(value);
2228
- }
2597
+ return `__row[${JSON.stringify(cleanColumnName)}]`;
2229
2598
  }
2230
2599
  );
2231
2600
  const computeMatch = processedExpression.match(/@compute\s*\(\s*\(\s*\)\s*=>\s*\{(.*)\}\s*\)/s);
@@ -2233,8 +2602,8 @@ var ComputedFieldProcessor = class {
2233
2602
  throw new Error(`Formato de @compute inv\xE1lido para campo ${fieldName}`);
2234
2603
  }
2235
2604
  const functionBody = computeMatch[1];
2236
- const computeFunction = new Function(functionBody);
2237
- let result = computeFunction();
2605
+ const computeFunction = new Function("__row", functionBody);
2606
+ let result = computeFunction(processedItem);
2238
2607
  result = convertToType(result, type2);
2239
2608
  processedItem[fieldName] = result;
2240
2609
  } catch (error) {
@@ -2426,14 +2795,14 @@ var TableProcessor = class {
2426
2795
  if (await DbConfig_default.ifExist()) {
2427
2796
  await DbConfig_default.connect();
2428
2797
  try {
2429
- const tableExistsQuery = `SELECT name FROM sqlite_master WHERE type='table' AND name='dbcube_computes_config'`;
2798
+ const tableExistsQuery = `SELECT name FROM sqlite_master WHERE type='table' AND name='dbcube_schemas_config'`;
2430
2799
  const tableExistsResult = await DbConfig_default.query(tableExistsQuery);
2431
2800
  if (tableExistsResult.status === "success" && tableExistsResult.data && tableExistsResult.data.length > 0) {
2432
- const queryComputes = await DbConfig_default.query(`SELECT * FROM dbcube_schemas_config WHERE table_ref='${tableName}' AND database_ref='${database_ref}'`);
2801
+ const queryComputes = await DbConfig_default.queryWithParameters(`SELECT * FROM dbcube_schemas_config WHERE table_ref=? AND database_ref=?`, [tableName, database_ref]);
2433
2802
  const oldQuery = queryComputes.data[0];
2434
2803
  if (!oldQuery || !oldQuery.struct) {
2435
- console.error("No exist a previus schema please execute the refresh first...", oldQuery);
2436
- return [];
2804
+ await DbConfig_default.disconnect();
2805
+ return [nowQuery];
2437
2806
  }
2438
2807
  const nowSchema = parseCreateTableQuery(nowQuery, dbType);
2439
2808
  const oldSchema = parseCreateTableQuery(oldQuery.struct, dbType);
@@ -2468,7 +2837,7 @@ var TableProcessor = class {
2468
2837
  if (await DbConfig_default.ifExist()) {
2469
2838
  await DbConfig_default.connect();
2470
2839
  try {
2471
- await DbConfig_default.query(`DELETE FROM dbcube_schemas_config WHERE table_ref='${table_ref}' AND database_ref='${database_ref}'`);
2840
+ await DbConfig_default.queryWithParameters(`DELETE FROM dbcube_schemas_config WHERE table_ref=? AND database_ref=?`, [table_ref, database_ref]);
2472
2841
  const tableExistsQuery = `INSERT INTO dbcube_schemas_config (table_ref, database_ref, struct) VALUES (?, ?, ?)`;
2473
2842
  await DbConfig_default.queryWithParameters(tableExistsQuery, [table_ref, database_ref, struct]);
2474
2843
  } catch (error) {
@@ -2487,7 +2856,7 @@ var TriggerProcessor = class {
2487
2856
  const tableExistsQuery = `SELECT name FROM sqlite_master WHERE type='table' AND name='dbcube_triggers_config'`;
2488
2857
  const tableExistsResult = await DbConfig_default.query(tableExistsQuery);
2489
2858
  if (tableExistsResult.status === "success" && tableExistsResult.data && tableExistsResult.data.length > 0) {
2490
- const queryComputes = await DbConfig_default.query(`SELECT * FROM dbcube_triggers_config WHERE database_ref='${name}'`);
2859
+ const queryComputes = await DbConfig_default.queryWithParameters(`SELECT * FROM dbcube_triggers_config WHERE database_ref=?`, [name]);
2491
2860
  triggers = queryComputes.data;
2492
2861
  } else {
2493
2862
  triggers = [];
@@ -2523,6 +2892,7 @@ export {
2523
2892
  Binary,
2524
2893
  ComputedFieldProcessor,
2525
2894
  Config,
2895
+ DaemonClient,
2526
2896
  DbConfig,
2527
2897
  Engine,
2528
2898
  FileLogger,