@dbcube/core 3.0.7 → 3.0.9

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 CHANGED
@@ -767,6 +767,10 @@ var import_module2 = require("module");
767
767
  var net = __toESM(require("net"));
768
768
  var import_child_process2 = require("child_process");
769
769
  var globalTcpServers = /* @__PURE__ */ new Map();
770
+ var globalTcpConnections = /* @__PURE__ */ new Map();
771
+ var queryCache = /* @__PURE__ */ new Map();
772
+ var cacheSize = 0;
773
+ var MAX_CACHE_SIZE = 500;
770
774
  var QueryEngine = class {
771
775
  name;
772
776
  config;
@@ -885,10 +889,10 @@ var QueryEngine = class {
885
889
  if (!serverInfo || !serverInfo.process || serverInfo.process.killed) {
886
890
  console.log("\u{1F680} Starting TCP server for ultra-fast queries...");
887
891
  await this.startTcpServer();
892
+ await this.waitForServerReady();
888
893
  }
889
- await this.waitForServerReady();
890
894
  console.log("\u26A1 Using TCP server (ultra-fast)");
891
- return this.sendTcpRequest(args);
895
+ return this.sendTcpRequestFast(args);
892
896
  }
893
897
  async waitForServerReady() {
894
898
  const maxRetries = 10;
@@ -923,6 +927,17 @@ var QueryEngine = class {
923
927
  sleep(ms) {
924
928
  return new Promise((resolve5) => setTimeout(resolve5, ms));
925
929
  }
930
+ getCachedDML(dmlJson) {
931
+ if (queryCache.has(dmlJson)) {
932
+ return queryCache.get(dmlJson);
933
+ }
934
+ const parsed = JSON.parse(dmlJson);
935
+ if (cacheSize < MAX_CACHE_SIZE) {
936
+ queryCache.set(dmlJson, parsed);
937
+ cacheSize++;
938
+ }
939
+ return parsed;
940
+ }
926
941
  async startTcpServer() {
927
942
  await this.initializeBinary();
928
943
  if (!this.binary) {
@@ -1036,6 +1051,137 @@ var QueryEngine = class {
1036
1051
  });
1037
1052
  });
1038
1053
  }
1054
+ async sendTcpRequestFast(args) {
1055
+ const existingConnection = globalTcpConnections.get(this.connectionId);
1056
+ if (existingConnection && existingConnection.readyState === "open") {
1057
+ try {
1058
+ return await this.sendOnExistingConnection(existingConnection, args);
1059
+ } catch (error) {
1060
+ globalTcpConnections.delete(this.connectionId);
1061
+ existingConnection.destroy();
1062
+ }
1063
+ }
1064
+ return await this.createPersistentConnection(args);
1065
+ }
1066
+ async sendOnExistingConnection(connection, args) {
1067
+ return new Promise((resolve5, reject) => {
1068
+ const dmlIndex = args.findIndex((arg) => arg === "--dml");
1069
+ const dmlJson = dmlIndex !== -1 ? args[dmlIndex + 1] : null;
1070
+ if (!dmlJson) {
1071
+ reject(new Error("No DML found in arguments"));
1072
+ return;
1073
+ }
1074
+ let responseBuffer = "";
1075
+ let isResolved = false;
1076
+ const timeout = setTimeout(() => {
1077
+ if (!isResolved) {
1078
+ isResolved = true;
1079
+ reject(new Error("TCP request timeout"));
1080
+ }
1081
+ }, 100);
1082
+ const onData = (data) => {
1083
+ responseBuffer += data.toString();
1084
+ const match = responseBuffer.match(/PROCESS_RESPONSE:(\{.*\})/);
1085
+ if (match && !isResolved) {
1086
+ isResolved = true;
1087
+ clearTimeout(timeout);
1088
+ connection.off("data", onData);
1089
+ connection.off("error", onError);
1090
+ try {
1091
+ const response = JSON.parse(match[1]);
1092
+ resolve5({
1093
+ status: response.status,
1094
+ message: response.message,
1095
+ data: response.data
1096
+ });
1097
+ } catch (error) {
1098
+ reject(new Error("Failed to parse TCP response"));
1099
+ }
1100
+ }
1101
+ };
1102
+ const onError = (error) => {
1103
+ if (!isResolved) {
1104
+ isResolved = true;
1105
+ clearTimeout(timeout);
1106
+ connection.off("data", onData);
1107
+ connection.off("error", onError);
1108
+ reject(error);
1109
+ }
1110
+ };
1111
+ connection.on("data", onData);
1112
+ connection.on("error", onError);
1113
+ const command = {
1114
+ action: "execute",
1115
+ dml: dmlJson
1116
+ };
1117
+ connection.write(JSON.stringify(command));
1118
+ });
1119
+ }
1120
+ async createPersistentConnection(args) {
1121
+ return new Promise((resolve5, reject) => {
1122
+ const client = new net.Socket();
1123
+ let responseBuffer = "";
1124
+ let isResolved = false;
1125
+ client.setNoDelay(true);
1126
+ client.setKeepAlive(true, 6e4);
1127
+ const timeout = setTimeout(() => {
1128
+ if (!isResolved) {
1129
+ isResolved = true;
1130
+ client.destroy();
1131
+ reject(new Error("TCP connection timeout"));
1132
+ }
1133
+ }, 5e3);
1134
+ client.connect(this.tcpPort, "127.0.0.1", () => {
1135
+ clearTimeout(timeout);
1136
+ const dmlIndex = args.findIndex((arg) => arg === "--dml");
1137
+ const dmlJson = dmlIndex !== -1 ? args[dmlIndex + 1] : null;
1138
+ if (!dmlJson) {
1139
+ if (!isResolved) {
1140
+ isResolved = true;
1141
+ client.destroy();
1142
+ reject(new Error("No DML found in arguments"));
1143
+ }
1144
+ return;
1145
+ }
1146
+ globalTcpConnections.set(this.connectionId, client);
1147
+ const command = {
1148
+ action: "execute",
1149
+ dml: dmlJson
1150
+ };
1151
+ client.write(JSON.stringify(command));
1152
+ });
1153
+ client.on("data", (data) => {
1154
+ responseBuffer += data.toString();
1155
+ const match = responseBuffer.match(/PROCESS_RESPONSE:(\{.*\})/);
1156
+ if (match && !isResolved) {
1157
+ isResolved = true;
1158
+ try {
1159
+ const response = JSON.parse(match[1]);
1160
+ resolve5({
1161
+ status: response.status,
1162
+ message: response.message,
1163
+ data: response.data
1164
+ });
1165
+ } catch (error) {
1166
+ reject(new Error("Failed to parse TCP response"));
1167
+ }
1168
+ }
1169
+ });
1170
+ client.on("error", (error) => {
1171
+ if (!isResolved) {
1172
+ isResolved = true;
1173
+ globalTcpConnections.delete(this.connectionId);
1174
+ reject(error);
1175
+ }
1176
+ });
1177
+ client.on("close", () => {
1178
+ globalTcpConnections.delete(this.connectionId);
1179
+ if (!isResolved && !responseBuffer.includes("PROCESS_RESPONSE:")) {
1180
+ reject(new Error("Connection closed without valid response"));
1181
+ }
1182
+ });
1183
+ });
1184
+ }
1039
1185
  async createProcess(binary, args) {
1040
1186
  await this.initializeBinary();
1041
1187
  if (!this.binary) {
@@ -1124,6 +1270,12 @@ var QueryEngine = class {
1124
1270
  });
1125
1271
  }
1126
1272
  async disconnect() {
1273
+ const connection = globalTcpConnections.get(this.connectionId);
1274
+ if (connection && connection.readyState === "open") {
1275
+ connection.write(JSON.stringify({ action: "disconnect" }));
1276
+ connection.destroy();
1277
+ globalTcpConnections.delete(this.connectionId);
1278
+ }
1127
1279
  const serverInfo = globalTcpServers.get(this.connectionId);
1128
1280
  if (serverInfo && serverInfo.process && !serverInfo.process.killed) {
1129
1281
  console.log("\u{1F50C} Stopping TCP server...");
@@ -1131,7 +1283,7 @@ var QueryEngine = class {
1131
1283
  globalTcpServers.delete(this.connectionId);
1132
1284
  return {
1133
1285
  status: 200,
1134
- message: "TCP server stopped",
1286
+ message: "TCP server and connections stopped",
1135
1287
  data: null
1136
1288
  };
1137
1289
  }