@dbcube/core 5.1.15 → 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/README.md +29 -0
- package/dist/bin.cjs +7 -3
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +7 -3
- package/dist/bin.js.map +1 -1
- package/dist/index.cjs +182 -86
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +113 -47
- package/dist/index.d.ts +113 -47
- package/dist/index.js +182 -86
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -392,7 +392,7 @@ var Downloader = class {
|
|
|
392
392
|
}
|
|
393
393
|
this.mainSpinner.text = import_chalk.default.blue(`Updating ${binariesToDownload.length} binary(ies)...`);
|
|
394
394
|
try {
|
|
395
|
-
await Promise.
|
|
395
|
+
const results = await Promise.allSettled(binariesToDownload.map(async (binary) => {
|
|
396
396
|
const maxRetries = 3;
|
|
397
397
|
let attempt = 0;
|
|
398
398
|
while (attempt <= maxRetries) {
|
|
@@ -420,6 +420,11 @@ var Downloader = class {
|
|
|
420
420
|
}
|
|
421
421
|
}
|
|
422
422
|
}));
|
|
423
|
+
const failures = results.filter((r) => r.status === "rejected");
|
|
424
|
+
if (failures.length > 0) {
|
|
425
|
+
const messages = failures.map((f) => f.reason instanceof Error ? f.reason.message : String(f.reason));
|
|
426
|
+
throw new Error(messages.join(" | "));
|
|
427
|
+
}
|
|
423
428
|
this.mainSpinner.succeed(import_chalk.default.green("Binaries updated successfully"));
|
|
424
429
|
} catch (error) {
|
|
425
430
|
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
@@ -484,8 +489,7 @@ var Downloader = class {
|
|
|
484
489
|
}
|
|
485
490
|
});
|
|
486
491
|
response.on("end", () => {
|
|
487
|
-
file.end();
|
|
488
|
-
resolve5();
|
|
492
|
+
file.end(() => resolve5());
|
|
489
493
|
});
|
|
490
494
|
response.on("error", (err) => {
|
|
491
495
|
file.close();
|
|
@@ -712,7 +716,6 @@ var Config = class {
|
|
|
712
716
|
/**
|
|
713
717
|
* Obtiene un valor de configuración
|
|
714
718
|
* @param key - Clave de configuración
|
|
715
|
-
* @returns Valor de configuración
|
|
716
719
|
*/
|
|
717
720
|
get(key) {
|
|
718
721
|
return this.data[key];
|
|
@@ -720,14 +723,12 @@ var Config = class {
|
|
|
720
723
|
/**
|
|
721
724
|
* Obtiene la configuración de una base de datos específica
|
|
722
725
|
* @param dbName - Nombre de la base de datos
|
|
723
|
-
* @returns Configuración de la base de datos o null
|
|
724
726
|
*/
|
|
725
727
|
getDatabase(dbName) {
|
|
726
728
|
return this.databases[dbName] || null;
|
|
727
729
|
}
|
|
728
730
|
/**
|
|
729
731
|
* Obtiene todas las bases de datos configuradas
|
|
730
|
-
* @returns Todas las configuraciones de bases de datos
|
|
731
732
|
*/
|
|
732
733
|
getAllDatabases() {
|
|
733
734
|
return this.databases;
|
|
@@ -775,6 +776,39 @@ var DaemonClient = class _DaemonClient {
|
|
|
775
776
|
portfilePath() {
|
|
776
777
|
return import_path3.default.join(process.cwd(), ".dbcube", "daemon", `${this.name}.json`);
|
|
777
778
|
}
|
|
779
|
+
lockfilePath() {
|
|
780
|
+
return import_path3.default.join(process.cwd(), ".dbcube", "daemon", `${this.name}.lock`);
|
|
781
|
+
}
|
|
782
|
+
/**
|
|
783
|
+
* Exclusive-create lock so two processes never spawn two daemons for the
|
|
784
|
+
* same database at once. Stale locks (crashed starter) expire after 15s.
|
|
785
|
+
*/
|
|
786
|
+
acquireSpawnLock() {
|
|
787
|
+
const lockPath = this.lockfilePath();
|
|
788
|
+
try {
|
|
789
|
+
import_fs.default.mkdirSync(import_path3.default.dirname(lockPath), { recursive: true });
|
|
790
|
+
const fd = import_fs.default.openSync(lockPath, "wx");
|
|
791
|
+
import_fs.default.writeSync(fd, String(process.pid));
|
|
792
|
+
import_fs.default.closeSync(fd);
|
|
793
|
+
return true;
|
|
794
|
+
} catch {
|
|
795
|
+
try {
|
|
796
|
+
const age = Date.now() - import_fs.default.statSync(lockPath).mtimeMs;
|
|
797
|
+
if (age > 15e3) {
|
|
798
|
+
import_fs.default.unlinkSync(lockPath);
|
|
799
|
+
return this.acquireSpawnLock();
|
|
800
|
+
}
|
|
801
|
+
} catch {
|
|
802
|
+
}
|
|
803
|
+
return false;
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
releaseSpawnLock() {
|
|
807
|
+
try {
|
|
808
|
+
import_fs.default.unlinkSync(this.lockfilePath());
|
|
809
|
+
} catch {
|
|
810
|
+
}
|
|
811
|
+
}
|
|
778
812
|
/**
|
|
779
813
|
* Ensures a usable daemon connection. Returns false when the daemon
|
|
780
814
|
* can't be used (old binary, startup failure) so callers fall back
|
|
@@ -791,24 +825,32 @@ var DaemonClient = class _DaemonClient {
|
|
|
791
825
|
async connectOrStart() {
|
|
792
826
|
const port = this.readPortfile();
|
|
793
827
|
if (port && await this.tryConnect(port)) return true;
|
|
828
|
+
const gotLock = this.acquireSpawnLock();
|
|
794
829
|
try {
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
const
|
|
803
|
-
|
|
830
|
+
if (gotLock) {
|
|
831
|
+
try {
|
|
832
|
+
import_fs.default.unlinkSync(this.portfilePath());
|
|
833
|
+
} catch {
|
|
834
|
+
}
|
|
835
|
+
this.spawnDaemon();
|
|
836
|
+
}
|
|
837
|
+
const deadline = Date.now() + 1e4;
|
|
838
|
+
while (Date.now() < deadline) {
|
|
839
|
+
await new Promise((r) => setTimeout(r, 150));
|
|
840
|
+
const newPort = this.readPortfile();
|
|
841
|
+
if (newPort && await this.tryConnect(newPort)) return true;
|
|
842
|
+
}
|
|
843
|
+
return false;
|
|
844
|
+
} finally {
|
|
845
|
+
if (gotLock) this.releaseSpawnLock();
|
|
804
846
|
}
|
|
805
|
-
return false;
|
|
806
847
|
}
|
|
807
848
|
readPortfile() {
|
|
808
849
|
try {
|
|
809
850
|
const raw = import_fs.default.readFileSync(this.portfilePath(), "utf8");
|
|
810
851
|
const info = JSON.parse(raw);
|
|
811
|
-
|
|
852
|
+
const port = info?.port;
|
|
853
|
+
return Number.isInteger(port) && port > 0 && port <= 65535 ? port : null;
|
|
812
854
|
} catch {
|
|
813
855
|
return null;
|
|
814
856
|
}
|
|
@@ -827,7 +869,7 @@ var DaemonClient = class _DaemonClient {
|
|
|
827
869
|
socket.setNoDelay(true);
|
|
828
870
|
this.attach(socket);
|
|
829
871
|
try {
|
|
830
|
-
const pong = await this.send({ action: "ping" });
|
|
872
|
+
const pong = await this.send({ action: "ping" }, 2e3);
|
|
831
873
|
resolve5(pong.status === 200);
|
|
832
874
|
} catch {
|
|
833
875
|
this.detach();
|
|
@@ -884,7 +926,7 @@ var DaemonClient = class _DaemonClient {
|
|
|
884
926
|
* Sends a request to the daemon. Responses arrive in FIFO order on the
|
|
885
927
|
* single socket, so pending requests resolve in send order.
|
|
886
928
|
*/
|
|
887
|
-
send(payload) {
|
|
929
|
+
send(payload, timeoutMs) {
|
|
888
930
|
return new Promise((resolve5, reject) => {
|
|
889
931
|
if (!this.socket || this.socket.destroyed) {
|
|
890
932
|
reject(new Error("Daemon not connected"));
|
|
@@ -894,7 +936,8 @@ var DaemonClient = class _DaemonClient {
|
|
|
894
936
|
const i = this.pending.findIndex((p) => p.timer === timer);
|
|
895
937
|
if (i !== -1) this.pending.splice(i, 1);
|
|
896
938
|
reject(new Error("Daemon request timeout"));
|
|
897
|
-
|
|
939
|
+
this.detach();
|
|
940
|
+
}, timeoutMs ?? this.requestTimeout);
|
|
898
941
|
this.pending.push({ resolve: resolve5, reject, timer });
|
|
899
942
|
this.socket.write(JSON.stringify(payload) + "\n");
|
|
900
943
|
});
|
|
@@ -1051,14 +1094,16 @@ var Engine = class {
|
|
|
1051
1094
|
"--host",
|
|
1052
1095
|
this.config.config.HOST,
|
|
1053
1096
|
"--port",
|
|
1054
|
-
this.config.config.PORT,
|
|
1055
|
-
"--user",
|
|
1056
|
-
this.config.config.USER,
|
|
1057
|
-
"--password",
|
|
1058
|
-
this.config.config.PASSWORD,
|
|
1097
|
+
String(this.config.config.PORT),
|
|
1059
1098
|
"--motor",
|
|
1060
1099
|
this.config.type
|
|
1061
1100
|
];
|
|
1101
|
+
if (this.config.config.USER != null && this.config.config.USER !== "") {
|
|
1102
|
+
args.push("--user", this.config.config.USER);
|
|
1103
|
+
}
|
|
1104
|
+
if (this.config.config.PASSWORD != null && this.config.config.PASSWORD !== "") {
|
|
1105
|
+
args.push("--password", this.config.config.PASSWORD);
|
|
1106
|
+
}
|
|
1062
1107
|
}
|
|
1063
1108
|
return args;
|
|
1064
1109
|
}
|
|
@@ -1117,8 +1162,10 @@ var Engine = class {
|
|
|
1117
1162
|
}
|
|
1118
1163
|
};
|
|
1119
1164
|
child.stdout.on("data", (data) => {
|
|
1120
|
-
|
|
1121
|
-
|
|
1165
|
+
const text = data.toString();
|
|
1166
|
+
stdoutBuffer += text;
|
|
1167
|
+
const visible = text.split("\n").filter((l) => l.trim() && !l.includes("PROCESS_RESPONSE:")).join("\n");
|
|
1168
|
+
if (visible) console.log(visible);
|
|
1122
1169
|
const match = stdoutBuffer.match(/PROCESS_RESPONSE:(\{.*\})/);
|
|
1123
1170
|
if (match) {
|
|
1124
1171
|
try {
|
|
@@ -1138,8 +1185,10 @@ var Engine = class {
|
|
|
1138
1185
|
}
|
|
1139
1186
|
});
|
|
1140
1187
|
child.stderr.on("data", (data) => {
|
|
1141
|
-
|
|
1142
|
-
|
|
1188
|
+
const text = data.toString();
|
|
1189
|
+
stderrBuffer += text;
|
|
1190
|
+
const visible = text.split("\n").filter((l) => l.trim() && !l.includes("PROCESS_RESPONSE:")).join("\n");
|
|
1191
|
+
if (visible) console.log(visible);
|
|
1143
1192
|
const match = stderrBuffer.match(/PROCESS_RESPONSE:(\{.*\})/);
|
|
1144
1193
|
if (match) {
|
|
1145
1194
|
try {
|
|
@@ -1193,7 +1242,6 @@ var globalTcpConnections = /* @__PURE__ */ new Map();
|
|
|
1193
1242
|
var connectionQueues = /* @__PURE__ */ new Map();
|
|
1194
1243
|
var connectionProcessing = /* @__PURE__ */ new Map();
|
|
1195
1244
|
var queryCache = /* @__PURE__ */ new Map();
|
|
1196
|
-
var cacheSize = 0;
|
|
1197
1245
|
var MAX_CACHE_SIZE = 500;
|
|
1198
1246
|
var QueryEngine = class {
|
|
1199
1247
|
name;
|
|
@@ -1207,7 +1255,7 @@ var QueryEngine = class {
|
|
|
1207
1255
|
this.name = name;
|
|
1208
1256
|
this.config = this.setConfig(name);
|
|
1209
1257
|
this.arguments = this.setArguments();
|
|
1210
|
-
this.timeout = timeout;
|
|
1258
|
+
this.timeout = this.config?.daemon?.requestTimeoutMs ?? timeout;
|
|
1211
1259
|
this.connectionId = `${name}_query_engine_${this.config.type}_${this.config.config.DATABASE}_${this.config.config.HOST || "localhost"}`;
|
|
1212
1260
|
this.tcpPort = this.generatePort();
|
|
1213
1261
|
}
|
|
@@ -1262,17 +1310,30 @@ var QueryEngine = class {
|
|
|
1262
1310
|
"--host",
|
|
1263
1311
|
this.config.config.HOST,
|
|
1264
1312
|
"--port",
|
|
1265
|
-
this.config.config.PORT,
|
|
1266
|
-
"--user",
|
|
1267
|
-
this.config.config.USER,
|
|
1268
|
-
"--password",
|
|
1269
|
-
this.config.config.PASSWORD,
|
|
1313
|
+
String(this.config.config.PORT),
|
|
1270
1314
|
"--motor",
|
|
1271
1315
|
this.config.type
|
|
1272
1316
|
];
|
|
1317
|
+
if (this.config.config.USER != null && this.config.config.USER !== "") {
|
|
1318
|
+
args.push("--user", this.config.config.USER);
|
|
1319
|
+
}
|
|
1320
|
+
if (this.config.config.PASSWORD != null && this.config.config.PASSWORD !== "") {
|
|
1321
|
+
args.push("--password", this.config.config.PASSWORD);
|
|
1322
|
+
}
|
|
1273
1323
|
}
|
|
1324
|
+
const pool = this.config.pool ?? {};
|
|
1325
|
+
if (pool.maxConnections != null) args.push("--max-connections", String(pool.maxConnections));
|
|
1326
|
+
if (pool.minConnections != null) args.push("--min-connections", String(pool.minConnections));
|
|
1327
|
+
if (pool.acquireTimeoutMs != null) args.push("--acquire-timeout-ms", String(pool.acquireTimeoutMs));
|
|
1328
|
+
if (pool.idleTimeoutMs != null) args.push("--idle-timeout-ms", String(pool.idleTimeoutMs));
|
|
1274
1329
|
return args;
|
|
1275
1330
|
}
|
|
1331
|
+
/** El daemon puede desactivarse por config (daemon.enabled=false) o por env (DBCUBE_DAEMON=0). */
|
|
1332
|
+
daemonEnabled() {
|
|
1333
|
+
const flag = process.env.DBCUBE_DAEMON;
|
|
1334
|
+
if (flag === "0" || flag === "false") return false;
|
|
1335
|
+
return this.config?.daemon?.enabled !== false;
|
|
1336
|
+
}
|
|
1276
1337
|
setConfig(name) {
|
|
1277
1338
|
const configInstance = new Config();
|
|
1278
1339
|
try {
|
|
@@ -1308,18 +1369,71 @@ var QueryEngine = class {
|
|
|
1308
1369
|
const isExecuteAction = actionIndex !== -1 && args[actionIndex + 1] === "execute";
|
|
1309
1370
|
const isQueryEngine = binary === "query_engine";
|
|
1310
1371
|
if (isQueryEngine && isExecuteAction) {
|
|
1311
|
-
return this.executeWithTcpServer(args);
|
|
1372
|
+
return this.executeWithTcpServer(this.argsToCommand(args));
|
|
1312
1373
|
} else {
|
|
1313
1374
|
return this.createProcess(binary, args);
|
|
1314
1375
|
}
|
|
1315
1376
|
}
|
|
1316
|
-
|
|
1377
|
+
argsToCommand(args) {
|
|
1378
|
+
const command = {};
|
|
1379
|
+
for (let i = 0; i < args.length; i += 2) {
|
|
1380
|
+
if (args[i].startsWith("--")) {
|
|
1381
|
+
command[args[i].substring(2)] = args[i + 1];
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1384
|
+
return command;
|
|
1385
|
+
}
|
|
1386
|
+
/**
|
|
1387
|
+
* Executes a DML plan over the persistent TCP server.
|
|
1388
|
+
* Pass txId to run it inside an active transaction.
|
|
1389
|
+
*/
|
|
1390
|
+
async executeDml(dml, txId) {
|
|
1391
|
+
const command = { action: "execute", dml: JSON.stringify(dml) };
|
|
1392
|
+
if (txId) command.tx_id = txId;
|
|
1393
|
+
return this.executeWithTcpServer(command);
|
|
1394
|
+
}
|
|
1395
|
+
/**
|
|
1396
|
+
* Executes raw SQL (or a MongoDB command document) with bound parameters
|
|
1397
|
+
* over the persistent TCP server.
|
|
1398
|
+
*/
|
|
1399
|
+
async rawQuery(query, params = [], txId) {
|
|
1400
|
+
const command = { action: "raw", query, params };
|
|
1401
|
+
if (txId) command.tx_id = txId;
|
|
1402
|
+
return this.executeWithTcpServer(command);
|
|
1403
|
+
}
|
|
1404
|
+
/** Starts a server-side transaction and returns its id. */
|
|
1405
|
+
async beginTransaction() {
|
|
1406
|
+
const res = await this.executeWithTcpServer({ action: "begin" });
|
|
1407
|
+
if (res.status !== 200 || !res.data?.tx_id) {
|
|
1408
|
+
throw new Error(String(res.message || "Failed to begin transaction (update the query-engine binary: npx dbcube update)"));
|
|
1409
|
+
}
|
|
1410
|
+
return res.data.tx_id;
|
|
1411
|
+
}
|
|
1412
|
+
async commitTransaction(txId) {
|
|
1413
|
+
const res = await this.executeWithTcpServer({ action: "commit", tx_id: txId });
|
|
1414
|
+
if (res.status !== 200) throw new Error(String(res.message || "Failed to commit transaction"));
|
|
1415
|
+
}
|
|
1416
|
+
async rollbackTransaction(txId) {
|
|
1417
|
+
const res = await this.executeWithTcpServer({ action: "rollback", tx_id: txId });
|
|
1418
|
+
if (res.status !== 200) throw new Error(String(res.message || "Failed to rollback transaction"));
|
|
1419
|
+
}
|
|
1420
|
+
async executeWithTcpServer(command) {
|
|
1421
|
+
if (!this.daemonEnabled()) {
|
|
1422
|
+
if (command.tx_id || ["begin", "commit", "rollback"].includes(command.action)) {
|
|
1423
|
+
throw new Error("Transactions require daemon mode. Remove daemon.enabled=false from dbcube.config.js (or unset DBCUBE_DAEMON=0).");
|
|
1424
|
+
}
|
|
1425
|
+
const args = [];
|
|
1426
|
+
for (const [key, value] of Object.entries(command)) {
|
|
1427
|
+
args.push(`--${key.replace(/_/g, "-")}`, typeof value === "string" ? value : JSON.stringify(value));
|
|
1428
|
+
}
|
|
1429
|
+
return this.createProcess("query_engine", args);
|
|
1430
|
+
}
|
|
1317
1431
|
const serverInfo = globalTcpServers.get(this.connectionId);
|
|
1318
1432
|
if (!serverInfo || !serverInfo.process || serverInfo.process.killed) {
|
|
1319
1433
|
await this.startTcpServer();
|
|
1320
1434
|
await this.waitForServerReady();
|
|
1321
1435
|
}
|
|
1322
|
-
return this.sendTcpRequestFast(
|
|
1436
|
+
return this.sendTcpRequestFast(command);
|
|
1323
1437
|
}
|
|
1324
1438
|
async waitForServerReady() {
|
|
1325
1439
|
const maxRetries = 10;
|
|
@@ -1362,10 +1476,11 @@ var QueryEngine = class {
|
|
|
1362
1476
|
return queryCache.get(dmlJson);
|
|
1363
1477
|
}
|
|
1364
1478
|
const parsed = JSON.parse(dmlJson);
|
|
1365
|
-
if (
|
|
1366
|
-
queryCache.
|
|
1367
|
-
|
|
1479
|
+
if (queryCache.size >= MAX_CACHE_SIZE) {
|
|
1480
|
+
const oldest = queryCache.keys().next().value;
|
|
1481
|
+
if (oldest !== void 0) queryCache.delete(oldest);
|
|
1368
1482
|
}
|
|
1483
|
+
queryCache.set(dmlJson, parsed);
|
|
1369
1484
|
return parsed;
|
|
1370
1485
|
}
|
|
1371
1486
|
async startTcpServer() {
|
|
@@ -1412,14 +1527,14 @@ var QueryEngine = class {
|
|
|
1412
1527
|
});
|
|
1413
1528
|
});
|
|
1414
1529
|
}
|
|
1415
|
-
async sendTcpRequestFast(
|
|
1530
|
+
async sendTcpRequestFast(command) {
|
|
1416
1531
|
return new Promise((resolve5, reject) => {
|
|
1417
1532
|
let queue = connectionQueues.get(this.connectionId);
|
|
1418
1533
|
if (!queue) {
|
|
1419
1534
|
queue = [];
|
|
1420
1535
|
connectionQueues.set(this.connectionId, queue);
|
|
1421
1536
|
}
|
|
1422
|
-
queue.push({
|
|
1537
|
+
queue.push({ command, resolve: resolve5, reject });
|
|
1423
1538
|
this.processQueue();
|
|
1424
1539
|
});
|
|
1425
1540
|
}
|
|
@@ -1446,9 +1561,16 @@ var QueryEngine = class {
|
|
|
1446
1561
|
connection = await this.createNewConnection(serverInfo.port);
|
|
1447
1562
|
globalTcpConnections.set(this.connectionId, connection);
|
|
1448
1563
|
}
|
|
1449
|
-
const result = await this.executeOnConnection(connection, request.
|
|
1564
|
+
const result = await this.executeOnConnection(connection, request.command);
|
|
1450
1565
|
request.resolve(result);
|
|
1451
1566
|
} catch (error) {
|
|
1567
|
+
const staleConnection = globalTcpConnections.get(this.connectionId);
|
|
1568
|
+
if (staleConnection) {
|
|
1569
|
+
try {
|
|
1570
|
+
staleConnection.destroy();
|
|
1571
|
+
} catch {
|
|
1572
|
+
}
|
|
1573
|
+
}
|
|
1452
1574
|
globalTcpConnections.delete(this.connectionId);
|
|
1453
1575
|
request.reject(error);
|
|
1454
1576
|
}
|
|
@@ -1476,16 +1598,8 @@ var QueryEngine = class {
|
|
|
1476
1598
|
});
|
|
1477
1599
|
});
|
|
1478
1600
|
}
|
|
1479
|
-
async executeOnConnection(connection,
|
|
1601
|
+
async executeOnConnection(connection, command) {
|
|
1480
1602
|
return new Promise((resolve5, reject) => {
|
|
1481
|
-
const command = {};
|
|
1482
|
-
for (let i = 0; i < args.length; i += 2) {
|
|
1483
|
-
if (args[i].startsWith("--")) {
|
|
1484
|
-
const key = args[i].substring(2);
|
|
1485
|
-
const value = args[i + 1];
|
|
1486
|
-
command[key] = value;
|
|
1487
|
-
}
|
|
1488
|
-
}
|
|
1489
1603
|
let responseBuffer = "";
|
|
1490
1604
|
let isResolved = false;
|
|
1491
1605
|
const timeout = setTimeout(() => {
|
|
@@ -1527,7 +1641,7 @@ var QueryEngine = class {
|
|
|
1527
1641
|
};
|
|
1528
1642
|
connection.on("data", onData);
|
|
1529
1643
|
connection.on("error", onError);
|
|
1530
|
-
connection.write(JSON.stringify(command));
|
|
1644
|
+
connection.write(JSON.stringify(command) + "\n");
|
|
1531
1645
|
});
|
|
1532
1646
|
}
|
|
1533
1647
|
async createProcess(binary, args) {
|
|
@@ -2452,7 +2566,7 @@ var ComputedFieldProcessor = class {
|
|
|
2452
2566
|
const tableExistsQuery = `SELECT name FROM sqlite_master WHERE type='table' AND name='dbcube_computes_config'`;
|
|
2453
2567
|
const tableExistsResult = await DbConfig_default.query(tableExistsQuery);
|
|
2454
2568
|
if (tableExistsResult.status === "success" && tableExistsResult.data && tableExistsResult.data.length > 0) {
|
|
2455
|
-
const queryComputes = await DbConfig_default.
|
|
2569
|
+
const queryComputes = await DbConfig_default.queryWithParameters(`SELECT * FROM dbcube_computes_config WHERE database_ref=?`, [name]);
|
|
2456
2570
|
computedFields = queryComputes.data;
|
|
2457
2571
|
} else {
|
|
2458
2572
|
computedFields = [];
|
|
@@ -2483,21 +2597,10 @@ var ComputedFieldProcessor = class {
|
|
|
2483
2597
|
}
|
|
2484
2598
|
functionBody = functionBody.replace(/@column\(([^)]+)\)/g, (_match, columnName) => {
|
|
2485
2599
|
const cleanColumnName = columnName.trim().replace(/['"]/g, "");
|
|
2486
|
-
|
|
2487
|
-
if (value === null || value === void 0) {
|
|
2488
|
-
return "null";
|
|
2489
|
-
} else if (typeof value === "string") {
|
|
2490
|
-
return `"${value.replace(/"/g, '\\"')}"`;
|
|
2491
|
-
} else if (typeof value === "number" || typeof value === "boolean") {
|
|
2492
|
-
return value.toString();
|
|
2493
|
-
} else if (value instanceof Date) {
|
|
2494
|
-
return `new Date("${value.toISOString()}")`;
|
|
2495
|
-
} else {
|
|
2496
|
-
return JSON.stringify(value);
|
|
2497
|
-
}
|
|
2600
|
+
return `__row[${JSON.stringify(cleanColumnName)}]`;
|
|
2498
2601
|
});
|
|
2499
|
-
const computeFunction = new Function(functionBody);
|
|
2500
|
-
return computeFunction();
|
|
2602
|
+
const computeFunction = new Function("__row", functionBody);
|
|
2603
|
+
return computeFunction(rowData);
|
|
2501
2604
|
} catch (error) {
|
|
2502
2605
|
console.error("Error processing computed field:", error);
|
|
2503
2606
|
return null;
|
|
@@ -2540,14 +2643,7 @@ var ComputedFieldProcessor = class {
|
|
|
2540
2643
|
/@column\(([^)]+)\)/g,
|
|
2541
2644
|
(match, columnName) => {
|
|
2542
2645
|
const cleanColumnName = columnName.replace(/['"]/g, "");
|
|
2543
|
-
|
|
2544
|
-
if (typeof value === "string") {
|
|
2545
|
-
return `"${value}"`;
|
|
2546
|
-
} else if (value === null || value === void 0) {
|
|
2547
|
-
return "null";
|
|
2548
|
-
} else {
|
|
2549
|
-
return String(value);
|
|
2550
|
-
}
|
|
2646
|
+
return `__row[${JSON.stringify(cleanColumnName)}]`;
|
|
2551
2647
|
}
|
|
2552
2648
|
);
|
|
2553
2649
|
const computeMatch = processedExpression.match(/@compute\s*\(\s*\(\s*\)\s*=>\s*\{(.*)\}\s*\)/s);
|
|
@@ -2555,8 +2651,8 @@ var ComputedFieldProcessor = class {
|
|
|
2555
2651
|
throw new Error(`Formato de @compute inv\xE1lido para campo ${fieldName}`);
|
|
2556
2652
|
}
|
|
2557
2653
|
const functionBody = computeMatch[1];
|
|
2558
|
-
const computeFunction = new Function(functionBody);
|
|
2559
|
-
let result = computeFunction();
|
|
2654
|
+
const computeFunction = new Function("__row", functionBody);
|
|
2655
|
+
let result = computeFunction(processedItem);
|
|
2560
2656
|
result = convertToType(result, type2);
|
|
2561
2657
|
processedItem[fieldName] = result;
|
|
2562
2658
|
} catch (error) {
|
|
@@ -2748,14 +2844,14 @@ var TableProcessor = class {
|
|
|
2748
2844
|
if (await DbConfig_default.ifExist()) {
|
|
2749
2845
|
await DbConfig_default.connect();
|
|
2750
2846
|
try {
|
|
2751
|
-
const tableExistsQuery = `SELECT name FROM sqlite_master WHERE type='table' AND name='
|
|
2847
|
+
const tableExistsQuery = `SELECT name FROM sqlite_master WHERE type='table' AND name='dbcube_schemas_config'`;
|
|
2752
2848
|
const tableExistsResult = await DbConfig_default.query(tableExistsQuery);
|
|
2753
2849
|
if (tableExistsResult.status === "success" && tableExistsResult.data && tableExistsResult.data.length > 0) {
|
|
2754
|
-
const queryComputes = await DbConfig_default.
|
|
2850
|
+
const queryComputes = await DbConfig_default.queryWithParameters(`SELECT * FROM dbcube_schemas_config WHERE table_ref=? AND database_ref=?`, [tableName, database_ref]);
|
|
2755
2851
|
const oldQuery = queryComputes.data[0];
|
|
2756
2852
|
if (!oldQuery || !oldQuery.struct) {
|
|
2757
|
-
|
|
2758
|
-
return [];
|
|
2853
|
+
await DbConfig_default.disconnect();
|
|
2854
|
+
return [nowQuery];
|
|
2759
2855
|
}
|
|
2760
2856
|
const nowSchema = parseCreateTableQuery(nowQuery, dbType);
|
|
2761
2857
|
const oldSchema = parseCreateTableQuery(oldQuery.struct, dbType);
|
|
@@ -2790,7 +2886,7 @@ var TableProcessor = class {
|
|
|
2790
2886
|
if (await DbConfig_default.ifExist()) {
|
|
2791
2887
|
await DbConfig_default.connect();
|
|
2792
2888
|
try {
|
|
2793
|
-
await DbConfig_default.
|
|
2889
|
+
await DbConfig_default.queryWithParameters(`DELETE FROM dbcube_schemas_config WHERE table_ref=? AND database_ref=?`, [table_ref, database_ref]);
|
|
2794
2890
|
const tableExistsQuery = `INSERT INTO dbcube_schemas_config (table_ref, database_ref, struct) VALUES (?, ?, ?)`;
|
|
2795
2891
|
await DbConfig_default.queryWithParameters(tableExistsQuery, [table_ref, database_ref, struct]);
|
|
2796
2892
|
} catch (error) {
|
|
@@ -2809,7 +2905,7 @@ var TriggerProcessor = class {
|
|
|
2809
2905
|
const tableExistsQuery = `SELECT name FROM sqlite_master WHERE type='table' AND name='dbcube_triggers_config'`;
|
|
2810
2906
|
const tableExistsResult = await DbConfig_default.query(tableExistsQuery);
|
|
2811
2907
|
if (tableExistsResult.status === "success" && tableExistsResult.data && tableExistsResult.data.length > 0) {
|
|
2812
|
-
const queryComputes = await DbConfig_default.
|
|
2908
|
+
const queryComputes = await DbConfig_default.queryWithParameters(`SELECT * FROM dbcube_triggers_config WHERE database_ref=?`, [name]);
|
|
2813
2909
|
triggers = queryComputes.data;
|
|
2814
2910
|
} else {
|
|
2815
2911
|
triggers = [];
|