refactoring query builder

This commit is contained in:
Umed Khudoiberdiev 2017-06-21 16:50:35 +05:00
parent 332439a2cb
commit a0dea7ec45
6 changed files with 45 additions and 96 deletions

View File

@ -50,16 +50,4 @@ export class DeleteQueryBuilder<Entity> extends QueryBuilder<Entity> {
return this;
}
/**
* Clones query builder as it is.
* Note: it uses new query runner, if you want query builder that uses exactly same query runner,
* you can create query builder this way: new DeleteQueryBuilder(queryBuilder) where queryBuilder
* is cloned QueryBuilder.
*/
clone(): DeleteQueryBuilder<Entity> {
const qb = new DeleteQueryBuilder<Entity>(this.connection);
qb.expressionMap = this.expressionMap.clone();
return qb;
}
}

View File

@ -35,16 +35,4 @@ export class InsertQueryBuilder<Entity> extends QueryBuilder<Entity> {
return this;
}
/**
* Clones query builder as it is.
* Note: it uses new query runner, if you want query builder that uses exactly same query runner,
* you can create query builder this way: new InsertQueryBuilder(queryBuilder) where queryBuilder
* is cloned QueryBuilder.
*/
clone(): InsertQueryBuilder<Entity> {
const qb = new InsertQueryBuilder<Entity>(this.connection);
qb.expressionMap = this.expressionMap.clone();
return qb;
}
}

View File

@ -1,55 +1,44 @@
import {RawSqlResultsToEntityTransformer} from "./transformer/RawSqlResultsToEntityTransformer";
import {EntityMetadata} from "../metadata/EntityMetadata";
import {ObjectLiteral} from "../common/ObjectLiteral";
import {QueryRunner} from "../query-runner/QueryRunner";
import {SqlServerDriver} from "../driver/sqlserver/SqlServerDriver";
import {Connection} from "../connection/Connection";
import {JoinOptions} from "./JoinOptions";
import {PessimisticLockTransactionRequiredError} from "./error/PessimisticLockTransactionRequiredError";
import {NoVersionOrUpdateDateColumnError} from "./error/NoVersionOrUpdateDateColumnError";
import {OptimisticLockVersionMismatchError} from "./error/OptimisticLockVersionMismatchError";
import {OptimisticLockCanNotBeUsedError} from "./error/OptimisticLockCanNotBeUsedError";
import {PostgresDriver} from "../driver/postgres/PostgresDriver";
import {MysqlDriver} from "../driver/mysql/MysqlDriver";
import {LockNotSupportedOnGivenDriverError} from "./error/LockNotSupportedOnGivenDriverError";
import {ColumnMetadata} from "../metadata/ColumnMetadata";
import {JoinAttribute} from "./JoinAttribute";
import {RelationIdAttribute} from "./relation-id/RelationIdAttribute";
import {RelationCountAttribute} from "./relation-count/RelationCountAttribute";
import {QueryExpressionMap} from "./QueryExpressionMap";
import {SelectQuery} from "./SelectQuery";
import {RelationIdLoader} from "./relation-id/RelationIdLoader";
import {RelationIdLoadResult} from "./relation-id/RelationIdLoadResult";
import {RelationIdMetadataToAttributeTransformer} from "./relation-id/RelationIdMetadataToAttributeTransformer";
import {RelationCountLoadResult} from "./relation-count/RelationCountLoadResult";
import {RelationCountLoader} from "./relation-count/RelationCountLoader";
import {RelationCountMetadataToAttributeTransformer} from "./relation-count/RelationCountMetadataToAttributeTransformer";
import {OracleDriver} from "../driver/oracle/OracleDriver";
import {Broadcaster} from "../subscriber/Broadcaster";
import {SelectQueryBuilder} from "./SelectQueryBuilder";
import {UpdateQueryBuilder} from "./UpdateQueryBuilder";
import {DeleteQueryBuilder} from "./DeleteQueryBuilder";
import {InsertQueryBuilder} from "./InsertQueryBuilder";
import {RelationQueryBuilder} from "./RelationQueryBuilder";
// todo: completely cover query builder with tests
// todo: entityOrProperty can be target name. implement proper behaviour if it is.
// todo: check in persistment if id exist on object and throw exception (can be in partial selection?)
// todo: fix problem with long aliases eg getMaxIdentifierLength
// todo: fix replacing in .select("COUNT(post.id) AS cnt") statement
// todo: implement joinAlways in relations and relationId
// todo: finish partial selection
// todo: sugar methods like: .addCount and .selectCount, selectCountAndMap, selectSum, selectSumAndMap, ...
// todo: implement @Select decorator
// todo: add quoting functions
// todo: .addCount and .addCountSelect()
// todo: add selectAndMap
// todo: tests for:
// todo: entityOrProperty can be target name. implement proper behaviour if it is.
// todo: think about subselect in joins syntax
// todo: COMPLETELY COVER QUERY BUILDER WITH TESTS
// todo: implement subselects for WHERE, FROM, SELECT
// .fromSubSelect()
// .whereSubSelect()
// .addSubSelect()
// .addSubSelectAndMap()
// use qb => qb.select().from().where() syntax where needed
// todo: SUBSELECT IMPLEMENTATION
// .whereSubselect(qb => qb.select().from().where())
// todo: also create qb.createSubQueryBuilder()
// todo: check in persistment if id exist on object and throw exception (can be in partial selection?)
// todo: STREAMING
// todo: implement relation/entity loading and setting them into properties within a separate query
// .loadAndMap("post.categories", "post.categories", qb => ...)
// .loadAndMap("post.categories", Category, qb => ...)
// todo: implement streaming
// .stream(): ReadStream
/**
* Allows to build complex sql queries in a fashion way and execute those queries.
@ -316,14 +305,6 @@ export abstract class QueryBuilder<Entity> {
return parameters;
}
/**
* Gets generated sql that will be executed.
* Parameters in the query are escaped for the currently used driver.
*/
getSql(): string {
return this.connection.driver.escapeQueryWithParameters(this.getQuery(), this.expressionMap.parameters)[0];
}
/**
* Gets generated sql query without parameters being replaced.
*/
@ -340,6 +321,14 @@ export abstract class QueryBuilder<Entity> {
return sql.trim();
}
/**
* Gets generated sql that will be executed.
* Parameters in the query are escaped for the currently used driver.
*/
getSql(): string {
return this.connection.driver.escapeQueryWithParameters(this.getQuery(), this.expressionMap.parameters)[0];
}
/**
* Gets sql to be executed with all parameters used in it.
*/
@ -371,6 +360,25 @@ export abstract class QueryBuilder<Entity> {
}
}
/**
* Creates a completely new query builder.
*/
createQueryBuilder(): this {
return new (this.constructor as any)(this.connection);
}
/**
* Clones query builder as it is.
* Note: it uses new query runner, if you want query builder that uses exactly same query runner,
* you can create query builder using its constructor, for example new SelectQueryBuilder(queryBuilder)
* where queryBuilder is cloned QueryBuilder.
*/
clone(): this {
const qb = this.createQueryBuilder();
qb.expressionMap = this.expressionMap.clone();
return qb;
}
/**
* Disables escaping.
*/

View File

@ -60,18 +60,6 @@ export class RelationQueryBuilder<Entity> extends QueryBuilder<Entity> {
return [];
}
/**
* Clones query builder as it is.
* Note: it uses new query runner, if you want query builder that uses exactly same query runner,
* you can create query builder this way: new RelationQueryBuilder(queryBuilder) where queryBuilder
* is cloned QueryBuilder.
*/
clone(): RelationQueryBuilder<Entity> {
const qb = new RelationQueryBuilder<Entity>(this.connection);
qb.expressionMap = this.expressionMap.clone();
return qb;
}
}

View File

@ -31,6 +31,7 @@ import {DeleteQueryBuilder} from "./DeleteQueryBuilder";
import {InsertQueryBuilder} from "./InsertQueryBuilder";
import {QueryBuilder} from "./QueryBuilder";
/**
* Allows to build complex sql queries in a fashion way and execute those queries.
*/
@ -710,18 +711,6 @@ export class SelectQueryBuilder<Entity> extends QueryBuilder<Entity> {
return result;
}
/**
* Clones query builder as it is.
* Note: it uses new query runner, if you want query builder that uses exactly same query runner,
* you can create query builder this way: new SelectQueryBuilder(queryBuilder) where queryBuilder
* is cloned QueryBuilder.
*/
clone(): SelectQueryBuilder<Entity> {
const qb = new SelectQueryBuilder<Entity>(this.connection);
qb.expressionMap = this.expressionMap.clone();
return qb;
}
/**
* Enables special query builder options.
*

View File

@ -49,16 +49,4 @@ export class UpdateQueryBuilder<Entity> extends QueryBuilder<Entity> {
return this;
}
/**
* Clones query builder as it is.
* Note: it uses new query runner, if you want query builder that uses exactly same query runner,
* you can create query builder this way: new UpdateQueryBuilder(queryBuilder) where queryBuilder
* is cloned QueryBuilder.
*/
clone(): UpdateQueryBuilder<Entity> {
const qb = new UpdateQueryBuilder<Entity>(this.connection);
qb.expressionMap = this.expressionMap.clone();
return qb;
}
}