Skip to content

Commit 95ba895

Browse files
author
Matthew Gramigna
authored
Add passing of retrieve to findRecords implementations (cqframework#265)
* Add passing of retrieve to findRecords implementations * Changea approach to use new interface for storing retrieve data * Restructure logic in external and add more test cases * Remove todo and combine variable assignment * Remove unused import
1 parent 8e4ba7c commit 95ba895

File tree

9 files changed

+467
-41
lines changed

9 files changed

+467
-41
lines changed

examples/browser/cql4browsers.js

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4907,6 +4907,17 @@ var __extends = (this && this.__extends) || (function () {
49074907
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
49084908
};
49094909
})();
4910+
var __assign = (this && this.__assign) || function () {
4911+
__assign = Object.assign || function(t) {
4912+
for (var s, i = 1, n = arguments.length; i < n; i++) {
4913+
s = arguments[i];
4914+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
4915+
t[p] = s[p];
4916+
}
4917+
return t;
4918+
};
4919+
return __assign.apply(this, arguments);
4920+
};
49104921
Object.defineProperty(exports, "__esModule", { value: true });
49114922
exports.Retrieve = void 0;
49124923
var expression_1 = require("./expression");
@@ -4927,21 +4938,28 @@ var Retrieve = /** @class */ (function (_super) {
49274938
Retrieve.prototype.exec = function (ctx) {
49284939
var _a;
49294940
var _this = this;
4930-
var records = ctx.findRecords(this.templateId != null ? this.templateId : this.datatype);
4931-
var codes = this.codes;
4932-
if (this.codes && typeof this.codes.exec === 'function') {
4933-
codes = this.codes.execute(ctx);
4934-
if (codes == null) {
4941+
// Object with retrieve information to pass back to patient source
4942+
// Always assign datatype. Assign codeProperty and dateProperty if present
4943+
var retrieveDetails = __assign(__assign({ datatype: this.datatype }, (this.codeProperty ? { codeProperty: this.codeProperty } : {})), (this.dateProperty ? { dateProperty: this.dateProperty } : {}));
4944+
if (this.codes) {
4945+
var resolvedCodes = this.codes.execute(ctx);
4946+
if (resolvedCodes == null) {
49354947
return [];
49364948
}
4949+
retrieveDetails.codes = resolvedCodes;
4950+
}
4951+
if (this.dateRange) {
4952+
retrieveDetails.dateRange = this.dateRange.execute(ctx);
4953+
}
4954+
if (this.templateId) {
4955+
retrieveDetails.templateId = this.templateId;
49374956
}
4938-
if (codes) {
4939-
records = records.filter(function (r) { return _this.recordMatchesCodesOrVS(r, codes); });
4957+
var records = ctx.findRecords(this.templateId != null ? this.templateId : this.datatype, retrieveDetails);
4958+
if (retrieveDetails.codes) {
4959+
records = records.filter(function (r) { return _this.recordMatchesCodesOrVS(r, retrieveDetails.codes); });
49404960
}
4941-
// TODO: Added @dateProperty check due to previous fix in cql4browsers in cql_qdm_patient_api hash: ddbc57
4942-
if (this.dateRange && this.dateProperty) {
4943-
var range_1 = this.dateRange.execute(ctx);
4944-
records = records.filter(function (r) { return range_1.includes(r.getDateOrInterval(_this.dateProperty)); });
4961+
if (retrieveDetails.dateRange && this.dateProperty) {
4962+
records = records.filter(function (r) { var _a; return (_a = retrieveDetails.dateRange) === null || _a === void 0 ? void 0 : _a.includes(r.getDateOrInterval(_this.dateProperty)); });
49454963
}
49464964
if (Array.isArray(records)) {
49474965
(_a = ctx.evaluatedRecords).push.apply(_a, records);
@@ -9014,8 +9032,8 @@ var Context = /** @class */ (function () {
90149032
return this;
90159033
}
90169034
};
9017-
Context.prototype.findRecords = function (profile) {
9018-
return this.parent && this.parent.findRecords(profile);
9035+
Context.prototype.findRecords = function (profile, retrieveDetails) {
9036+
return this.parent && this.parent.findRecords(profile, retrieveDetails);
90199037
};
90209038
Context.prototype.childContext = function (context_values) {
90219039
if (context_values === void 0) { context_values = {}; }
@@ -9360,8 +9378,8 @@ var PatientContext = /** @class */ (function (_super) {
93609378
}
93619379
return this.localId_context[localId];
93629380
};
9363-
PatientContext.prototype.findRecords = function (profile) {
9364-
return this.patient && this.patient.findRecords(profile);
9381+
PatientContext.prototype.findRecords = function (profile, retrieveDetails) {
9382+
return this.patient && this.patient.findRecords(profile, retrieveDetails);
93659383
};
93669384
return PatientContext;
93679385
}(Context));

package-lock.json

Lines changed: 122 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@
6969
"@types/luxon": "1",
7070
"@types/mocha": "^9.1.0",
7171
"@types/node": "^17.0.10",
72+
"@types/should-sinon": "0.0.8",
73+
"@types/sinon": "^10.0.11",
7274
"@types/test-console": "^2.0.0",
7375
"@typescript-eslint/eslint-plugin": "^5.10.0",
7476
"@typescript-eslint/parser": "^5.10.0",
@@ -80,6 +82,8 @@
8082
"nyc": "^15.1.0",
8183
"prettier": "^2.1.1",
8284
"should": "^13.2.3",
85+
"should-sinon": "0.0.6",
86+
"sinon": "^13.0.1",
8387
"test-console": "^2.0.0",
8488
"ts-node": "^10.4.0",
8589
"typescript": "^4.5.4",

src/elm/external.ts

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@ import { Expression } from './expression';
22
import { typeIsArray } from '../util/util';
33
import { Context } from '../runtime/context';
44
import { build } from './builder';
5+
import { RetrieveDetails } from '../types/cql-patient.interfaces';
6+
import { Code, ValueSet } from '../datatypes/clinical';
57

68
export class Retrieve extends Expression {
79
datatype: string;
8-
templateId: string;
9-
codeProperty: string;
10-
codes: any;
11-
dateProperty: string;
12-
dateRange: any;
10+
templateId?: string;
11+
codeProperty?: string;
12+
codes?: Expression;
13+
dateProperty?: string;
14+
dateRange?: Expression;
1315

1416
constructor(json: any) {
1517
super(json);
@@ -22,21 +24,45 @@ export class Retrieve extends Expression {
2224
}
2325

2426
exec(ctx: Context) {
25-
let records = ctx.findRecords(this.templateId != null ? this.templateId : this.datatype);
26-
let codes = this.codes;
27-
if (this.codes && typeof this.codes.exec === 'function') {
28-
codes = this.codes.execute(ctx);
29-
if (codes == null) {
27+
// Object with retrieve information to pass back to patient source
28+
// Always assign datatype. Assign codeProperty and dateProperty if present
29+
const retrieveDetails: RetrieveDetails = {
30+
datatype: this.datatype,
31+
...(this.codeProperty ? { codeProperty: this.codeProperty } : {}),
32+
...(this.dateProperty ? { dateProperty: this.dateProperty } : {})
33+
};
34+
35+
if (this.codes) {
36+
const resolvedCodes: Code[] | ValueSet | undefined = this.codes.execute(ctx);
37+
38+
if (resolvedCodes == null) {
3039
return [];
3140
}
41+
42+
retrieveDetails.codes = resolvedCodes;
43+
}
44+
45+
if (this.dateRange) {
46+
retrieveDetails.dateRange = this.dateRange.execute(ctx);
3247
}
33-
if (codes) {
34-
records = records.filter((r: any) => this.recordMatchesCodesOrVS(r, codes));
48+
49+
if (this.templateId) {
50+
retrieveDetails.templateId = this.templateId;
3551
}
36-
// TODO: Added @dateProperty check due to previous fix in cql4browsers in cql_qdm_patient_api hash: ddbc57
37-
if (this.dateRange && this.dateProperty) {
38-
const range = this.dateRange.execute(ctx);
39-
records = records.filter((r: any) => range.includes(r.getDateOrInterval(this.dateProperty)));
52+
53+
let records = ctx.findRecords(
54+
this.templateId != null ? this.templateId : this.datatype,
55+
retrieveDetails
56+
);
57+
58+
if (retrieveDetails.codes) {
59+
records = records.filter((r: any) => this.recordMatchesCodesOrVS(r, retrieveDetails.codes));
60+
}
61+
62+
if (retrieveDetails.dateRange && this.dateProperty) {
63+
records = records.filter((r: any) =>
64+
retrieveDetails.dateRange?.includes(r.getDateOrInterval(this.dateProperty))
65+
);
4066
}
4167

4268
if (Array.isArray(records)) {

src/runtime/context.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@ import { Exception } from '../datatypes/exception';
22
import { typeIsArray } from '../util/util';
33
import * as dt from '../datatypes/datatypes';
44
import { MessageListener, NullMessageListener } from './messageListeners';
5-
import { Patient } from '../cql-patient';
65
import { Parameter } from '../types/runtime.types';
7-
import { TerminologyProvider } from '../types';
6+
import { PatientObject, RetrieveDetails, TerminologyProvider } from '../types';
87

98
export class Context {
109
// Public Construcor args
@@ -77,8 +76,8 @@ export class Context {
7776
}
7877
}
7978

80-
findRecords(profile: any): any {
81-
return this.parent && this.parent.findRecords(profile);
79+
findRecords(profile: string | null, retrieveDetails?: RetrieveDetails): any {
80+
return this.parent && this.parent.findRecords(profile, retrieveDetails);
8281
}
8382

8483
childContext(context_values = {}) {
@@ -422,7 +421,7 @@ export class Context {
422421
export class PatientContext extends Context {
423422
constructor(
424423
public library: any,
425-
public patient?: Patient | null,
424+
public patient?: PatientObject | null,
426425
codeService?: TerminologyProvider | null,
427426
parameters?: Parameter,
428427
executionDateTime: dt.DateTime = dt.DateTime.fromJSDate(new Date()),
@@ -461,8 +460,8 @@ export class PatientContext extends Context {
461460
return this.localId_context[localId];
462461
}
463462

464-
findRecords(profile: any) {
465-
return this.patient && this.patient.findRecords(profile);
463+
findRecords(profile: any, retrieveDetails?: RetrieveDetails) {
464+
return this.patient && this.patient.findRecords(profile, retrieveDetails);
466465
}
467466
}
468467

0 commit comments

Comments
 (0)