Skip to content

Commit

Permalink
fix(core): Fix "contains" list filter operator for postgres
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelbromley committed Jan 28, 2020
1 parent 50fbae6 commit c3898a6
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 34 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Type } from '@vendure/common/lib/shared-types';
import { Connection } from 'typeorm';
import { ColumnMetadata } from 'typeorm/metadata/ColumnMetadata';

export function getColumnMetadata<T>(connection: Connection, entity: Type<T>) {
const metadata = connection.getMetadata(entity);
const columns = metadata.columns;
let translationColumns: ColumnMetadata[] = [];
const relations = metadata.relations;

const translationRelation = relations.find(r => r.propertyName === 'translations');
if (translationRelation) {
const translationMetadata = connection.getMetadata(translationRelation.type);
translationColumns = columns.concat(translationMetadata.columns.filter(c => !c.relationMetadata));
}
const alias = metadata.name.toLowerCase();
return { columns, translationColumns, alias };
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Type } from '@vendure/common/lib/shared-types';
import { assertNever } from '@vendure/common/lib/shared-utils';
import { Connection } from 'typeorm';
import { ColumnMetadata } from 'typeorm/metadata/ColumnMetadata';
import { Connection, ConnectionOptions } from 'typeorm';

import { UserInputError } from '../../../common/error/errors';
import {
Expand All @@ -14,6 +13,8 @@ import {
} from '../../../common/types/common-types';
import { VendureEntity } from '../../../entity/base/base.entity';

import { getColumnMetadata } from './get-column-metadata';

export interface WhereCondition {
clause: string;
parameters: { [param: string]: string | number };
Expand All @@ -30,21 +31,9 @@ export function parseFilterParams<T extends VendureEntity>(
if (!filterParams) {
return [];
}

const metadata = connection.getMetadata(entity);
const columns = metadata.columns;
let translationColumns: ColumnMetadata[] = [];
const relations = metadata.relations;

const translationRelation = relations.find(r => r.propertyName === 'translations');
if (translationRelation) {
const translationMetadata = connection.getMetadata(translationRelation.type);
translationColumns = columns.concat(translationMetadata.columns.filter(c => !c.relationMetadata));
}

const { columns, translationColumns, alias } = getColumnMetadata(connection, entity);
const output: WhereCondition[] = [];
const alias = metadata.name.toLowerCase();

const dbType = connection.options.type;
let argIndex = 1;
for (const [key, operation] of Object.entries(filterParams)) {
if (operation) {
Expand All @@ -57,7 +46,13 @@ export function parseFilterParams<T extends VendureEntity>(
} else {
throw new UserInputError('error.invalid-filter-field');
}
const condition = buildWhereCondition(fieldName, operator as Operator, operand, argIndex);
const condition = buildWhereCondition(
fieldName,
operator as Operator,
operand,
argIndex,
dbType,
);
output.push(condition);
argIndex++;
}
Expand All @@ -67,16 +62,23 @@ export function parseFilterParams<T extends VendureEntity>(
return output;
}

function buildWhereCondition(fieldName: string, operator: Operator, operand: any, argIndex: number): WhereCondition {
function buildWhereCondition(
fieldName: string,
operator: Operator,
operand: any,
argIndex: number,
dbType: ConnectionOptions['type'],
): WhereCondition {
switch (operator) {
case 'eq':
return {
clause: `${fieldName} = :arg${argIndex}`,
parameters: { [`arg${argIndex}`]: operand },
};
case 'contains':
const LIKE = dbType === 'postgres' ? 'ILIKE' : 'LIKE';
return {
clause: `${fieldName} LIKE :arg${argIndex}`,
clause: `${fieldName} ${LIKE} :arg${argIndex}`,
parameters: { [`arg${argIndex}`]: `%${operand.trim()}%` },
};
case 'lt':
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,5 +145,8 @@ export class MockConnection {
columns: this.columnsMap.get(entity) || [],
relations: this.relationsMap.get(entity) || [],
};
}
};
readonly options = {
type: 'sqljs',
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { UserInputError } from '../../../common/error/errors';
import { NullOptionals, SortParameter } from '../../../common/types/common-types';
import { VendureEntity } from '../../../entity/base/base.entity';

import { getColumnMetadata } from './get-column-metadata';

/**
* Parses the provided SortParameter array against the metadata of the given entity, ensuring that only
* valid fields are being sorted against. The output assumes
Expand All @@ -22,21 +24,8 @@ export function parseSortParams<T extends VendureEntity>(
if (!sortParams || Object.keys(sortParams).length === 0) {
return {};
}

const metadata = connection.getMetadata(entity);
const columns = metadata.columns;
let translationColumns: ColumnMetadata[] = [];
const relations = metadata.relations;

const translationRelation = relations.find(r => r.propertyName === 'translations');
if (translationRelation) {
const translationMetadata = connection.getMetadata(translationRelation.type);
translationColumns = columns.concat(translationMetadata.columns.filter(c => !c.relationMetadata));
}

const { columns, translationColumns, alias } = getColumnMetadata(connection, entity);
const output: OrderByCondition = {};
const alias = metadata.name.toLowerCase();

for (const [key, order] of Object.entries(sortParams)) {
if (columns.find(c => c.propertyName === key)) {
output[`${alias}.${key}`] = order as any;
Expand Down

0 comments on commit c3898a6

Please sign in to comment.