@tdxvolt/volt-client-grpc 0.11.1 → 0.11.4

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/lib/index.cjs CHANGED
@@ -987,7 +987,15 @@ class GRPCCall extends EventEmitter__default["default"] {
987
987
  streamResponse,
988
988
  );
989
989
  if (parsedResponse.payload) {
990
- this.emit("data", parsedResponse.payload);
990
+ // Interpret a non-empty status message as an error.
991
+ if (parsedResponse.payload?.status?.message) {
992
+ this.emit(
993
+ "error",
994
+ new Error(parsedResponse.payload.status.message),
995
+ );
996
+ } else {
997
+ this.emit("data", parsedResponse.payload);
998
+ }
991
999
  } else if (parsedResponse.ended) {
992
1000
  if (parsedResponse.error) {
993
1001
  this.emit("error", new Error(parsedResponse.error));
@@ -1026,7 +1034,8 @@ class GRPCCall extends EventEmitter__default["default"] {
1026
1034
  });
1027
1035
 
1028
1036
  if (this._initialRequest.request) {
1029
- this._call.write(this._initialRequest.request);
1037
+ // Allow callee to attach event handlers before we actually send the initial payload.
1038
+ process.nextTick(() => this._call.write(this._initialRequest.request));
1030
1039
  }
1031
1040
 
1032
1041
  return this;
@@ -2088,8 +2097,68 @@ class VoltClient extends EventEmitter__default["default"] {
2088
2097
  SqlExecute(request) {
2089
2098
  const grpcClient = this.getVoltAPIClient();
2090
2099
 
2091
- const subscribeCall = new GRPCCall(this, "Execute", "METHOD_TYPE_BIDI");
2092
- return subscribeCall.start(grpcClient, request);
2100
+ const call = new GRPCCall(this, "Execute", "METHOD_TYPE_BIDI");
2101
+ return call.start(grpcClient, request);
2102
+ }
2103
+
2104
+ /**
2105
+ * A synchronous version of SqlExecute that returns the result as an array of JSON objects.
2106
+ */
2107
+ SqlExecuteJSON(request) {
2108
+ return new Promise((resolve, reject) => {
2109
+ const call = this.SqlExecute(request);
2110
+
2111
+ let header;
2112
+ const rows = [];
2113
+
2114
+ call.on("error", reject);
2115
+ call.on("end", () => {
2116
+ resolve(rows);
2117
+ });
2118
+
2119
+ call.on("data", (response) => {
2120
+ if (response.header) {
2121
+ header = response.header;
2122
+ } else if (response.row) {
2123
+ const row = response.row;
2124
+ const obj = {};
2125
+
2126
+ for (let idx = 0; idx < header.column.length; idx++) {
2127
+ const column = header.column[idx];
2128
+
2129
+ if (row.column[idx].data === "null") {
2130
+ obj[column.name] = null;
2131
+ continue;
2132
+ }
2133
+
2134
+ switch (column.type) {
2135
+ case "DATA_TYPE_TEXT": {
2136
+ obj[column.name] = row.column[idx].text;
2137
+ break;
2138
+ }
2139
+ case "DATA_TYPE_INTEGER": {
2140
+ obj[column.name] = parseInt(row.column[idx].integer);
2141
+ break;
2142
+ }
2143
+ case "DATA_TYPE_REAL": {
2144
+ obj[column.name] = parseFloat(row.column[idx].real);
2145
+ break;
2146
+ }
2147
+ case "DATA_TYPE_BLOB": {
2148
+ obj[column.name] = row.column[idx].blob;
2149
+ break;
2150
+ }
2151
+ default: {
2152
+ obj[column.name] = `unrecognised data type: ${column.type}`;
2153
+ break;
2154
+ }
2155
+ }
2156
+ }
2157
+
2158
+ rows.push(obj);
2159
+ }
2160
+ });
2161
+ });
2093
2162
  }
2094
2163
 
2095
2164
  /**
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.11.1",
6
+ "version": "0.11.4",
7
7
  "description": "tdx Volt library for nodejs clients",
8
8
  "type": "module",
9
9
  "exports": {
package/src/grpc-call.js CHANGED
@@ -203,7 +203,15 @@ export default class GRPCCall extends EventEmitter {
203
203
  streamResponse,
204
204
  );
205
205
  if (parsedResponse.payload) {
206
- this.emit("data", parsedResponse.payload);
206
+ // Interpret a non-empty status message as an error.
207
+ if (parsedResponse.payload?.status?.message) {
208
+ this.emit(
209
+ "error",
210
+ new Error(parsedResponse.payload.status.message),
211
+ );
212
+ } else {
213
+ this.emit("data", parsedResponse.payload);
214
+ }
207
215
  } else if (parsedResponse.ended) {
208
216
  if (parsedResponse.error) {
209
217
  this.emit("error", new Error(parsedResponse.error));
@@ -242,7 +250,8 @@ export default class GRPCCall extends EventEmitter {
242
250
  });
243
251
 
244
252
  if (this._initialRequest.request) {
245
- this._call.write(this._initialRequest.request);
253
+ // Allow callee to attach event handlers before we actually send the initial payload.
254
+ process.nextTick(() => this._call.write(this._initialRequest.request));
246
255
  }
247
256
 
248
257
  return this;
@@ -530,8 +530,68 @@ export class VoltClient extends EventEmitter {
530
530
  SqlExecute(request) {
531
531
  const grpcClient = this.getVoltAPIClient();
532
532
 
533
- const subscribeCall = new GRPCCall(this, "Execute", "METHOD_TYPE_BIDI");
534
- return subscribeCall.start(grpcClient, request);
533
+ const call = new GRPCCall(this, "Execute", "METHOD_TYPE_BIDI");
534
+ return call.start(grpcClient, request);
535
+ }
536
+
537
+ /**
538
+ * A synchronous version of SqlExecute that returns the result as an array of JSON objects.
539
+ */
540
+ SqlExecuteJSON(request) {
541
+ return new Promise((resolve, reject) => {
542
+ const call = this.SqlExecute(request);
543
+
544
+ let header;
545
+ const rows = [];
546
+
547
+ call.on("error", reject);
548
+ call.on("end", () => {
549
+ resolve(rows);
550
+ });
551
+
552
+ call.on("data", (response) => {
553
+ if (response.header) {
554
+ header = response.header;
555
+ } else if (response.row) {
556
+ const row = response.row;
557
+ const obj = {};
558
+
559
+ for (let idx = 0; idx < header.column.length; idx++) {
560
+ const column = header.column[idx];
561
+
562
+ if (row.column[idx].data === "null") {
563
+ obj[column.name] = null;
564
+ continue;
565
+ }
566
+
567
+ switch (column.type) {
568
+ case "DATA_TYPE_TEXT": {
569
+ obj[column.name] = row.column[idx].text;
570
+ break;
571
+ }
572
+ case "DATA_TYPE_INTEGER": {
573
+ obj[column.name] = parseInt(row.column[idx].integer);
574
+ break;
575
+ }
576
+ case "DATA_TYPE_REAL": {
577
+ obj[column.name] = parseFloat(row.column[idx].real);
578
+ break;
579
+ }
580
+ case "DATA_TYPE_BLOB": {
581
+ obj[column.name] = row.column[idx].blob;
582
+ break;
583
+ }
584
+ default: {
585
+ obj[column.name] = `unrecognised data type: ${column.type}`;
586
+ break;
587
+ }
588
+ }
589
+ }
590
+
591
+ rows.push(obj);
592
+ }
593
+ });
594
+ });
535
595
  }
536
596
 
537
597
  /**