diff --git a/src/find-options/FindOperator.ts b/src/find-options/FindOperator.ts index d9c0ce69d5..fd0dae0b96 100644 --- a/src/find-options/FindOperator.ts +++ b/src/find-options/FindOperator.ts @@ -1,7 +1,4 @@ import {FindOperatorType} from "./FindOperatorType"; -import {Connection} from "../"; -import {OracleDriver} from "../driver/oracle/OracleDriver"; -import {MysqlDriver} from "../driver/mysql/MysqlDriver"; /** * Find Operator used in Find Conditions. @@ -69,6 +66,13 @@ export class FindOperator { return this._multipleParameters; } + /** + * Gets the Type of this FindOperator + */ + get type(): string { + return this._type; + } + /** * Gets the final value needs to be used as parameter value. */ @@ -79,53 +83,13 @@ export class FindOperator { return this._value; } - // ------------------------------------------------------------------------- - // Public Methods - // ------------------------------------------------------------------------- - /** - * Gets SQL needs to be inserted into final query. + * Gets the child FindOperator if it exists */ - toSql(connection: Connection, aliasPath: string, parameters: string[]): string { - switch (this._type) { - case "not": - if (this._value instanceof FindOperator) { - return `NOT(${this._value.toSql(connection, aliasPath, parameters)})`; - } else { - return `${aliasPath} != ${parameters[0]}`; - } - case "lessThan": - return `${aliasPath} < ${parameters[0]}`; - case "lessThanOrEqual": - return `${aliasPath} <= ${parameters[0]}`; - case "moreThan": - return `${aliasPath} > ${parameters[0]}`; - case "moreThanOrEqual": - return `${aliasPath} >= ${parameters[0]}`; - case "equal": - return `${aliasPath} = ${parameters[0]}`; - case "like": - return `${aliasPath} LIKE ${parameters[0]}`; - case "between": - return `${aliasPath} BETWEEN ${parameters[0]} AND ${parameters[1]}`; - case "in": - if ((connection.driver instanceof OracleDriver || connection.driver instanceof MysqlDriver) && parameters.length === 0) { - return `${aliasPath} IN (null)`; - } - return `${aliasPath} IN (${parameters.join(", ")})`; - case "any": - return `${aliasPath} = ANY(${parameters[0]})`; - case "isNull": - return `${aliasPath} IS NULL`; - case "raw": - if (this.value instanceof Function) { - return this.value(aliasPath); - } else { - return `${aliasPath} = ${this.value}`; - } - } - - return ""; - } + get child(): FindOperator|undefined { + if (this._value instanceof FindOperator) + return this._value; + return undefined; + } } diff --git a/src/query-builder/QueryBuilder.ts b/src/query-builder/QueryBuilder.ts index a1756f351b..afb383ddd0 100644 --- a/src/query-builder/QueryBuilder.ts +++ b/src/query-builder/QueryBuilder.ts @@ -17,6 +17,7 @@ import {ColumnMetadata} from "../metadata/ColumnMetadata"; import {SqljsDriver} from "../driver/sqljs/SqljsDriver"; import {SqlServerDriver} from "../driver/sqlserver/SqlServerDriver"; import {OracleDriver} from "../driver/oracle/OracleDriver"; +import {MysqlDriver} from "../driver/mysql/MysqlDriver"; import {EntitySchema} from "../"; import {FindOperator} from "../find-options/FindOperator"; import {In} from "../find-options/operator/In"; @@ -816,8 +817,8 @@ export abstract class QueryBuilder { parameters.push(this.connection.driver.createParameter(parameterName + (parameterBaseCount + realParameterValueIndex), parameterIndex - 1)); }); } - return parameterValue.toSql(this.connection, aliasPath, parameters); + return this.computeFindOperatorExpression(parameterValue, aliasPath, parameters); } else { this.expressionMap.nativeParameters[parameterName] = parameterValue; parameterIndex++; @@ -856,6 +857,51 @@ export abstract class QueryBuilder { return ""; } + /** + * Gets SQL needs to be inserted into final query. + */ + protected computeFindOperatorExpression(operator: FindOperator, aliasPath: string, parameters: any[]): string { + switch (operator.type) { + case "not": + if (operator.child) { + return `NOT(${this.computeFindOperatorExpression(operator.child, aliasPath, parameters)})`; + } else { + return `${aliasPath} != ${parameters[0]}`; + } + case "lessThan": + return `${aliasPath} < ${parameters[0]}`; + case "lessThanOrEqual": + return `${aliasPath} <= ${parameters[0]}`; + case "moreThan": + return `${aliasPath} > ${parameters[0]}`; + case "moreThanOrEqual": + return `${aliasPath} >= ${parameters[0]}`; + case "equal": + return `${aliasPath} = ${parameters[0]}`; + case "like": + return `${aliasPath} LIKE ${parameters[0]}`; + case "between": + return `${aliasPath} BETWEEN ${parameters[0]} AND ${parameters[1]}`; + case "in": + if ((this.connection.driver instanceof OracleDriver || this.connection.driver instanceof MysqlDriver) && parameters.length === 0) { + return `${aliasPath} IN (null)`; + } + return `${aliasPath} IN (${parameters.join(", ")})`; + case "any": + return `${aliasPath} = ANY(${parameters[0]})`; + case "isNull": + return `${aliasPath} IS NULL`; + case "raw": + if (typeof operator.value === "function") { + return operator.value(aliasPath); + } else { + return `${aliasPath} = ${operator.value}`; + } + } + + throw new TypeError(`Unsupported FindOperator ${FindOperator.constructor.name}`); + } + /** * Creates a query builder used to execute sql queries inside this query builder. */