From 29ff6c1279a4d5d326bc639afe33e73b3fec8d4e Mon Sep 17 00:00:00 2001 From: Etienne Noel Date: Wed, 5 Jun 2024 13:20:56 -0700 Subject: [PATCH 1/4] - Fix the interface. --- .../src/interfaces/mysql-client.interface.ts | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/mysql/src/interfaces/mysql-client.interface.ts b/packages/mysql/src/interfaces/mysql-client.interface.ts index cb78befb..3d25ee6b 100644 --- a/packages/mysql/src/interfaces/mysql-client.interface.ts +++ b/packages/mysql/src/interfaces/mysql-client.interface.ts @@ -6,10 +6,10 @@ import {SearchQuery, SearchResult} from "@pristine-ts/mysql-common"; export interface MysqlClientInterface { /** * This method returns a pool of connections to the database. - * @param databaseName + * @param configUniqueKeyname * @param force */ - getPool(databaseName: string, force: boolean): Promise; + getPool(configUniqueKeyname: string, force: boolean): Promise; /** * This method returns the table metadata for a given class. @@ -52,11 +52,11 @@ export interface MysqlClientInterface { /** * This method returns the column name for a given class and property name. - * @param databaseName + * @param configUniqueKeyname * @param sqlStatement * @param values */ - executeSql(databaseName: string, sqlStatement: string, values: any[]): Promise + executeSql(configUniqueKeyname: string, sqlStatement: string, values: any[]): Promise /** * This method maps the results to a given class type. @@ -67,39 +67,39 @@ export interface MysqlClientInterface { /** * This method returns a single element from the database. - * @param databaseName + * @param configUniqueKeyname * @param classType * @param primaryKey */ - get(databaseName: string, classType: { new(): T; }, primaryKey: string | number): Promise + get(configUniqueKeyname: string, classType: { new(): T; }, primaryKey: string | number): Promise /** * This method creates a new element in the database. - * @param databaseName + * @param configUniqueKeyname * @param element */ - create(databaseName: string, element: T): Promise + create(configUniqueKeyname: string, element: T): Promise /** * This method updates an element in the database. - * @param databaseName + * @param configUniqueKeyname * @param element */ - update(databaseName: string, element: T): Promise + update(configUniqueKeyname: string, element: T): Promise /** * This method deletes an element in the database. - * @param databaseName + * @param configUniqueKeyname * @param classType * @param primaryKey */ - delete(databaseName: string, classType: { new(): T; }, primaryKey: string | number): Promise + delete(configUniqueKeyname: string, classType: { new(): T; }, primaryKey: string | number): Promise /** * This method searches the database. - * @param databaseName + * @param configUniqueKeyname * @param classType * @param query */ - search(databaseName: string, classType: { new(): T; }, query: SearchQuery): Promise> + search(configUniqueKeyname: string, classType: { new(): T; }, query: SearchQuery): Promise> } From 276ed95ac7f923d8b6d3bdb2806467e98fa95292 Mon Sep 17 00:00:00 2001 From: Etienne Noel Date: Wed, 5 Jun 2024 13:45:55 -0700 Subject: [PATCH 2/4] - Improving the mysql search with filters. --- .../src/enums/filtering-operator.enum.ts | 8 ++++ .../search-query-parameters.interface.ts | 5 +++ packages/mysql-common/src/models/models.ts | 1 + .../src/models/search-field-filter.model.ts | 24 ++++++++++++ .../src/models/search-query.model.ts | 24 ++++++++++++ packages/mysql/src/clients/mysql.client.ts | 37 +++++++++++++++++++ 6 files changed, 99 insertions(+) create mode 100644 packages/mysql-common/src/enums/filtering-operator.enum.ts create mode 100644 packages/mysql-common/src/models/search-field-filter.model.ts diff --git a/packages/mysql-common/src/enums/filtering-operator.enum.ts b/packages/mysql-common/src/enums/filtering-operator.enum.ts new file mode 100644 index 00000000..544c7174 --- /dev/null +++ b/packages/mysql-common/src/enums/filtering-operator.enum.ts @@ -0,0 +1,8 @@ +export enum FilteringOperatorEnum { + Equal = "eq", + NotEqual = "ne", + GreaterThan = "gt", + GreaterThanOrEqual = "gte", + LessThan = "lt", + LessThanOrEqual = "lte", +} \ No newline at end of file diff --git a/packages/mysql-common/src/interfaces/search-query-parameters.interface.ts b/packages/mysql-common/src/interfaces/search-query-parameters.interface.ts index 1935c878..1d20a99a 100644 --- a/packages/mysql-common/src/interfaces/search-query-parameters.interface.ts +++ b/packages/mysql-common/src/interfaces/search-query-parameters.interface.ts @@ -30,4 +30,9 @@ export interface SearchQueryParametersInterface { * Separated by commas string of `field:asc|desc` to sort the results. */ sort?: string; + + /** + * Separated by commas string of `filter:field:operator:value` to filter the results. + */ + filters?: string; } diff --git a/packages/mysql-common/src/models/models.ts b/packages/mysql-common/src/models/models.ts index e4e5ea8c..729c224a 100644 --- a/packages/mysql-common/src/models/models.ts +++ b/packages/mysql-common/src/models/models.ts @@ -1,3 +1,4 @@ +export * from "./search-field-filter.model"; export * from "./search-query.model"; export * from "./search-query-field.model"; export * from "./search-result.model"; diff --git a/packages/mysql-common/src/models/search-field-filter.model.ts b/packages/mysql-common/src/models/search-field-filter.model.ts new file mode 100644 index 00000000..44c0518a --- /dev/null +++ b/packages/mysql-common/src/models/search-field-filter.model.ts @@ -0,0 +1,24 @@ +import {FilteringOperatorEnum} from "../enums/filtering-operator.enum"; + +export class SearchFieldFilter { +/** + * The name of the field to filter. + */ + field: string; + + /** + * The value to filter. + */ + value: string; + + /** + * The operator to use to filter. + */ + operator: FilteringOperatorEnum; + + constructor(field: string, operator: FilteringOperatorEnum, value: string) { + this.field = field; + this.value = value; + this.operator = operator; + } +} \ No newline at end of file diff --git a/packages/mysql-common/src/models/search-query.model.ts b/packages/mysql-common/src/models/search-query.model.ts index 1b150eac..9a0320fa 100644 --- a/packages/mysql-common/src/models/search-query.model.ts +++ b/packages/mysql-common/src/models/search-query.model.ts @@ -1,6 +1,8 @@ import {SearchQueryField} from "./search-query-field.model"; import {SortOrderEnum} from "../enums/sort-order.enum"; import {SearchQueryParametersInterface} from "../interfaces/search-query-parameters.interface"; +import {SearchFieldFilter} from "./search-field-filter.model"; +import {FilteringOperatorEnum} from "../enums/filtering-operator.enum"; export class SearchQuery { /** @@ -25,6 +27,11 @@ export class SearchQuery { */ query?: string; + /** + * The filters to apply to the search. + */ + filters: SearchFieldFilter[] = []; + constructor(options?: Partial) { this.fields = options?.fields ?? []; this.page = options?.page ?? 1; @@ -41,6 +48,14 @@ export class SearchQuery { return this.fields.find((field) => field.field === fieldName); } + /** + * This method adds a filter to the search query. + * @param filter + */ + addFilter(filter: SearchFieldFilter) { + this.filters.push(filter); + } + clearSort(field: string) { const fieldToClear = this.getField(field); @@ -119,6 +134,14 @@ export class SearchQuery { }); } + if(queryStrings.filters) { + queryStrings.filters.split(",").forEach((filter) => { + const [fieldName, operator, value] = filter.split(":"); + + this.addFilter(new SearchFieldFilter(fieldName, operator as FilteringOperatorEnum, value)); + }); + } + if(queryStrings.excludeFieldsFromResponse) { queryStrings.excludeFieldsFromResponse?.split(",").forEach((fieldName) => { const field = this.getField(fieldName); @@ -144,6 +167,7 @@ export class SearchQuery { excludeFieldsFromResponse: this.fields.filter((field) => field.exclude).map((field) => field.field).join(","), fields: this.fields.filter((field) => field.includeExplicitly).map((field) => field.field).join(","), sort: this.fields.filter((field) => field.order !== undefined).map((field) => `${field.field}:${field.order}`).join(","), + filters: this.filters.map((filter) => `${filter.field}:${filter.operator}:${filter.value}`).join(",") }; } } diff --git a/packages/mysql/src/clients/mysql.client.ts b/packages/mysql/src/clients/mysql.client.ts index 660c3dd6..f4e9a338 100644 --- a/packages/mysql/src/clients/mysql.client.ts +++ b/packages/mysql/src/clients/mysql.client.ts @@ -12,6 +12,7 @@ import {SearchQuery, SearchResult} from "@pristine-ts/mysql-common"; import {ServiceDefinitionTagEnum, tag} from "@pristine-ts/common"; import {MysqlConfig} from "../configs/mysql.config"; import {MysqlConfigProviderInterface} from "../interfaces/mysql-config-provider.interface"; +import {FilteringOperatorEnum} from "@pristine-ts/mysql-common/dist/types/enums/filtering-operator.enum"; @tag("MysqlClientInterface") @injectable() @@ -342,6 +343,42 @@ export class MysqlClient implements MysqlClientInterface { fieldsToSearch.forEach(field => sqlValues.push("%" + query.query + "%")); } + if(query.filters.length > 0) { + query.filters.forEach(filter => { + const column = this.getColumnName(classType, filter.field); + + let operator = null; + + switch (filter.operator as FilteringOperatorEnum) { + case FilteringOperatorEnum.Equal: + operator = "="; + break; + case FilteringOperatorEnum.NotEqual: + operator = "!="; + break; + case FilteringOperatorEnum.GreaterThan: + operator = ">"; + break; + case FilteringOperatorEnum.GreaterThanOrEqual: + operator = ">="; + break; + case FilteringOperatorEnum.LessThan: + operator = "<"; + break; + case FilteringOperatorEnum.LessThanOrEqual: + operator = "<="; + break; + } + + if(operator === null) { + return; + } + + sql += " AND " + column + " " + operator + " ?"; + sqlValues.push(filter.value); + }); + } + // // ORDERING // From c37bf17b1a891e692816f7126edfb10340e04aad Mon Sep 17 00:00:00 2001 From: Etienne Noel Date: Wed, 5 Jun 2024 13:46:18 -0700 Subject: [PATCH 3/4] - Update. --- packages/mysql/src/clients/mysql.client.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/mysql/src/clients/mysql.client.ts b/packages/mysql/src/clients/mysql.client.ts index f4e9a338..4075de8d 100644 --- a/packages/mysql/src/clients/mysql.client.ts +++ b/packages/mysql/src/clients/mysql.client.ts @@ -373,7 +373,7 @@ export class MysqlClient implements MysqlClientInterface { if(operator === null) { return; } - + sql += " AND " + column + " " + operator + " ?"; sqlValues.push(filter.value); }); From 7a0530cb659fbf7648612ecdbd388e3022337485 Mon Sep 17 00:00:00 2001 From: Etienne Noel Date: Wed, 5 Jun 2024 13:50:33 -0700 Subject: [PATCH 4/4] - Update. --- packages/mysql-common/src/enums/enums.ts | 1 + packages/mysql/src/clients/mysql.client.ts | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/mysql-common/src/enums/enums.ts b/packages/mysql-common/src/enums/enums.ts index 75860ebe..3a6493c4 100644 --- a/packages/mysql-common/src/enums/enums.ts +++ b/packages/mysql-common/src/enums/enums.ts @@ -1 +1,2 @@ +export * from "./filtering-operator.enum"; export * from "./sort-order.enum"; diff --git a/packages/mysql/src/clients/mysql.client.ts b/packages/mysql/src/clients/mysql.client.ts index 4075de8d..3d211dc9 100644 --- a/packages/mysql/src/clients/mysql.client.ts +++ b/packages/mysql/src/clients/mysql.client.ts @@ -8,11 +8,10 @@ import {MysqlModuleKeyname} from "../mysql.module.keyname"; import {createPool, Pool} from "mysql2/promise"; import {LogHandlerInterface} from "@pristine-ts/logging"; import {DataMapper} from "@pristine-ts/data-mapping-common"; -import {SearchQuery, SearchResult} from "@pristine-ts/mysql-common"; +import {SearchQuery, SearchResult, FilteringOperatorEnum} from "@pristine-ts/mysql-common"; import {ServiceDefinitionTagEnum, tag} from "@pristine-ts/common"; import {MysqlConfig} from "../configs/mysql.config"; import {MysqlConfigProviderInterface} from "../interfaces/mysql-config-provider.interface"; -import {FilteringOperatorEnum} from "@pristine-ts/mysql-common/dist/types/enums/filtering-operator.enum"; @tag("MysqlClientInterface") @injectable()