From 5a5ba748ad3ced7b7947decf2119acc2fa76875b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Sebasti=C3=A1n=20Valencia=20JIm=C3=A9nez?= Date: Mon, 29 Jan 2024 12:15:47 -0500 Subject: [PATCH] feat: add contains operator into sql criteria converter --- .../criteria/CriteriaToSqlConverter.ts | 22 ++++++++++++++++++- .../criteria/CriteriaToSqlConverter.test.ts | 10 +++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/03-criteria_to_sql/2-transform_criteria_to_sql/src/contexts/shared/infrastructure/criteria/CriteriaToSqlConverter.ts b/03-criteria_to_sql/2-transform_criteria_to_sql/src/contexts/shared/infrastructure/criteria/CriteriaToSqlConverter.ts index b6dbc54..81e0251 100644 --- a/03-criteria_to_sql/2-transform_criteria_to_sql/src/contexts/shared/infrastructure/criteria/CriteriaToSqlConverter.ts +++ b/03-criteria_to_sql/2-transform_criteria_to_sql/src/contexts/shared/infrastructure/criteria/CriteriaToSqlConverter.ts @@ -1,6 +1,14 @@ import { Criteria } from "../../domain/criteria/Criteria"; +import { Filter } from "../../domain/criteria/Filter"; +import { Operator } from "../../domain/criteria/FilterOperator"; + export class CriteriaToSqlConverter { + private operatorFunctionMap = { + [Operator.EQUAL.valueOf()]: this.toEQUAL, + [Operator.CONTAINS.valueOf()]: this.toCONTAINS, + }; + convert(fieldsToSelect: string[], tableName: string, criteria: Criteria): string { let query = `SELECT ${fieldsToSelect.join(", ")} FROM ${tableName}`; @@ -8,7 +16,11 @@ export class CriteriaToSqlConverter { query = query.concat(" WHERE "); const whereQuery = criteria.filters.value.map((filter) => { - return `${filter.field.value} ${filter.operator.value} '${filter.value.value}'`; + const operatorFunction = this.operatorFunctionMap[filter.operator.value]; + if (!operatorFunction) { + throw new Error(`No function defined for operator ${filter.operator.value}`); + } + return operatorFunction(filter); }); query = query.concat(whereQuery.join(" AND ")); @@ -22,4 +34,12 @@ export class CriteriaToSqlConverter { return `${query};`; } + + toEQUAL(filter: Filter): string { + return `${filter.field.value} = '${filter.value.value}'`; + } + + toCONTAINS(filter: Filter): string { + return `${filter.field.value} LIKE '%${filter.value.value}%'`; + } } diff --git a/03-criteria_to_sql/2-transform_criteria_to_sql/tests/contexts/shared/infrastructure/criteria/CriteriaToSqlConverter.test.ts b/03-criteria_to_sql/2-transform_criteria_to_sql/tests/contexts/shared/infrastructure/criteria/CriteriaToSqlConverter.test.ts index d4ba6b9..08efadf 100644 --- a/03-criteria_to_sql/2-transform_criteria_to_sql/tests/contexts/shared/infrastructure/criteria/CriteriaToSqlConverter.test.ts +++ b/03-criteria_to_sql/2-transform_criteria_to_sql/tests/contexts/shared/infrastructure/criteria/CriteriaToSqlConverter.test.ts @@ -93,4 +93,14 @@ describe("CriteriaToSqlConverter should", () => { "SELECT id, name, email FROM users WHERE name = 'Javier' AND email = 'javier@terra.es' ORDER BY id DESC;", ); }); + + it('Generate select with one filter and "CONTAINS" operator', () => { + const actualQuery = converter.convert( + ["id", "name"], + "users", + CriteriaMother.withOneFilter("name", "CONTAINS", "tuttodev"), + ); + + expect(actualQuery).toBe("SELECT id, name FROM users WHERE name LIKE '%tuttodev%';"); + }); });