@dbcube/core 4.1.12 → 4.1.14
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 +85 -184
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +85 -184
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -916,6 +916,8 @@ var net = __toESM(require("net"));
|
|
|
916
916
|
var import_child_process2 = require("child_process");
|
|
917
917
|
var globalTcpServers = /* @__PURE__ */ new Map();
|
|
918
918
|
var globalTcpConnections = /* @__PURE__ */ new Map();
|
|
919
|
+
var connectionQueues = /* @__PURE__ */ new Map();
|
|
920
|
+
var connectionProcessing = /* @__PURE__ */ new Map();
|
|
919
921
|
var queryCache = /* @__PURE__ */ new Map();
|
|
920
922
|
var cacheSize = 0;
|
|
921
923
|
var MAX_CACHE_SIZE = 500;
|
|
@@ -932,7 +934,7 @@ var QueryEngine = class {
|
|
|
932
934
|
this.config = this.setConfig(name);
|
|
933
935
|
this.arguments = this.setArguments();
|
|
934
936
|
this.timeout = timeout;
|
|
935
|
-
this.connectionId = `${name}
|
|
937
|
+
this.connectionId = `${name}_query_engine_${this.config.type}_${this.config.config.DATABASE}_${this.config.config.HOST || "localhost"}`;
|
|
936
938
|
this.tcpPort = this.generatePort();
|
|
937
939
|
}
|
|
938
940
|
generatePort() {
|
|
@@ -1030,7 +1032,8 @@ var QueryEngine = class {
|
|
|
1030
1032
|
async run(binary, args) {
|
|
1031
1033
|
const actionIndex = args.findIndex((arg) => arg === "--action");
|
|
1032
1034
|
const isExecuteAction = actionIndex !== -1 && args[actionIndex + 1] === "execute";
|
|
1033
|
-
|
|
1035
|
+
const isQueryEngine = binary === "query_engine";
|
|
1036
|
+
if (isQueryEngine && isExecuteAction) {
|
|
1034
1037
|
return this.executeWithTcpServer(args);
|
|
1035
1038
|
} else {
|
|
1036
1039
|
return this.createProcess(binary, args);
|
|
@@ -1047,22 +1050,26 @@ var QueryEngine = class {
|
|
|
1047
1050
|
async waitForServerReady() {
|
|
1048
1051
|
const maxRetries = 10;
|
|
1049
1052
|
const retryDelay = 500;
|
|
1053
|
+
const serverInfo = globalTcpServers.get(this.connectionId);
|
|
1054
|
+
if (!serverInfo) {
|
|
1055
|
+
throw new Error("Server not found");
|
|
1056
|
+
}
|
|
1050
1057
|
for (let i = 0; i < maxRetries; i++) {
|
|
1051
|
-
if (await this.isServerResponding()) {
|
|
1058
|
+
if (await this.isServerResponding(serverInfo.port)) {
|
|
1052
1059
|
return;
|
|
1053
1060
|
}
|
|
1054
1061
|
await this.sleep(retryDelay);
|
|
1055
1062
|
}
|
|
1056
1063
|
throw new Error("TCP server failed to become ready within timeout");
|
|
1057
1064
|
}
|
|
1058
|
-
async isServerResponding() {
|
|
1065
|
+
async isServerResponding(port) {
|
|
1059
1066
|
return new Promise((resolve5) => {
|
|
1060
1067
|
const client = new net.Socket();
|
|
1061
1068
|
const timeout = setTimeout(() => {
|
|
1062
1069
|
client.destroy();
|
|
1063
1070
|
resolve5(false);
|
|
1064
1071
|
}, 1e3);
|
|
1065
|
-
client.connect(
|
|
1072
|
+
client.connect(port, "127.0.0.1", () => {
|
|
1066
1073
|
clearTimeout(timeout);
|
|
1067
1074
|
client.destroy();
|
|
1068
1075
|
resolve5(true);
|
|
@@ -1118,7 +1125,7 @@ var QueryEngine = class {
|
|
|
1118
1125
|
}
|
|
1119
1126
|
});
|
|
1120
1127
|
serverProcess.stderr.on("data", (data) => {
|
|
1121
|
-
console.error(`[TCP Server Error] ${data.toString().trim()}`);
|
|
1128
|
+
console.error(`[query_engine TCP Server Error] ${data.toString().trim()}`);
|
|
1122
1129
|
});
|
|
1123
1130
|
serverProcess.on("close", (code) => {
|
|
1124
1131
|
globalTcpServers.delete(this.connectionId);
|
|
@@ -1131,92 +1138,88 @@ var QueryEngine = class {
|
|
|
1131
1138
|
});
|
|
1132
1139
|
});
|
|
1133
1140
|
}
|
|
1134
|
-
async
|
|
1141
|
+
async sendTcpRequestFast(args) {
|
|
1135
1142
|
return new Promise((resolve5, reject) => {
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
if (match && !isResolved) {
|
|
1168
|
-
isResolved = true;
|
|
1169
|
-
clearTimeout(timeout);
|
|
1170
|
-
client.destroy();
|
|
1171
|
-
try {
|
|
1172
|
-
const response = JSON.parse(match[1]);
|
|
1173
|
-
resolve5({
|
|
1174
|
-
status: response.status,
|
|
1175
|
-
message: response.message,
|
|
1176
|
-
data: response.data
|
|
1177
|
-
});
|
|
1178
|
-
} catch (error) {
|
|
1179
|
-
reject(new Error("Failed to parse TCP response"));
|
|
1143
|
+
let queue = connectionQueues.get(this.connectionId);
|
|
1144
|
+
if (!queue) {
|
|
1145
|
+
queue = [];
|
|
1146
|
+
connectionQueues.set(this.connectionId, queue);
|
|
1147
|
+
}
|
|
1148
|
+
queue.push({ args, resolve: resolve5, reject });
|
|
1149
|
+
this.processQueue();
|
|
1150
|
+
});
|
|
1151
|
+
}
|
|
1152
|
+
async processQueue() {
|
|
1153
|
+
if (connectionProcessing.get(this.connectionId)) {
|
|
1154
|
+
return;
|
|
1155
|
+
}
|
|
1156
|
+
const queue = connectionQueues.get(this.connectionId);
|
|
1157
|
+
if (!queue || queue.length === 0) {
|
|
1158
|
+
return;
|
|
1159
|
+
}
|
|
1160
|
+
connectionProcessing.set(this.connectionId, true);
|
|
1161
|
+
try {
|
|
1162
|
+
const serverInfo = globalTcpServers.get(this.connectionId);
|
|
1163
|
+
if (!serverInfo) {
|
|
1164
|
+
throw new Error("Server not initialized");
|
|
1165
|
+
}
|
|
1166
|
+
while (queue.length > 0) {
|
|
1167
|
+
const request = queue.shift();
|
|
1168
|
+
if (!request) break;
|
|
1169
|
+
try {
|
|
1170
|
+
let connection = globalTcpConnections.get(this.connectionId);
|
|
1171
|
+
if (!connection || connection.destroyed || connection.readyState !== "open") {
|
|
1172
|
+
connection = await this.createNewConnection(serverInfo.port);
|
|
1173
|
+
globalTcpConnections.set(this.connectionId, connection);
|
|
1180
1174
|
}
|
|
1175
|
+
const result = await this.executeOnConnection(connection, request.args);
|
|
1176
|
+
request.resolve(result);
|
|
1177
|
+
} catch (error) {
|
|
1178
|
+
globalTcpConnections.delete(this.connectionId);
|
|
1179
|
+
request.reject(error);
|
|
1181
1180
|
}
|
|
1181
|
+
}
|
|
1182
|
+
} finally {
|
|
1183
|
+
connectionProcessing.set(this.connectionId, false);
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
async createNewConnection(port) {
|
|
1187
|
+
return new Promise((resolve5, reject) => {
|
|
1188
|
+
const client = new net.Socket();
|
|
1189
|
+
client.setNoDelay(true);
|
|
1190
|
+
client.setKeepAlive(true, 6e4);
|
|
1191
|
+
const timeout = setTimeout(() => {
|
|
1192
|
+
client.destroy();
|
|
1193
|
+
reject(new Error("Connection timeout"));
|
|
1194
|
+
}, 5e3);
|
|
1195
|
+
client.connect(port, "127.0.0.1", () => {
|
|
1196
|
+
clearTimeout(timeout);
|
|
1197
|
+
resolve5(client);
|
|
1182
1198
|
});
|
|
1183
1199
|
client.on("error", (error) => {
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
clearTimeout(timeout);
|
|
1187
|
-
reject(error);
|
|
1188
|
-
}
|
|
1189
|
-
});
|
|
1190
|
-
client.on("close", () => {
|
|
1191
|
-
if (!isResolved) {
|
|
1192
|
-
clearTimeout(timeout);
|
|
1193
|
-
if (!responseBuffer.includes("PROCESS_RESPONSE:")) {
|
|
1194
|
-
reject(new Error("Connection closed without valid response"));
|
|
1195
|
-
}
|
|
1196
|
-
}
|
|
1200
|
+
clearTimeout(timeout);
|
|
1201
|
+
reject(error);
|
|
1197
1202
|
});
|
|
1198
1203
|
});
|
|
1199
1204
|
}
|
|
1200
|
-
async
|
|
1201
|
-
return await this.sendTcpRequest(args);
|
|
1202
|
-
}
|
|
1203
|
-
async sendOnExistingConnection(connection, args) {
|
|
1205
|
+
async executeOnConnection(connection, args) {
|
|
1204
1206
|
return new Promise((resolve5, reject) => {
|
|
1205
|
-
const
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1207
|
+
const command = {};
|
|
1208
|
+
for (let i = 0; i < args.length; i += 2) {
|
|
1209
|
+
if (args[i].startsWith("--")) {
|
|
1210
|
+
const key = args[i].substring(2);
|
|
1211
|
+
const value = args[i + 1];
|
|
1212
|
+
command[key] = value;
|
|
1213
|
+
}
|
|
1210
1214
|
}
|
|
1211
1215
|
let responseBuffer = "";
|
|
1212
1216
|
let isResolved = false;
|
|
1213
1217
|
const timeout = setTimeout(() => {
|
|
1214
1218
|
if (!isResolved) {
|
|
1215
1219
|
isResolved = true;
|
|
1216
|
-
connection.
|
|
1217
|
-
connection.
|
|
1218
|
-
|
|
1219
|
-
reject(new Error("TCP request timeout"));
|
|
1220
|
+
connection.removeListener("data", onData);
|
|
1221
|
+
connection.removeListener("error", onError);
|
|
1222
|
+
reject(new Error("Request timeout"));
|
|
1220
1223
|
}
|
|
1221
1224
|
}, this.timeout);
|
|
1222
1225
|
const onData = (data) => {
|
|
@@ -1225,8 +1228,8 @@ var QueryEngine = class {
|
|
|
1225
1228
|
if (match && !isResolved) {
|
|
1226
1229
|
isResolved = true;
|
|
1227
1230
|
clearTimeout(timeout);
|
|
1228
|
-
connection.
|
|
1229
|
-
connection.
|
|
1231
|
+
connection.removeListener("data", onData);
|
|
1232
|
+
connection.removeListener("error", onError);
|
|
1230
1233
|
try {
|
|
1231
1234
|
const response = JSON.parse(match[1]);
|
|
1232
1235
|
resolve5({
|
|
@@ -1235,7 +1238,7 @@ var QueryEngine = class {
|
|
|
1235
1238
|
data: response.data
|
|
1236
1239
|
});
|
|
1237
1240
|
} catch (error) {
|
|
1238
|
-
reject(new Error("Failed to parse
|
|
1241
|
+
reject(new Error("Failed to parse response"));
|
|
1239
1242
|
}
|
|
1240
1243
|
}
|
|
1241
1244
|
};
|
|
@@ -1243,118 +1246,16 @@ var QueryEngine = class {
|
|
|
1243
1246
|
if (!isResolved) {
|
|
1244
1247
|
isResolved = true;
|
|
1245
1248
|
clearTimeout(timeout);
|
|
1246
|
-
connection.
|
|
1247
|
-
connection.
|
|
1249
|
+
connection.removeListener("data", onData);
|
|
1250
|
+
connection.removeListener("error", onError);
|
|
1248
1251
|
reject(error);
|
|
1249
1252
|
}
|
|
1250
1253
|
};
|
|
1251
1254
|
connection.on("data", onData);
|
|
1252
1255
|
connection.on("error", onError);
|
|
1253
|
-
const command = {
|
|
1254
|
-
action: "execute",
|
|
1255
|
-
dml: dmlJson
|
|
1256
|
-
};
|
|
1257
1256
|
connection.write(JSON.stringify(command));
|
|
1258
1257
|
});
|
|
1259
1258
|
}
|
|
1260
|
-
async createPersistentConnection(args) {
|
|
1261
|
-
return new Promise((resolve5, reject) => {
|
|
1262
|
-
let client = globalTcpConnections.get(this.connectionId);
|
|
1263
|
-
let isNewConnection = false;
|
|
1264
|
-
if (!client || client.destroyed) {
|
|
1265
|
-
client = new net.Socket();
|
|
1266
|
-
isNewConnection = true;
|
|
1267
|
-
client.setNoDelay(true);
|
|
1268
|
-
client.setKeepAlive(true, 6e4);
|
|
1269
|
-
client.setMaxListeners(20);
|
|
1270
|
-
}
|
|
1271
|
-
let responseBuffer = "";
|
|
1272
|
-
let isResolved = false;
|
|
1273
|
-
const timeout = setTimeout(() => {
|
|
1274
|
-
if (!isResolved) {
|
|
1275
|
-
isResolved = true;
|
|
1276
|
-
client.removeListener("data", dataHandler);
|
|
1277
|
-
globalTcpConnections.delete(this.connectionId);
|
|
1278
|
-
reject(new Error("TCP connection timeout"));
|
|
1279
|
-
}
|
|
1280
|
-
}, this.timeout);
|
|
1281
|
-
const executeQuery = () => {
|
|
1282
|
-
const dmlIndex = args.findIndex((arg) => arg === "--dml");
|
|
1283
|
-
const dmlJson = dmlIndex !== -1 ? args[dmlIndex + 1] : null;
|
|
1284
|
-
if (!dmlJson) {
|
|
1285
|
-
clearTimeout(timeout);
|
|
1286
|
-
if (!isResolved) {
|
|
1287
|
-
isResolved = true;
|
|
1288
|
-
reject(new Error("No DML found in arguments"));
|
|
1289
|
-
}
|
|
1290
|
-
return;
|
|
1291
|
-
}
|
|
1292
|
-
const command = {
|
|
1293
|
-
action: "execute",
|
|
1294
|
-
dml: dmlJson
|
|
1295
|
-
};
|
|
1296
|
-
const commandStr = JSON.stringify(command);
|
|
1297
|
-
const canWrite = client.write(commandStr);
|
|
1298
|
-
if (!canWrite) {
|
|
1299
|
-
client.once("drain", () => {
|
|
1300
|
-
});
|
|
1301
|
-
}
|
|
1302
|
-
};
|
|
1303
|
-
const dataHandler = (data) => {
|
|
1304
|
-
responseBuffer += data.toString();
|
|
1305
|
-
const match = responseBuffer.match(/PROCESS_RESPONSE:(\{.*\})/);
|
|
1306
|
-
if (match && !isResolved) {
|
|
1307
|
-
isResolved = true;
|
|
1308
|
-
clearTimeout(timeout);
|
|
1309
|
-
try {
|
|
1310
|
-
const response = JSON.parse(match[1]);
|
|
1311
|
-
responseBuffer = "";
|
|
1312
|
-
client.removeListener("data", dataHandler);
|
|
1313
|
-
resolve5({
|
|
1314
|
-
status: response.status,
|
|
1315
|
-
message: response.message,
|
|
1316
|
-
data: response.data
|
|
1317
|
-
});
|
|
1318
|
-
} catch (error) {
|
|
1319
|
-
client.removeListener("data", dataHandler);
|
|
1320
|
-
reject(new Error("Failed to parse TCP response"));
|
|
1321
|
-
}
|
|
1322
|
-
}
|
|
1323
|
-
};
|
|
1324
|
-
const errorHandler = (error) => {
|
|
1325
|
-
if (!isResolved) {
|
|
1326
|
-
isResolved = true;
|
|
1327
|
-
clearTimeout(timeout);
|
|
1328
|
-
globalTcpConnections.delete(this.connectionId);
|
|
1329
|
-
client.removeListener("data", dataHandler);
|
|
1330
|
-
reject(error);
|
|
1331
|
-
}
|
|
1332
|
-
};
|
|
1333
|
-
const closeHandler = () => {
|
|
1334
|
-
globalTcpConnections.delete(this.connectionId);
|
|
1335
|
-
if (!isResolved) {
|
|
1336
|
-
isResolved = true;
|
|
1337
|
-
clearTimeout(timeout);
|
|
1338
|
-
client.removeListener("data", dataHandler);
|
|
1339
|
-
reject(new Error("Connection closed unexpectedly"));
|
|
1340
|
-
}
|
|
1341
|
-
};
|
|
1342
|
-
if (isNewConnection) {
|
|
1343
|
-
client.connect(this.tcpPort, "127.0.0.1", () => {
|
|
1344
|
-
clearTimeout(timeout);
|
|
1345
|
-
globalTcpConnections.set(this.connectionId, client);
|
|
1346
|
-
client.on("error", errorHandler);
|
|
1347
|
-
client.on("close", closeHandler);
|
|
1348
|
-
client.on("data", dataHandler);
|
|
1349
|
-
executeQuery();
|
|
1350
|
-
});
|
|
1351
|
-
} else {
|
|
1352
|
-
clearTimeout(timeout);
|
|
1353
|
-
client.on("data", dataHandler);
|
|
1354
|
-
executeQuery();
|
|
1355
|
-
}
|
|
1356
|
-
});
|
|
1357
|
-
}
|
|
1358
1259
|
async createProcess(binary, args) {
|
|
1359
1260
|
await this.initializeBinary();
|
|
1360
1261
|
if (!this.binary) {
|