Skip to content

Commit

Permalink
Merge 5052c60 into ba6eba7
Browse files Browse the repository at this point in the history
  • Loading branch information
sshah-asymmetrik authored Jun 5, 2019
2 parents ba6eba7 + 5052c60 commit 45cbb8a
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 10 deletions.
31 changes: 22 additions & 9 deletions packages/fhir-qb/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ class QueryBuilder {
// 1. [id] 2. [type]/[id] 3. [url]
if (value.match(/^http/)) {
// If the requestValue begins with "http", it's a url.
// The reference type will be the second to last value, with the id being the last value. TODO do we need to clean trailing slashes?
// The reference type will be the second to last value, with the id being the last value.
targetReference = [
referenceParts[referenceParts.length - 2],
referenceParts[referenceParts.length - 1],
Expand Down Expand Up @@ -556,8 +556,13 @@ class QueryBuilder {
* @parameter xpath
* @returns {*|string}
*/
static parseXPath(xpath) {
return xpath.split(/\.(.+)/)[1];
static parseXPath(xpaths) {
xpaths = Array.isArray(xpaths) ? xpaths : [xpaths];
let parsedXPaths = [];
xpaths.forEach((xpath) => {
parsedXPaths.push(xpath.split(/\.(.+)/)[1]);
});
return parsedXPaths;
}

/**
Expand Down Expand Up @@ -673,14 +678,22 @@ class QueryBuilder {

// For each match to perform, transform them into the appropriate format using the db specific qb;
let matchesToPerform = [];
for (let rawMatch of rawMatchesToPerform) {
rawMatchesToPerform.forEach((rawMatch) =>{
let orStatements = [];
for (let value of rawMatch.values) {
rawMatch.value = value;
orStatements.push(this.getSubSearchQuery(rawMatch));
}
// Because there can be multiple fields to check for a given parameter, account for all of them in the
// or statement being constructed.
rawMatch.field.forEach((field) => {
// Make a copy of the rawMatch that's only specific to one of the possible fields
let fieldRawMatch = Object.assign({}, rawMatch);
fieldRawMatch.field = field;
// For each value, add to the or statement for the given field
rawMatch.values.forEach((value) => {
fieldRawMatch.value = value;
orStatements.push(this.getSubSearchQuery(fieldRawMatch));
});
});
matchesToPerform.push(orStatements);
}
});

// Assemble the search query
query = this.qb.assembleSearchQuery({
Expand Down
97 changes: 96 additions & 1 deletion packages/fhir-qb/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3092,7 +3092,7 @@ describe('Mongo Tests', () => {
foo: { type: 'number', xpath: 'Resource.foo' },
};
const includeArchived = false;
let { errors, query } = qb.buildSearchQuery({
let { query } = qb.buildSearchQuery({
req,
parameterDefinitions,
includeArchived,
Expand Down Expand Up @@ -6542,4 +6542,99 @@ describe('Mongo Tests', () => {
);
});
});

describe('Parameter Definition Tests', () => {
test('TODO - test multiple xpaths', () => {
const req = {
method: 'GET',
query: {
foo: 'Evé',
},
};
const parameterDefinitions = {
foo: { type: 'string', xpath: ['Resource.foo', 'Resource.bar'] },
};
const includeArchived = false;
let { errors, query } = qb.buildSearchQuery({
req,
parameterDefinitions,
includeArchived,
});
const expectedResult = [
{
$match: {
$and: [{ $or: [{ foo: { $regex: '^Eve', $options: 'i' } }, { bar: { $regex: '^Eve', $options: 'i' } }] }],
},
},
{ $match: { 'meta._isArchived': false } },
{
$facet: {
data: [{ $skip: 0 }, { $limit: 10 }],
metadata: [
{ $count: 'total' },
{
$addFields: {
numberOfPages: { $ceil: { $divide: ['$total', 10] } },
},
},
{ $addFields: { page: 1 } },
],
},
},
];
expect(errors).toHaveLength(0);
expect(query).toEqual(expectedResult);
});
test('Should return a query that matches foo AND (bar OR baz) in field foo or qux', () => {
const req = {
method: 'GET',
query: {
foo: ['foo', 'bar,baz'],
},
};
const parameterDefinitions = {
foo: { type: 'string', xpath: ['Resource.foo', 'Resource.qux'] },
};
const includeArchived = false;
let { errors, query } = qb.buildSearchQuery({
req,
parameterDefinitions,
includeArchived,
});
const expectedResult = [
{
$match: {
$and: [
{ $or: [{ foo: { $options: 'i', $regex: '^foo' } }, { qux: { $options: 'i', $regex: '^foo' } }] },
{
$or: [
{ foo: { $options: 'i', $regex: '^bar' } },
{ foo: { $options: 'i', $regex: '^baz' } },
{ qux: { $options: 'i', $regex: '^bar' } },
{ qux: { $options: 'i', $regex: '^baz' } }
],
},
],
},
},
{ $match: { 'meta._isArchived': false } },
{
$facet: {
data: [{ $skip: 0 }, { $limit: 10 }],
metadata: [
{ $count: 'total' },
{
$addFields: {
numberOfPages: { $ceil: { $divide: ['$total', 10] } },
},
},
{ $addFields: { page: 1 } },
],
},
},
];
expect(errors).toHaveLength(0);
expect(query).toEqual(expectedResult);
});
});
});

0 comments on commit 45cbb8a

Please sign in to comment.