Skip to content

Commit

Permalink
Add handling of expr or simple comparison
Browse files Browse the repository at this point in the history
Jira ticket: CAMS-421

Co-authored-by: Arthur Morrow <[email protected]>
Co-authored-by: Brian Posey <[email protected]>
  • Loading branch information
3 people committed Mar 5, 2025
1 parent fc58505 commit 4881665
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 16 deletions.
39 changes: 36 additions & 3 deletions backend/lib/adapters/gateways/mongo/utils/foo.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import QueryBuilder from '../../../../query/query-builder';
import { SyncedCase } from '../../../../../../common/src/cams/cases';

describe('foo', () => {
const { greaterThan } = QueryBuilder;
const { and, equals, exists, greaterThan } = QueryBuilder;
test('should do the thing', () => {
const expected = {
$expr: {
Expand All @@ -13,8 +13,9 @@ describe('foo', () => {

expect(
toMongoQuery(
QueryBuilder.build(greaterThan<SyncedCase['closedDate']>('closedDate', 'reopenedDate')),
true,
QueryBuilder.build(
greaterThan<SyncedCase['closedDate']>('closedDate', 'reopenedDate', true),
),
),
).toEqual(expected);

Expand All @@ -28,5 +29,37 @@ describe('foo', () => {
QueryBuilder.build(greaterThan<SyncedCase['closedDate']>('closedDate', '2025-01-01')),
),
).toEqual(expected2);

const expected3 = {
$and: [
{ closedDate: { $exists: true } },
{ reopenedDate: { $exists: true } },
{ $expr: { $gt: ['$closedDate', '$reopenedDate'] } },
{ chapter: { $eq: '7' } },
{ $expr: { $eq: ['$closedDate', '$reopenedDate'] } },
],
};

type Foo = {
bar: number;
bar2: number;
baz: string;
};

expect(
toMongoQuery(
QueryBuilder.build(
and(
exists<SyncedCase>('closedDate', true),
exists<SyncedCase>('reopenedDate', true),
greaterThan<SyncedCase['closedDate']>('closedDate', 'reopenedDate', true),
equals<SyncedCase['chapter']>('chapter', '7'),
equals<SyncedCase['closedDate']>('closedDate', 'reopenedDate', true),
greaterThan<Foo['bar']>('bar', 7, true),
greaterThan<Foo['bar']>('bar', 'bar2', true),
),
),
),
).toEqual(expected3);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ const mapCondition: { [key: string]: string } = {
};

// TODO: create new aggregate renderer
function translateCondition(query: Condition, isAggregateCondition: boolean = false) {
if (isAggregateCondition) {
// https://www.mongodb.com/docs/manual/reference/operator/aggregation/#std-label-aggregation-expressions
function translateCondition(query: Condition) {
if (query.compareFields) {
return {
$expr: {
[mapCondition[query.condition]]: [`$${query.leftOperand}`, `$${query.rightOperand}`],
Expand Down Expand Up @@ -77,20 +78,20 @@ function translatePagination(query: Pagination) {
return result;
}

function renderQuery(query: Query, isAggregateCondition: boolean = false) {
function renderQuery(query: Query) {
if (isArray(query)) {
return query.map((q) => renderQuery(q, isAggregateCondition));
return query.map((q) => renderQuery(q));
} else if (isPagination(query)) {
return translatePagination(query);
} else if (isConjunction(query)) {
return translateConjunction(query);
} else if (isCondition(query)) {
return translateCondition(query, isAggregateCondition);
return translateCondition(query);
}
}

export function toMongoQuery(query: Query, isAggregateCondition: boolean = false): DocumentQuery {
return renderQuery(query, isAggregateCondition);
export function toMongoQuery(query: Query): DocumentQuery {
return renderQuery(query);
}

export function toMongoSort(sort: Sort): MongoSort {
Expand Down
31 changes: 25 additions & 6 deletions backend/lib/query/query-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export type Condition = {
| 'REGEX';
leftOperand: string;
rightOperand: unknown;
compareFields?: boolean;
};

export function isCondition(obj: unknown): obj is Condition {
Expand Down Expand Up @@ -67,35 +68,47 @@ function not(...values: ConditionOrConjunction[]): Conjunction {
};
}

function equals<T>(attributeName: string, value: T): Condition {
function equals<T>(attributeName: string, value: T, compareFields: boolean = false): Condition {
return {
condition: 'EQUALS',
leftOperand: attributeName,
rightOperand: value,
compareFields,
};
}

function notEqual<T>(attributeName: string, value: T): Condition {
function notEqual<T>(attributeName: string, value: T, compareFields: boolean = false): Condition {
return {
condition: 'NOT_EQUAL',
leftOperand: attributeName,
rightOperand: value,
compareFields,
};
}

function greaterThan<T>(attributeName: string, value: T): Condition {
function greaterThan<T>(
attributeName: string,
value: T,
compareFields: boolean = false,
): Condition {
return {
condition: 'GREATER_THAN',
leftOperand: attributeName,
rightOperand: value,
compareFields,
};
}

function greaterThanOrEqual<T>(attributeName: string, value: T): Condition {
function greaterThanOrEqual<T>(
attributeName: string,
value: T,
compareFields: boolean = false,
): Condition {
return {
condition: 'GREATER_THAN_OR_EQUAL',
leftOperand: attributeName,
rightOperand: value,
compareFields,
};
}

Expand All @@ -107,19 +120,25 @@ function contains<T>(attributeName: string, value: T | T[]): Condition {
};
}

function lessThan<T>(attributeName: string, value: T): Condition {
function lessThan<T>(attributeName: string, value: T, compareFields: boolean = false): Condition {
return {
condition: 'LESS_THAN',
leftOperand: attributeName,
rightOperand: value,
compareFields,
};
}

function lessThanOrEqual<T>(attributeName: string, value: T): Condition {
function lessThanOrEqual<T>(
attributeName: string,
value: T,
compareFields: boolean = false,
): Condition {
return {
condition: 'LESS_THAN_OR_EQUAL',
leftOperand: attributeName,
rightOperand: value,
compareFields,
};
}

Expand Down

0 comments on commit 4881665

Please sign in to comment.