@dbcube/core 3.0.21 → 3.0.23
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 +196 -186
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +8 -2
- package/dist/index.d.ts +8 -2
- package/dist/index.js +197 -194
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -766,166 +766,11 @@ var import_path2 = __toESM(require("path"));
|
|
|
766
766
|
var import_module2 = require("module");
|
|
767
767
|
var net = __toESM(require("net"));
|
|
768
768
|
var import_child_process2 = require("child_process");
|
|
769
|
-
var MAX_CONNECTIONS_PER_DB = 10;
|
|
770
|
-
var MAX_CACHE_ENTRIES = 1e3;
|
|
771
|
-
var CACHE_CLEANUP_THRESHOLD = 0.9;
|
|
772
|
-
var CONNECTION_IDLE_TIMEOUT = 3e5;
|
|
773
|
-
var CONNECTION_MAX_AGE = 36e5;
|
|
774
|
-
var LRUCache = class {
|
|
775
|
-
cache;
|
|
776
|
-
maxSize;
|
|
777
|
-
cleanupThreshold;
|
|
778
|
-
constructor(maxSize, cleanupThreshold = 0.9) {
|
|
779
|
-
this.cache = /* @__PURE__ */ new Map();
|
|
780
|
-
this.maxSize = maxSize;
|
|
781
|
-
this.cleanupThreshold = cleanupThreshold;
|
|
782
|
-
}
|
|
783
|
-
get(key) {
|
|
784
|
-
const entry = this.cache.get(key);
|
|
785
|
-
if (!entry) return void 0;
|
|
786
|
-
entry.lastAccessed = Date.now();
|
|
787
|
-
entry.accessCount++;
|
|
788
|
-
return entry.value;
|
|
789
|
-
}
|
|
790
|
-
set(key, value) {
|
|
791
|
-
if (this.cache.size >= this.maxSize * this.cleanupThreshold) {
|
|
792
|
-
this.evictLRU();
|
|
793
|
-
}
|
|
794
|
-
this.cache.set(key, {
|
|
795
|
-
value,
|
|
796
|
-
lastAccessed: Date.now(),
|
|
797
|
-
accessCount: 1
|
|
798
|
-
});
|
|
799
|
-
}
|
|
800
|
-
evictLRU() {
|
|
801
|
-
const entries = Array.from(this.cache.entries()).sort((a, b) => {
|
|
802
|
-
const scoreDiff = this.calculateScore(a[1]) - this.calculateScore(b[1]);
|
|
803
|
-
if (scoreDiff !== 0) return scoreDiff;
|
|
804
|
-
return a[1].lastAccessed - b[1].lastAccessed;
|
|
805
|
-
});
|
|
806
|
-
const toRemove = Math.floor(this.maxSize * 0.2);
|
|
807
|
-
for (let i = 0; i < toRemove && i < entries.length; i++) {
|
|
808
|
-
this.cache.delete(entries[i][0]);
|
|
809
|
-
}
|
|
810
|
-
}
|
|
811
|
-
calculateScore(entry) {
|
|
812
|
-
const now = Date.now();
|
|
813
|
-
const age = now - entry.lastAccessed;
|
|
814
|
-
const recencyScore = 1 / (age + 1);
|
|
815
|
-
const frequencyScore = entry.accessCount;
|
|
816
|
-
return recencyScore * 0.3 + frequencyScore * 0.7;
|
|
817
|
-
}
|
|
818
|
-
clear() {
|
|
819
|
-
this.cache.clear();
|
|
820
|
-
}
|
|
821
|
-
size() {
|
|
822
|
-
return this.cache.size;
|
|
823
|
-
}
|
|
824
|
-
};
|
|
825
|
-
var ConnectionPool = class {
|
|
826
|
-
pools;
|
|
827
|
-
maxConnectionsPerDb;
|
|
828
|
-
constructor(maxConnectionsPerDb = MAX_CONNECTIONS_PER_DB) {
|
|
829
|
-
this.pools = /* @__PURE__ */ new Map();
|
|
830
|
-
this.maxConnectionsPerDb = maxConnectionsPerDb;
|
|
831
|
-
setInterval(() => this.cleanupIdleConnections(), 6e4);
|
|
832
|
-
}
|
|
833
|
-
getConnection(connectionId) {
|
|
834
|
-
const pool = this.pools.get(connectionId);
|
|
835
|
-
if (!pool || pool.length === 0) return null;
|
|
836
|
-
for (let i = 0; i < pool.length; i++) {
|
|
837
|
-
const conn = pool[i];
|
|
838
|
-
if (this.isConnectionValid(conn)) {
|
|
839
|
-
conn.lastUsed = Date.now();
|
|
840
|
-
conn.requestCount++;
|
|
841
|
-
return conn.socket;
|
|
842
|
-
} else {
|
|
843
|
-
conn.socket.destroy();
|
|
844
|
-
pool.splice(i, 1);
|
|
845
|
-
i--;
|
|
846
|
-
}
|
|
847
|
-
}
|
|
848
|
-
return null;
|
|
849
|
-
}
|
|
850
|
-
addConnection(connectionId, socket) {
|
|
851
|
-
if (!this.pools.has(connectionId)) {
|
|
852
|
-
this.pools.set(connectionId, []);
|
|
853
|
-
}
|
|
854
|
-
const pool = this.pools.get(connectionId);
|
|
855
|
-
if (pool.length >= this.maxConnectionsPerDb) {
|
|
856
|
-
const oldest = pool.shift();
|
|
857
|
-
if (oldest) {
|
|
858
|
-
oldest.socket.destroy();
|
|
859
|
-
}
|
|
860
|
-
}
|
|
861
|
-
pool.push({
|
|
862
|
-
socket,
|
|
863
|
-
lastUsed: Date.now(),
|
|
864
|
-
createdAt: Date.now(),
|
|
865
|
-
requestCount: 0
|
|
866
|
-
});
|
|
867
|
-
}
|
|
868
|
-
removeConnection(connectionId, socket) {
|
|
869
|
-
const pool = this.pools.get(connectionId);
|
|
870
|
-
if (!pool) return;
|
|
871
|
-
const index = pool.findIndex((c) => c.socket === socket);
|
|
872
|
-
if (index !== -1) {
|
|
873
|
-
pool[index].socket.destroy();
|
|
874
|
-
pool.splice(index, 1);
|
|
875
|
-
}
|
|
876
|
-
if (pool.length === 0) {
|
|
877
|
-
this.pools.delete(connectionId);
|
|
878
|
-
}
|
|
879
|
-
}
|
|
880
|
-
closeAll(connectionId) {
|
|
881
|
-
if (connectionId) {
|
|
882
|
-
const pool = this.pools.get(connectionId);
|
|
883
|
-
if (pool) {
|
|
884
|
-
pool.forEach((conn) => conn.socket.destroy());
|
|
885
|
-
this.pools.delete(connectionId);
|
|
886
|
-
}
|
|
887
|
-
} else {
|
|
888
|
-
this.pools.forEach((pool) => {
|
|
889
|
-
pool.forEach((conn) => conn.socket.destroy());
|
|
890
|
-
});
|
|
891
|
-
this.pools.clear();
|
|
892
|
-
}
|
|
893
|
-
}
|
|
894
|
-
isConnectionValid(conn) {
|
|
895
|
-
const now = Date.now();
|
|
896
|
-
const age = now - conn.createdAt;
|
|
897
|
-
return conn.socket.readyState === "open" && age < CONNECTION_MAX_AGE;
|
|
898
|
-
}
|
|
899
|
-
cleanupIdleConnections() {
|
|
900
|
-
const now = Date.now();
|
|
901
|
-
this.pools.forEach((pool, connectionId) => {
|
|
902
|
-
for (let i = pool.length - 1; i >= 0; i--) {
|
|
903
|
-
const conn = pool[i];
|
|
904
|
-
const idleTime = now - conn.lastUsed;
|
|
905
|
-
if (idleTime > CONNECTION_IDLE_TIMEOUT || !this.isConnectionValid(conn)) {
|
|
906
|
-
conn.socket.destroy();
|
|
907
|
-
pool.splice(i, 1);
|
|
908
|
-
}
|
|
909
|
-
}
|
|
910
|
-
if (pool.length === 0) {
|
|
911
|
-
this.pools.delete(connectionId);
|
|
912
|
-
}
|
|
913
|
-
});
|
|
914
|
-
}
|
|
915
|
-
getStats() {
|
|
916
|
-
const stats = {};
|
|
917
|
-
this.pools.forEach((pool, id) => {
|
|
918
|
-
stats[id] = {
|
|
919
|
-
activeConnections: pool.length,
|
|
920
|
-
totalRequests: pool.reduce((sum, c) => sum + c.requestCount, 0)
|
|
921
|
-
};
|
|
922
|
-
});
|
|
923
|
-
return stats;
|
|
924
|
-
}
|
|
925
|
-
};
|
|
926
769
|
var globalTcpServers = /* @__PURE__ */ new Map();
|
|
927
|
-
var
|
|
928
|
-
var queryCache = new
|
|
770
|
+
var globalTcpConnections = /* @__PURE__ */ new Map();
|
|
771
|
+
var queryCache = /* @__PURE__ */ new Map();
|
|
772
|
+
var cacheSize = 0;
|
|
773
|
+
var MAX_CACHE_SIZE = 500;
|
|
929
774
|
var QueryEngine = class {
|
|
930
775
|
name;
|
|
931
776
|
config;
|
|
@@ -955,8 +800,7 @@ var QueryEngine = class {
|
|
|
955
800
|
}
|
|
956
801
|
isPortAvailable(port) {
|
|
957
802
|
return new Promise((resolve5) => {
|
|
958
|
-
const
|
|
959
|
-
const tester = net2.createServer();
|
|
803
|
+
const tester = net.createServer();
|
|
960
804
|
tester.once("error", () => resolve5(false));
|
|
961
805
|
tester.once("listening", () => {
|
|
962
806
|
tester.close();
|
|
@@ -1080,12 +924,14 @@ var QueryEngine = class {
|
|
|
1080
924
|
return new Promise((resolve5) => setTimeout(resolve5, ms));
|
|
1081
925
|
}
|
|
1082
926
|
getCachedDML(dmlJson) {
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
return cached;
|
|
927
|
+
if (queryCache.has(dmlJson)) {
|
|
928
|
+
return queryCache.get(dmlJson);
|
|
1086
929
|
}
|
|
1087
930
|
const parsed = JSON.parse(dmlJson);
|
|
1088
|
-
|
|
931
|
+
if (cacheSize < MAX_CACHE_SIZE) {
|
|
932
|
+
queryCache.set(dmlJson, parsed);
|
|
933
|
+
cacheSize++;
|
|
934
|
+
}
|
|
1089
935
|
return parsed;
|
|
1090
936
|
}
|
|
1091
937
|
async startTcpServer() {
|
|
@@ -1199,12 +1045,13 @@ var QueryEngine = class {
|
|
|
1199
1045
|
});
|
|
1200
1046
|
}
|
|
1201
1047
|
async sendTcpRequestFast(args) {
|
|
1202
|
-
const existingConnection =
|
|
1048
|
+
const existingConnection = globalTcpConnections.get(this.connectionId);
|
|
1203
1049
|
if (existingConnection && existingConnection.readyState === "open") {
|
|
1204
1050
|
try {
|
|
1205
1051
|
return await this.sendOnExistingConnection(existingConnection, args);
|
|
1206
1052
|
} catch (error) {
|
|
1207
|
-
|
|
1053
|
+
globalTcpConnections.delete(this.connectionId);
|
|
1054
|
+
existingConnection.destroy();
|
|
1208
1055
|
}
|
|
1209
1056
|
}
|
|
1210
1057
|
return await this.createPersistentConnection(args);
|
|
@@ -1289,7 +1136,7 @@ var QueryEngine = class {
|
|
|
1289
1136
|
}
|
|
1290
1137
|
return;
|
|
1291
1138
|
}
|
|
1292
|
-
|
|
1139
|
+
globalTcpConnections.set(this.connectionId, client);
|
|
1293
1140
|
const command = {
|
|
1294
1141
|
action: "execute",
|
|
1295
1142
|
dml: dmlJson
|
|
@@ -1316,12 +1163,12 @@ var QueryEngine = class {
|
|
|
1316
1163
|
client.on("error", (error) => {
|
|
1317
1164
|
if (!isResolved) {
|
|
1318
1165
|
isResolved = true;
|
|
1319
|
-
|
|
1166
|
+
globalTcpConnections.delete(this.connectionId);
|
|
1320
1167
|
reject(error);
|
|
1321
1168
|
}
|
|
1322
1169
|
});
|
|
1323
1170
|
client.on("close", () => {
|
|
1324
|
-
|
|
1171
|
+
globalTcpConnections.delete(this.connectionId);
|
|
1325
1172
|
if (!isResolved && !responseBuffer.includes("PROCESS_RESPONSE:")) {
|
|
1326
1173
|
reject(new Error("Connection closed without valid response"));
|
|
1327
1174
|
}
|
|
@@ -1416,7 +1263,12 @@ var QueryEngine = class {
|
|
|
1416
1263
|
});
|
|
1417
1264
|
}
|
|
1418
1265
|
async disconnect() {
|
|
1419
|
-
|
|
1266
|
+
const connection = globalTcpConnections.get(this.connectionId);
|
|
1267
|
+
if (connection && connection.readyState === "open") {
|
|
1268
|
+
connection.write(JSON.stringify({ action: "disconnect" }));
|
|
1269
|
+
connection.destroy();
|
|
1270
|
+
globalTcpConnections.delete(this.connectionId);
|
|
1271
|
+
}
|
|
1420
1272
|
const serverInfo = globalTcpServers.get(this.connectionId);
|
|
1421
1273
|
if (serverInfo && serverInfo.process && !serverInfo.process.killed) {
|
|
1422
1274
|
serverInfo.process.kill();
|
|
@@ -1433,21 +1285,6 @@ var QueryEngine = class {
|
|
|
1433
1285
|
data: null
|
|
1434
1286
|
};
|
|
1435
1287
|
}
|
|
1436
|
-
// Método para obtener estadísticas del pool y cache
|
|
1437
|
-
static getStats() {
|
|
1438
|
-
return {
|
|
1439
|
-
connectionPool: connectionPool.getStats(),
|
|
1440
|
-
cache: {
|
|
1441
|
-
size: queryCache.size(),
|
|
1442
|
-
maxSize: MAX_CACHE_ENTRIES
|
|
1443
|
-
}
|
|
1444
|
-
};
|
|
1445
|
-
}
|
|
1446
|
-
// Método para limpiar todo el cache y conexiones
|
|
1447
|
-
static clearAll() {
|
|
1448
|
-
queryCache.clear();
|
|
1449
|
-
connectionPool.closeAll();
|
|
1450
|
-
}
|
|
1451
1288
|
};
|
|
1452
1289
|
|
|
1453
1290
|
// src/lib/SqliteExecutor.ts
|
|
@@ -1456,13 +1293,20 @@ var path5 = __toESM(require("path"));
|
|
|
1456
1293
|
var fs3 = __toESM(require("fs"));
|
|
1457
1294
|
var import_util = require("util");
|
|
1458
1295
|
var import_module3 = require("module");
|
|
1296
|
+
var net2 = __toESM(require("net"));
|
|
1459
1297
|
var execAsync = (0, import_util.promisify)(import_child_process3.exec);
|
|
1298
|
+
var globalSqliteServers = /* @__PURE__ */ new Map();
|
|
1299
|
+
var globalSqliteConnections = /* @__PURE__ */ new Map();
|
|
1460
1300
|
var SqliteExecutor = class {
|
|
1461
1301
|
binaryPath;
|
|
1462
1302
|
dbPath;
|
|
1303
|
+
connectionId;
|
|
1304
|
+
tcpPort = 9944;
|
|
1305
|
+
useTcp = true;
|
|
1463
1306
|
constructor(dbPath) {
|
|
1464
1307
|
this.dbPath = dbPath;
|
|
1465
1308
|
this.binaryPath = this.getBinaryPath();
|
|
1309
|
+
this.connectionId = `sqlite_${dbPath.replace(/[^a-zA-Z0-9]/g, "_")}`;
|
|
1466
1310
|
}
|
|
1467
1311
|
getBinaryPath() {
|
|
1468
1312
|
const possibleDirs = [
|
|
@@ -1545,7 +1389,173 @@ var SqliteExecutor = class {
|
|
|
1545
1389
|
return false;
|
|
1546
1390
|
}
|
|
1547
1391
|
}
|
|
1392
|
+
async findAvailablePort(startPort) {
|
|
1393
|
+
for (let port = startPort; port >= 9900; port--) {
|
|
1394
|
+
if (await this.isPortAvailable(port)) {
|
|
1395
|
+
return port;
|
|
1396
|
+
}
|
|
1397
|
+
}
|
|
1398
|
+
throw new Error("No available ports found in range 9900-9944");
|
|
1399
|
+
}
|
|
1400
|
+
isPortAvailable(port) {
|
|
1401
|
+
return new Promise((resolve5) => {
|
|
1402
|
+
const tester = net2.createServer();
|
|
1403
|
+
tester.once("error", () => resolve5(false));
|
|
1404
|
+
tester.once("listening", () => {
|
|
1405
|
+
tester.close();
|
|
1406
|
+
resolve5(true);
|
|
1407
|
+
});
|
|
1408
|
+
tester.listen(port, "127.0.0.1");
|
|
1409
|
+
});
|
|
1410
|
+
}
|
|
1411
|
+
async startTcpServer() {
|
|
1412
|
+
this.tcpPort = await this.findAvailablePort(this.tcpPort);
|
|
1413
|
+
return new Promise((resolve5, reject) => {
|
|
1414
|
+
const serverArgs = [
|
|
1415
|
+
"--action",
|
|
1416
|
+
"serve",
|
|
1417
|
+
"--id",
|
|
1418
|
+
this.connectionId,
|
|
1419
|
+
"--database-ref",
|
|
1420
|
+
"config",
|
|
1421
|
+
"--database",
|
|
1422
|
+
this.dbPath
|
|
1423
|
+
];
|
|
1424
|
+
const serverProcess = (0, import_child_process3.spawn)(this.binaryPath, serverArgs);
|
|
1425
|
+
let started = false;
|
|
1426
|
+
const timeout = setTimeout(() => {
|
|
1427
|
+
if (!started) {
|
|
1428
|
+
serverProcess.kill();
|
|
1429
|
+
reject(new Error("SQLite TCP server startup timeout"));
|
|
1430
|
+
}
|
|
1431
|
+
}, 1e4);
|
|
1432
|
+
serverProcess.stdout.on("data", (data) => {
|
|
1433
|
+
const output = data.toString();
|
|
1434
|
+
if (output.includes("SQLite TCP Server started") || output.includes("PROCESS_RESPONSE:")) {
|
|
1435
|
+
if (!started) {
|
|
1436
|
+
started = true;
|
|
1437
|
+
clearTimeout(timeout);
|
|
1438
|
+
const match = output.match(/PROCESS_RESPONSE:(\{.*\})/);
|
|
1439
|
+
if (match) {
|
|
1440
|
+
try {
|
|
1441
|
+
const response = JSON.parse(match[1]);
|
|
1442
|
+
if (response.data && response.data.port) {
|
|
1443
|
+
this.tcpPort = response.data.port;
|
|
1444
|
+
}
|
|
1445
|
+
} catch (e) {
|
|
1446
|
+
}
|
|
1447
|
+
}
|
|
1448
|
+
globalSqliteServers.set(this.connectionId, {
|
|
1449
|
+
port: this.tcpPort,
|
|
1450
|
+
process: serverProcess
|
|
1451
|
+
});
|
|
1452
|
+
resolve5();
|
|
1453
|
+
}
|
|
1454
|
+
}
|
|
1455
|
+
});
|
|
1456
|
+
serverProcess.stderr.on("data", (data) => {
|
|
1457
|
+
console.error(`[SQLite Server Error] ${data.toString().trim()}`);
|
|
1458
|
+
});
|
|
1459
|
+
serverProcess.on("close", () => {
|
|
1460
|
+
globalSqliteServers.delete(this.connectionId);
|
|
1461
|
+
globalSqliteConnections.delete(this.connectionId);
|
|
1462
|
+
});
|
|
1463
|
+
serverProcess.on("error", (error) => {
|
|
1464
|
+
if (!started) {
|
|
1465
|
+
clearTimeout(timeout);
|
|
1466
|
+
reject(error);
|
|
1467
|
+
}
|
|
1468
|
+
});
|
|
1469
|
+
});
|
|
1470
|
+
}
|
|
1471
|
+
async sendTcpQuery(sql, params) {
|
|
1472
|
+
const serverInfo = globalSqliteServers.get(this.connectionId);
|
|
1473
|
+
if (!serverInfo || !serverInfo.process || serverInfo.process.killed) {
|
|
1474
|
+
await this.startTcpServer();
|
|
1475
|
+
await this.sleep(500);
|
|
1476
|
+
}
|
|
1477
|
+
return new Promise((resolve5, reject) => {
|
|
1478
|
+
const client = new net2.Socket();
|
|
1479
|
+
let responseBuffer = "";
|
|
1480
|
+
let isResolved = false;
|
|
1481
|
+
const timeout = setTimeout(() => {
|
|
1482
|
+
if (!isResolved) {
|
|
1483
|
+
isResolved = true;
|
|
1484
|
+
client.destroy();
|
|
1485
|
+
reject(new Error("TCP query timeout"));
|
|
1486
|
+
}
|
|
1487
|
+
}, 1e4);
|
|
1488
|
+
client.connect(this.tcpPort, "127.0.0.1", () => {
|
|
1489
|
+
const command = {
|
|
1490
|
+
action: "query",
|
|
1491
|
+
query: sql,
|
|
1492
|
+
params: params || []
|
|
1493
|
+
};
|
|
1494
|
+
client.write(JSON.stringify(command) + "\n");
|
|
1495
|
+
});
|
|
1496
|
+
client.on("data", (data) => {
|
|
1497
|
+
responseBuffer += data.toString();
|
|
1498
|
+
const match = responseBuffer.match(/PROCESS_RESPONSE:(\{.*\})/);
|
|
1499
|
+
if (match && !isResolved) {
|
|
1500
|
+
isResolved = true;
|
|
1501
|
+
clearTimeout(timeout);
|
|
1502
|
+
client.destroy();
|
|
1503
|
+
try {
|
|
1504
|
+
const response = JSON.parse(match[1]);
|
|
1505
|
+
if (response.code === 200) {
|
|
1506
|
+
resolve5({
|
|
1507
|
+
status: "success",
|
|
1508
|
+
message: response.message,
|
|
1509
|
+
data: response.data
|
|
1510
|
+
});
|
|
1511
|
+
} else {
|
|
1512
|
+
resolve5({
|
|
1513
|
+
status: "error",
|
|
1514
|
+
message: response.message,
|
|
1515
|
+
data: null
|
|
1516
|
+
});
|
|
1517
|
+
}
|
|
1518
|
+
} catch (error) {
|
|
1519
|
+
reject(new Error("Failed to parse TCP response"));
|
|
1520
|
+
}
|
|
1521
|
+
}
|
|
1522
|
+
});
|
|
1523
|
+
client.on("error", (error) => {
|
|
1524
|
+
if (!isResolved) {
|
|
1525
|
+
isResolved = true;
|
|
1526
|
+
clearTimeout(timeout);
|
|
1527
|
+
this.useTcp = false;
|
|
1528
|
+
this.executeBinary([
|
|
1529
|
+
"--action",
|
|
1530
|
+
"query",
|
|
1531
|
+
"--database",
|
|
1532
|
+
this.dbPath,
|
|
1533
|
+
"--query",
|
|
1534
|
+
sql,
|
|
1535
|
+
...params && params.length > 0 ? ["--params", JSON.stringify(params)] : []
|
|
1536
|
+
]).then(resolve5).catch(reject);
|
|
1537
|
+
}
|
|
1538
|
+
});
|
|
1539
|
+
client.on("close", () => {
|
|
1540
|
+
if (!isResolved) {
|
|
1541
|
+
clearTimeout(timeout);
|
|
1542
|
+
reject(new Error("Connection closed without valid response"));
|
|
1543
|
+
}
|
|
1544
|
+
});
|
|
1545
|
+
});
|
|
1546
|
+
}
|
|
1547
|
+
sleep(ms) {
|
|
1548
|
+
return new Promise((resolve5) => setTimeout(resolve5, ms));
|
|
1549
|
+
}
|
|
1548
1550
|
async query(sql, params) {
|
|
1551
|
+
if (this.useTcp) {
|
|
1552
|
+
try {
|
|
1553
|
+
return await this.sendTcpQuery(sql, params);
|
|
1554
|
+
} catch (error) {
|
|
1555
|
+
console.warn("TCP query failed, falling back to direct execution");
|
|
1556
|
+
this.useTcp = false;
|
|
1557
|
+
}
|
|
1558
|
+
}
|
|
1549
1559
|
const args = [
|
|
1550
1560
|
"--action",
|
|
1551
1561
|
"query",
|