@dbcube/core 3.0.14 → 3.0.16
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 +27 -159
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +0 -4
- package/dist/index.d.ts +0 -4
- package/dist/index.js +27 -159
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -768,39 +768,9 @@ var net = __toESM(require("net"));
|
|
|
768
768
|
var import_child_process2 = require("child_process");
|
|
769
769
|
var globalTcpServers = /* @__PURE__ */ new Map();
|
|
770
770
|
var globalTcpConnections = /* @__PURE__ */ new Map();
|
|
771
|
-
var
|
|
772
|
-
var
|
|
773
|
-
var
|
|
774
|
-
cache = /* @__PURE__ */ new Map();
|
|
775
|
-
maxSize;
|
|
776
|
-
constructor(maxSize) {
|
|
777
|
-
this.maxSize = maxSize;
|
|
778
|
-
}
|
|
779
|
-
get(key) {
|
|
780
|
-
if (this.cache.has(key)) {
|
|
781
|
-
const value = this.cache.get(key);
|
|
782
|
-
this.cache.delete(key);
|
|
783
|
-
this.cache.set(key, value);
|
|
784
|
-
return value;
|
|
785
|
-
}
|
|
786
|
-
return void 0;
|
|
787
|
-
}
|
|
788
|
-
set(key, value) {
|
|
789
|
-
if (this.cache.has(key)) {
|
|
790
|
-
this.cache.delete(key);
|
|
791
|
-
} else if (this.cache.size >= this.maxSize) {
|
|
792
|
-
const firstKey = this.cache.keys().next().value;
|
|
793
|
-
if (firstKey !== void 0) {
|
|
794
|
-
this.cache.delete(firstKey);
|
|
795
|
-
}
|
|
796
|
-
}
|
|
797
|
-
this.cache.set(key, value);
|
|
798
|
-
}
|
|
799
|
-
size() {
|
|
800
|
-
return this.cache.size;
|
|
801
|
-
}
|
|
802
|
-
};
|
|
803
|
-
var queryCache = new LRUCache(500);
|
|
771
|
+
var queryCache = /* @__PURE__ */ new Map();
|
|
772
|
+
var cacheSize = 0;
|
|
773
|
+
var MAX_CACHE_SIZE = 500;
|
|
804
774
|
var QueryEngine = class {
|
|
805
775
|
name;
|
|
806
776
|
config;
|
|
@@ -919,7 +889,6 @@ var QueryEngine = class {
|
|
|
919
889
|
if (!serverInfo || !serverInfo.process || serverInfo.process.killed) {
|
|
920
890
|
await this.startTcpServer();
|
|
921
891
|
await this.waitForServerReady();
|
|
922
|
-
await this.initializeConnectionPool();
|
|
923
892
|
}
|
|
924
893
|
return this.sendTcpRequestFast(args);
|
|
925
894
|
}
|
|
@@ -955,30 +924,15 @@ var QueryEngine = class {
|
|
|
955
924
|
sleep(ms) {
|
|
956
925
|
return new Promise((resolve5) => setTimeout(resolve5, ms));
|
|
957
926
|
}
|
|
958
|
-
async initializeConnectionPool() {
|
|
959
|
-
console.log("\u{1F3CA} Initializing connection pool...");
|
|
960
|
-
if (!connectionPools.has(this.connectionId)) {
|
|
961
|
-
connectionPools.set(this.connectionId, []);
|
|
962
|
-
}
|
|
963
|
-
const pool = connectionPools.get(this.connectionId);
|
|
964
|
-
for (let i = 0; i < MAX_POOL_SIZE; i++) {
|
|
965
|
-
try {
|
|
966
|
-
const connection = await this.createPooledConnection();
|
|
967
|
-
pool.push(connection);
|
|
968
|
-
console.log(`\u2705 Pool connection ${i + 1}/${MAX_POOL_SIZE} created`);
|
|
969
|
-
} catch (error) {
|
|
970
|
-
console.error(`\u274C Failed to create pool connection ${i + 1}:`, error);
|
|
971
|
-
}
|
|
972
|
-
}
|
|
973
|
-
console.log(`\u{1F680} Connection pool ready with ${pool.length} connections`);
|
|
974
|
-
}
|
|
975
927
|
getCachedDML(dmlJson) {
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
return cached;
|
|
928
|
+
if (queryCache.has(dmlJson)) {
|
|
929
|
+
return queryCache.get(dmlJson);
|
|
979
930
|
}
|
|
980
931
|
const parsed = JSON.parse(dmlJson);
|
|
981
|
-
|
|
932
|
+
if (cacheSize < MAX_CACHE_SIZE) {
|
|
933
|
+
queryCache.set(dmlJson, parsed);
|
|
934
|
+
cacheSize++;
|
|
935
|
+
}
|
|
982
936
|
return parsed;
|
|
983
937
|
}
|
|
984
938
|
async startTcpServer() {
|
|
@@ -1002,6 +956,7 @@ var QueryEngine = class {
|
|
|
1002
956
|
if (output.includes("TCP Server listening on")) {
|
|
1003
957
|
if (!started) {
|
|
1004
958
|
started = true;
|
|
959
|
+
clearTimeout(timeout);
|
|
1005
960
|
globalTcpServers.set(this.connectionId, {
|
|
1006
961
|
port: this.tcpPort,
|
|
1007
962
|
process: serverProcess
|
|
@@ -1018,6 +973,7 @@ var QueryEngine = class {
|
|
|
1018
973
|
});
|
|
1019
974
|
serverProcess.on("error", (error) => {
|
|
1020
975
|
if (!started) {
|
|
976
|
+
clearTimeout(timeout);
|
|
1021
977
|
reject(error);
|
|
1022
978
|
}
|
|
1023
979
|
});
|
|
@@ -1041,6 +997,7 @@ var QueryEngine = class {
|
|
|
1041
997
|
if (!dmlJson) {
|
|
1042
998
|
if (!isResolved) {
|
|
1043
999
|
isResolved = true;
|
|
1000
|
+
clearTimeout(timeout);
|
|
1044
1001
|
client.destroy();
|
|
1045
1002
|
reject(new Error("No DML found in arguments"));
|
|
1046
1003
|
}
|
|
@@ -1057,6 +1014,7 @@ var QueryEngine = class {
|
|
|
1057
1014
|
const match = responseBuffer.match(/PROCESS_RESPONSE:(\{.*\})/);
|
|
1058
1015
|
if (match && !isResolved) {
|
|
1059
1016
|
isResolved = true;
|
|
1017
|
+
clearTimeout(timeout);
|
|
1060
1018
|
client.destroy();
|
|
1061
1019
|
try {
|
|
1062
1020
|
const response = JSON.parse(match[1]);
|
|
@@ -1073,11 +1031,13 @@ var QueryEngine = class {
|
|
|
1073
1031
|
client.on("error", (error) => {
|
|
1074
1032
|
if (!isResolved) {
|
|
1075
1033
|
isResolved = true;
|
|
1034
|
+
clearTimeout(timeout);
|
|
1076
1035
|
reject(error);
|
|
1077
1036
|
}
|
|
1078
1037
|
});
|
|
1079
1038
|
client.on("close", () => {
|
|
1080
1039
|
if (!isResolved) {
|
|
1040
|
+
clearTimeout(timeout);
|
|
1081
1041
|
if (!responseBuffer.includes("PROCESS_RESPONSE:")) {
|
|
1082
1042
|
reject(new Error("Connection closed without valid response"));
|
|
1083
1043
|
}
|
|
@@ -1086,24 +1046,18 @@ var QueryEngine = class {
|
|
|
1086
1046
|
});
|
|
1087
1047
|
}
|
|
1088
1048
|
async sendTcpRequestFast(args) {
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
}
|
|
1092
|
-
const pool = connectionPools.get(this.connectionId);
|
|
1093
|
-
if (pool.length > 0) {
|
|
1094
|
-
const connection = pool.pop();
|
|
1049
|
+
const existingConnection = globalTcpConnections.get(this.connectionId);
|
|
1050
|
+
if (existingConnection && existingConnection.readyState === "open") {
|
|
1095
1051
|
try {
|
|
1096
|
-
|
|
1097
|
-
pool.push(connection);
|
|
1098
|
-
return result;
|
|
1052
|
+
return await this.sendOnExistingConnection(existingConnection, args);
|
|
1099
1053
|
} catch (error) {
|
|
1100
|
-
|
|
1101
|
-
|
|
1054
|
+
globalTcpConnections.delete(this.connectionId);
|
|
1055
|
+
existingConnection.destroy();
|
|
1102
1056
|
}
|
|
1103
1057
|
}
|
|
1104
|
-
return await this.
|
|
1058
|
+
return await this.createPersistentConnection(args);
|
|
1105
1059
|
}
|
|
1106
|
-
async
|
|
1060
|
+
async sendOnExistingConnection(connection, args) {
|
|
1107
1061
|
return new Promise((resolve5, reject) => {
|
|
1108
1062
|
const dmlIndex = args.findIndex((arg) => arg === "--dml");
|
|
1109
1063
|
const dmlJson = dmlIndex !== -1 ? args[dmlIndex + 1] : null;
|
|
@@ -1113,96 +1067,20 @@ var QueryEngine = class {
|
|
|
1113
1067
|
}
|
|
1114
1068
|
let responseBuffer = "";
|
|
1115
1069
|
let isResolved = false;
|
|
1116
|
-
const
|
|
1117
|
-
responseBuffer += data.toString();
|
|
1118
|
-
const match = responseBuffer.match(/PROCESS_RESPONSE:(\{.*\})/);
|
|
1119
|
-
if (match && !isResolved) {
|
|
1120
|
-
isResolved = true;
|
|
1121
|
-
connection.off("data", onData);
|
|
1122
|
-
connection.off("error", onError);
|
|
1123
|
-
connection.off("close", onClose);
|
|
1124
|
-
try {
|
|
1125
|
-
const response = JSON.parse(match[1]);
|
|
1126
|
-
resolve5({
|
|
1127
|
-
status: response.status,
|
|
1128
|
-
message: response.message,
|
|
1129
|
-
data: response.data
|
|
1130
|
-
});
|
|
1131
|
-
} catch (error) {
|
|
1132
|
-
reject(new Error("Failed to parse TCP response"));
|
|
1133
|
-
}
|
|
1134
|
-
}
|
|
1135
|
-
};
|
|
1136
|
-
const onError = (error) => {
|
|
1137
|
-
if (!isResolved) {
|
|
1138
|
-
isResolved = true;
|
|
1139
|
-
connection.off("data", onData);
|
|
1140
|
-
connection.off("error", onError);
|
|
1141
|
-
connection.off("close", onClose);
|
|
1142
|
-
reject(error);
|
|
1143
|
-
}
|
|
1144
|
-
};
|
|
1145
|
-
const onClose = () => {
|
|
1070
|
+
const timeout = setTimeout(() => {
|
|
1146
1071
|
if (!isResolved) {
|
|
1147
1072
|
isResolved = true;
|
|
1148
|
-
|
|
1149
|
-
connection.off("error", onError);
|
|
1150
|
-
connection.off("close", onClose);
|
|
1151
|
-
connection.off("close", onClose);
|
|
1152
|
-
reject(new Error("Connection closed unexpectedly"));
|
|
1073
|
+
reject(new Error("TCP request timeout"));
|
|
1153
1074
|
}
|
|
1154
|
-
};
|
|
1155
|
-
connection.on("data", onData);
|
|
1156
|
-
connection.on("error", onError);
|
|
1157
|
-
connection.on("close", onClose);
|
|
1158
|
-
const command = `{"action":"execute","dml":${dmlJson}}`;
|
|
1159
|
-
connection.write(command);
|
|
1160
|
-
});
|
|
1161
|
-
}
|
|
1162
|
-
async createAndPoolConnection(args) {
|
|
1163
|
-
const connection = await this.createPooledConnection();
|
|
1164
|
-
if (!connectionPools.has(this.connectionId)) {
|
|
1165
|
-
connectionPools.set(this.connectionId, []);
|
|
1166
|
-
}
|
|
1167
|
-
const result = await this.sendUltraFast(connection, args);
|
|
1168
|
-
const pool = connectionPools.get(this.connectionId);
|
|
1169
|
-
if (pool.length < MAX_POOL_SIZE) {
|
|
1170
|
-
pool.push(connection);
|
|
1171
|
-
} else {
|
|
1172
|
-
connection.destroy();
|
|
1173
|
-
}
|
|
1174
|
-
return result;
|
|
1175
|
-
}
|
|
1176
|
-
async createPooledConnection() {
|
|
1177
|
-
return new Promise((resolve5, reject) => {
|
|
1178
|
-
const client = new net.Socket();
|
|
1179
|
-
client.setNoDelay(true);
|
|
1180
|
-
client.setKeepAlive(true, 0);
|
|
1181
|
-
client.connect(this.tcpPort, "127.0.0.1", () => {
|
|
1182
|
-
resolve5(client);
|
|
1183
|
-
});
|
|
1184
|
-
client.on("error", reject);
|
|
1185
|
-
});
|
|
1186
|
-
}
|
|
1187
|
-
async sendOnExistingConnection(connection, args) {
|
|
1188
|
-
return new Promise((resolve5, reject) => {
|
|
1189
|
-
const dmlIndex = args.findIndex((arg) => arg === "--dml");
|
|
1190
|
-
const dmlJson = dmlIndex !== -1 ? args[dmlIndex + 1] : null;
|
|
1191
|
-
if (!dmlJson) {
|
|
1192
|
-
reject(new Error("No DML found in arguments"));
|
|
1193
|
-
return;
|
|
1194
|
-
}
|
|
1195
|
-
const dmlParsed = this.getCachedDML(dmlJson);
|
|
1196
|
-
let responseBuffer = "";
|
|
1197
|
-
let isResolved = false;
|
|
1075
|
+
}, 100);
|
|
1198
1076
|
const onData = (data) => {
|
|
1199
1077
|
responseBuffer += data.toString();
|
|
1200
1078
|
const match = responseBuffer.match(/PROCESS_RESPONSE:(\{.*\})/);
|
|
1201
1079
|
if (match && !isResolved) {
|
|
1202
1080
|
isResolved = true;
|
|
1081
|
+
clearTimeout(timeout);
|
|
1203
1082
|
connection.off("data", onData);
|
|
1204
1083
|
connection.off("error", onError);
|
|
1205
|
-
connection.off("close", onClose);
|
|
1206
1084
|
try {
|
|
1207
1085
|
const response = JSON.parse(match[1]);
|
|
1208
1086
|
resolve5({
|
|
@@ -1218,24 +1096,14 @@ var QueryEngine = class {
|
|
|
1218
1096
|
const onError = (error) => {
|
|
1219
1097
|
if (!isResolved) {
|
|
1220
1098
|
isResolved = true;
|
|
1099
|
+
clearTimeout(timeout);
|
|
1221
1100
|
connection.off("data", onData);
|
|
1222
1101
|
connection.off("error", onError);
|
|
1223
|
-
connection.off("close", onClose);
|
|
1224
1102
|
reject(error);
|
|
1225
1103
|
}
|
|
1226
1104
|
};
|
|
1227
|
-
const onClose = () => {
|
|
1228
|
-
if (!isResolved) {
|
|
1229
|
-
isResolved = true;
|
|
1230
|
-
connection.off("data", onData);
|
|
1231
|
-
connection.off("error", onError);
|
|
1232
|
-
connection.off("close", onClose);
|
|
1233
|
-
reject(new Error("Connection closed unexpectedly"));
|
|
1234
|
-
}
|
|
1235
|
-
};
|
|
1236
1105
|
connection.on("data", onData);
|
|
1237
1106
|
connection.on("error", onError);
|
|
1238
|
-
connection.on("close", onClose);
|
|
1239
1107
|
const command = {
|
|
1240
1108
|
action: "execute",
|
|
1241
1109
|
dml: dmlJson
|