Skip to content

Commit 148df7d

Browse files
Merge pull request #545 from KxSystems/KXI-62038
add new required meaning
2 parents cbfad75 + 6b2fa92 commit 148df7d

File tree

4 files changed

+203
-15
lines changed

4 files changed

+203
-15
lines changed

src/commands/dataSourceCommand.ts

Lines changed: 83 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ import {
5151
} from "../utils/core";
5252
import { ServerType } from "../models/connectionsModels";
5353
import { retrieveDataTypeByString } from "../utils/uda";
54-
import { UDARequestBody } from "../models/uda";
54+
import { UDA, UDAParam, UDARequestBody } from "../models/uda";
5555

5656
export async function addDataSource(): Promise<void> {
5757
const kdbDataSourcesFolderPath = createKdbDataSourcesFolder();
@@ -454,52 +454,121 @@ export async function runUDADataSource(
454454
fileContent: DataSourceFiles,
455455
selectedConn: InsightsConnection,
456456
): Promise<any> {
457-
const UDA = fileContent.dataSource.uda;
457+
const uda = fileContent.dataSource.uda;
458458
const returnFormat = ext.isResultsTabVisible ? "structuredText" : "text";
459459

460-
if (!UDA) {
461-
return { error: "UDA not found" };
460+
const validationError = await validateUDA(uda, selectedConn);
461+
if (validationError) {
462+
return validationError;
463+
}
464+
465+
if (!uda) {
466+
return { error: "UDA is undefined" };
467+
}
468+
const { params, parameterTypes, error } = processUDAParams(uda);
469+
if (error) {
470+
return error;
462471
}
472+
const udaReqBody: UDARequestBody = createUDARequestBody(
473+
uda.name,
474+
params,
475+
parameterTypes,
476+
returnFormat,
477+
);
463478

464-
const isAvailable = await selectedConn.isUDAAvailable(UDA.name);
479+
return await executeUDARequest(selectedConn, udaReqBody);
480+
}
465481

466-
if (UDA.name === "") {
482+
export async function validateUDA(
483+
uda: UDA | undefined,
484+
selectedConn: InsightsConnection,
485+
): Promise<{ error: string } | null> {
486+
if (!uda) {
487+
return { error: "UDA not found" };
488+
}
489+
490+
if (uda.name === "") {
467491
return { error: "UDA name not found" };
468492
}
469493

494+
const isAvailable = await selectedConn.isUDAAvailable(uda.name);
470495
if (!isAvailable) {
471-
return { error: `UDA ${UDA.name} is not available in this connection` };
496+
return { error: `UDA ${uda.name} is not available in this connection` };
472497
}
473498

499+
return null;
500+
}
501+
502+
export function processUDAParams(uda: UDA): {
503+
params: { [key: string]: any };
504+
parameterTypes: { [key: string]: any };
505+
error?: { error: string };
506+
} {
474507
const params: { [key: string]: any } = {};
475508
const parameterTypes: { [key: string]: any } = {};
476509

477-
if (UDA.params && UDA.params.length > 0) {
478-
for (const param of UDA.params) {
479-
if (param.isReq && (!param.value || param.value === "")) {
510+
if (uda.params && uda.params.length > 0) {
511+
for (const param of uda.params) {
512+
if (isInvalidRequiredParam(param)) {
480513
return {
481-
error: `The UDA: ${UDA.name} requires the parameter: ${param.name}.`,
514+
params: {},
515+
parameterTypes: {},
516+
error: {
517+
error: `The UDA: ${uda.name} requires the parameter: ${param.name}.`,
518+
},
482519
};
483520
}
521+
484522
if (param.isVisible) {
485-
params[param.name] = param.value;
523+
params[param.name] = param.value || "";
486524
parameterTypes[param.name] = param.selectedMultiTypeString
487525
? retrieveDataTypeByString(param.selectedMultiTypeString)
488526
: param.type;
489527
}
490528
}
491529
}
492530

493-
const udaReqBody: UDARequestBody = {
531+
return { params, parameterTypes };
532+
}
533+
534+
export function isInvalidRequiredParam(param: UDAParam): boolean {
535+
if (param.name === "table" && param.isReq) {
536+
return !param.value || param.value === "";
537+
}
538+
539+
const isAllowedEmptyType =
540+
(Array.isArray(param.type) &&
541+
param.type.length === 1 &&
542+
ext.constants.allowedEmptyRequiredTypes.includes(param.type[0])) ||
543+
(typeof param.type === "number" &&
544+
ext.constants.allowedEmptyRequiredTypes.includes(param.type));
545+
546+
return (
547+
!isAllowedEmptyType && param.isReq && (!param.value || param.value === "")
548+
);
549+
}
550+
551+
export function createUDARequestBody(
552+
name: string,
553+
params: { [key: string]: any },
554+
parameterTypes: { [key: string]: any },
555+
returnFormat: string,
556+
): UDARequestBody {
557+
return {
494558
language: "q",
495-
name: UDA.name,
559+
name,
496560
parameterTypes,
497561
params,
498562
returnFormat,
499563
sampleFn: "first",
500564
sampleSize: 10000,
501565
};
566+
}
502567

568+
export async function executeUDARequest(
569+
selectedConn: InsightsConnection,
570+
udaReqBody: UDARequestBody,
571+
): Promise<any> {
503572
const udaCall = await selectedConn.getDatasourceQuery(
504573
DataSourceTypes.UDA,
505574
udaReqBody,

src/extensionVariables.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ export namespace ext {
239239
"t",
240240
"s",
241241
],
242+
allowedEmptyRequiredTypes: [10, -10, -11],
242243
dataTypes: new Map(
243244
Object.entries({
244245
"-1": "Boolean",

src/webview/components/kdbDataSourceView.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ const UDA_DISTINGUISED_PARAMS: UDAParam[] = [
109109
isDistinguised: true,
110110
},
111111
];
112+
const allowedEmptyRequiredTypes = [10, -10, -11];
112113

113114
@customElement("kdb-data-source-view")
114115
export class KdbDataSourceView extends LitElement {
@@ -1375,7 +1376,13 @@ export class KdbDataSourceView extends LitElement {
13751376
const type = validInputTypes.includes(inputType) ? inputType : "text";
13761377
const value = param.value || param.default || "";
13771378
const renderDeleteParam = this.renderDeleteUDAParamButton(param);
1378-
const isReq = param.isReq ? "*" : "";
1379+
const fieldCanBeEmpty =
1380+
param.name !== "table" &&
1381+
((Array.isArray(param.type) &&
1382+
param.type.some((type) => allowedEmptyRequiredTypes.includes(type))) ||
1383+
(typeof param.type === "number" &&
1384+
allowedEmptyRequiredTypes.includes(param.type)));
1385+
const isReq = param.isReq && !fieldCanBeEmpty ? "*" : "";
13791386
const isDistinguised = param.isDistinguised ? "Distinguished | " : "";
13801387
const typeString = param.typeStrings?.[0]
13811388
? "Type: " + param.typeStrings[0] + " | "

test/suite/commands.test.ts

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ import {
5858
ServerType,
5959
} from "../../src/models/connectionsModels";
6060
import { InsightsApiConfig } from "../../src/models/config";
61+
import { UDAParam } from "../../src/models/uda";
6162

6263
describe("dataSourceCommand", () => {
6364
afterEach(() => {
@@ -1172,6 +1173,116 @@ describe("dataSourceCommand2", () => {
11721173
assert.deepEqual(result, { error });
11731174
});
11741175
});
1176+
1177+
describe("isInvalidRequiredParam", () => {
1178+
it("should return true if param.name is 'table' and isReq is true but value is empty", () => {
1179+
const param: UDAParam = {
1180+
name: "table",
1181+
isReq: true,
1182+
value: "",
1183+
type: -10,
1184+
description: "",
1185+
};
1186+
const result = dataSourceCommand.isInvalidRequiredParam(param);
1187+
assert.strictEqual(result, true);
1188+
});
1189+
1190+
it("should return false if param.name is 'table' and isReq is true with a valid value", () => {
1191+
const param = {
1192+
name: "table",
1193+
isReq: true,
1194+
value: "validValue",
1195+
type: -10,
1196+
description: "",
1197+
};
1198+
const result = dataSourceCommand.isInvalidRequiredParam(param);
1199+
assert.strictEqual(result, false);
1200+
});
1201+
1202+
it("should return false if param.type is a number and is in allowedEmptyRequiredTypes", () => {
1203+
const param = {
1204+
name: "param1",
1205+
isReq: true,
1206+
value: "",
1207+
type: -10,
1208+
description: "",
1209+
};
1210+
const result = dataSourceCommand.isInvalidRequiredParam(param);
1211+
assert.strictEqual(result, false);
1212+
});
1213+
1214+
it("should return true if param.type is a number and is not in allowedEmptyRequiredTypes", () => {
1215+
const param = {
1216+
name: "param1",
1217+
isReq: true,
1218+
value: "",
1219+
type: 1,
1220+
description: "",
1221+
};
1222+
const result = dataSourceCommand.isInvalidRequiredParam(param);
1223+
assert.strictEqual(result, true);
1224+
});
1225+
1226+
it("should return false if param.type is an array and contains a value in allowedEmptyRequiredTypes", () => {
1227+
const param = {
1228+
name: "param1",
1229+
isReq: true,
1230+
value: "",
1231+
type: [-10],
1232+
description: "",
1233+
};
1234+
const result = dataSourceCommand.isInvalidRequiredParam(param);
1235+
assert.strictEqual(result, false);
1236+
});
1237+
1238+
it("should return true if param.type is an array and does not contain a value in allowedEmptyRequiredTypes", () => {
1239+
const param = {
1240+
name: "param1",
1241+
isReq: true,
1242+
value: "",
1243+
type: [1],
1244+
description: "",
1245+
};
1246+
const result = dataSourceCommand.isInvalidRequiredParam(param);
1247+
assert.strictEqual(result, true);
1248+
});
1249+
1250+
it("should return true if param.isReq is true and value is empty, and type is not allowed", () => {
1251+
const param = {
1252+
name: "param1",
1253+
isReq: true,
1254+
value: "",
1255+
type: 1,
1256+
description: "",
1257+
};
1258+
const result = dataSourceCommand.isInvalidRequiredParam(param);
1259+
assert.strictEqual(result, true);
1260+
});
1261+
1262+
it("should return false if param.isReq is false, regardless of value or type", () => {
1263+
const param = {
1264+
name: "param1",
1265+
isReq: false,
1266+
value: "",
1267+
type: 1,
1268+
description: "",
1269+
};
1270+
const result = dataSourceCommand.isInvalidRequiredParam(param);
1271+
assert.strictEqual(result, false);
1272+
});
1273+
1274+
it("should return false if param.value is not empty, regardless of type", () => {
1275+
const param = {
1276+
name: "param1",
1277+
isReq: true,
1278+
value: "validValue",
1279+
type: 1,
1280+
description: "",
1281+
};
1282+
const result = dataSourceCommand.isInvalidRequiredParam(param);
1283+
assert.strictEqual(result, false);
1284+
});
1285+
});
11751286
});
11761287

11771288
describe("installTools", () => {

0 commit comments

Comments
 (0)