added createQueryRunner method into connection object

This commit is contained in:
Umed Khudoiberdiev 2017-06-19 11:39:51 +05:00
parent 5f403335d6
commit b82b2f31a8
11 changed files with 31 additions and 21 deletions

View File

@ -72,6 +72,7 @@ Now
`EntityManager` now simply use them from the connection.
* refactored how query runner works, removed query runner provider
* fixed some issues with sqlite, sqlite now strongly works on a single connection
* `Connection` how has `createQueryRunner` that can be used to control database connection and its transaction state
### BUG FIXES

View File

@ -31,7 +31,7 @@ export class QueryCommand {
let queryRunner: QueryRunner|undefined = undefined;
try {
queryRunner = await connection.driver.createQueryRunner();
queryRunner = await connection.createQueryRunner();
const queryResult = await queryRunner.query(argv._[1]);
connection.logger.log("info", "Query executed. Result: " + JSON.stringify(queryResult));

View File

@ -206,7 +206,7 @@ export class Connection {
* Can be used only after connection to the database is established.
*/
async dropDatabase(): Promise<void> {
const queryRunner = await this.driver.createQueryRunner();
const queryRunner = await this.createQueryRunner();
await queryRunner.clearDatabase();
await queryRunner.release();
}
@ -312,7 +312,7 @@ export class Connection {
if (queryRunner && queryRunner.isReleased)
throw new QueryRunnerProviderAlreadyReleasedError();
const usedQueryRunner = queryRunner || this.driver.createQueryRunner();
const usedQueryRunner = queryRunner || this.createQueryRunner();
const transactionEntityManager = new EntityManagerFactory().create(this, usedQueryRunner);
try {
@ -343,7 +343,7 @@ export class Connection {
if (queryRunner && queryRunner.isReleased)
throw new QueryRunnerProviderAlreadyReleasedError();
const usedQueryRunner = queryRunner || this.driver.createQueryRunner();
const usedQueryRunner = queryRunner || this.createQueryRunner();
try {
return await usedQueryRunner.query(query, parameters); // await is needed here because we are using finally
@ -382,6 +382,15 @@ export class Connection {
}
}
/**
* Creates a query runner used for perform queries on a single database connection.
* Using query runners you can control your queries to execute using single database connection and
* manually control your database transaction.
*/
createQueryRunner(): QueryRunner {
return this.driver.createQueryRunner();
}
/**
* Creates a new entity manager with a single opened connection to the database.
* This may be useful if you want to perform all db queries within one connection.
@ -389,7 +398,7 @@ export class Connection {
*/
createIsolatedManager(queryRunner?: QueryRunner): EntityManager {
if (!queryRunner)
queryRunner = this.driver.createQueryRunner();
queryRunner = this.createQueryRunner();
return new EntityManagerFactory().create(this, queryRunner);
}
@ -401,7 +410,7 @@ export class Connection {
*/
createIsolatedRepository<Entity>(entityClassOrName: ObjectType<Entity>|string, queryRunner?: QueryRunner): Repository<Entity> {
if (!queryRunner)
queryRunner = this.driver.createQueryRunner();
queryRunner = this.createQueryRunner();
return new RepositoryFactory().createRepository(this, this.getMetadata(entityClassOrName), queryRunner);
}
@ -413,7 +422,7 @@ export class Connection {
*/
createIsolatedSpecificRepository<Entity>(entityClassOrName: ObjectType<Entity>|string, queryRunner?: QueryRunner): SpecificRepository<Entity> {
if (!queryRunner)
queryRunner = this.driver.createQueryRunner();
queryRunner = this.createQueryRunner();
return new RepositoryFactory().createSpecificRepository(this, this.getMetadata(entityClassOrName), queryRunner);
}

View File

@ -568,7 +568,7 @@ export class EntityManager {
*/
async clear<Entity>(entityClass: ObjectType<Entity>|string): Promise<void> {
const metadata = this.connection.getMetadata(entityClass);
const queryRunner = this.queryRunner || this.connection.driver.createQueryRunner();
const queryRunner = this.queryRunner || this.connection.createQueryRunner();
try {
return await queryRunner.truncate(metadata.tableName); // await is needed here because we are using finally
@ -735,7 +735,7 @@ export class EntityManager {
*/
protected async saveOne(target: Function|string, entity: any, options?: SaveOptions): Promise<void> {
const metadata = this.connection.getMetadata(target);
const queryRunner = this.queryRunner || this.connection.driver.createQueryRunner();
const queryRunner = this.queryRunner || this.connection.createQueryRunner();
try {
const transactionEntityManager = this.connection.createIsolatedManager(queryRunner);
// transactionEntityManager.data =
@ -757,7 +757,7 @@ export class EntityManager {
*/
protected async removeOne(target: Function|string, entity: any, options?: RemoveOptions): Promise<void> {
const metadata = this.connection.getMetadata(target);
const queryRunner = this.queryRunner || this.connection.driver.createQueryRunner();
const queryRunner = this.queryRunner || this.connection.createQueryRunner();
try {
const transactionEntityManager = this.connection.createIsolatedManager(queryRunner);

View File

@ -22,7 +22,7 @@ export class MigrationExecutor {
// -------------------------------------------------------------------------
constructor(protected connection: Connection, queryRunner?: QueryRunner) {
this.queryRunner = queryRunner || connection.driver.createQueryRunner();
this.queryRunner = queryRunner || connection.createQueryRunner();
}
// -------------------------------------------------------------------------

View File

@ -1746,7 +1746,7 @@ export class QueryBuilder<Entity> {
return this.queryRunner;
} else { // means its empty
return this.connection.driver.createQueryRunner();
return this.connection.createQueryRunner();
}
}

View File

@ -70,7 +70,7 @@ export class SpecificRepository<Entity extends ObjectLiteral> {
}
const usedQueryRunner = this.queryRunner || this.connection.driver.createQueryRunner();
const usedQueryRunner = this.queryRunner || this.connection.createQueryRunner();
await usedQueryRunner.update(table, values, conditions);
if (!this.queryRunner) // means created by this method
await usedQueryRunner.release();
@ -117,7 +117,7 @@ export class SpecificRepository<Entity extends ObjectLiteral> {
conditions[relation.joinColumns[0].referencedColumn!.databaseName] = entityId;
}
const usedQueryRunner = this.queryRunner || this.connection.driver.createQueryRunner();
const usedQueryRunner = this.queryRunner || this.connection.createQueryRunner();
await usedQueryRunner.update(table, values, conditions);
if (!this.queryRunner) // means created by this method
await usedQueryRunner.release();
@ -150,7 +150,7 @@ export class SpecificRepository<Entity extends ObjectLiteral> {
if (!relation.isManyToMany)
throw new Error(`Only many-to-many relation supported for this operation. However ${this.metadata.name}#${propertyPath} relation type is ${relation.relationType}`);
const usedQueryRunner = this.queryRunner || this.connection.driver.createQueryRunner();
const usedQueryRunner = this.queryRunner || this.connection.createQueryRunner();
const insertPromises = relatedEntityIds.map(relatedEntityId => {
const values: any = {};
if (relation.isOwning) {
@ -196,7 +196,7 @@ export class SpecificRepository<Entity extends ObjectLiteral> {
if (!relation.isManyToMany)
throw new Error(`Only many-to-many relation supported for this operation. However ${this.metadata.name}#${propertyPath} relation type is ${relation.relationType}`);
const usedQueryRunner = this.queryRunner || this.connection.driver.createQueryRunner();
const usedQueryRunner = this.queryRunner || this.connection.createQueryRunner();
try {
const insertPromises = entityIds.map(entityId => {
const values: any = {};

View File

@ -57,7 +57,7 @@ export class RdbmsSchemaBuilder implements SchemaBuilder {
* Creates complete schemas for the given entity metadatas.
*/
async build(): Promise<void> {
this.queryRunner = await this.connection.driver.createQueryRunner();
this.queryRunner = await this.connection.createQueryRunner();
this.tableSchemas = await this.loadTableSchemas();
await this.queryRunner.startTransaction();

View File

@ -220,7 +220,7 @@ describe("Connection", () => {
afterEach(() => closeTestingConnections(connections));
it("database should be empty after schema sync", () => Promise.all(connections.map(async connection => {
await connection.syncSchema(true);
const queryRunner = connection.driver.createQueryRunner();
const queryRunner = connection.createQueryRunner();
let schema = await queryRunner.loadTableSchemas(["view"]);
await queryRunner.release();
expect(schema.some(table => table.name === "view")).to.be.false;
@ -304,7 +304,7 @@ describe("Connection", () => {
const commentRepo = connection.getRepository(CommentV1);
await commentRepo.save(comment);
const queryRunner = connection.driver.createQueryRunner();
const queryRunner = connection.createQueryRunner();
const rows = await queryRunner.query(`select * from "${schemaName}"."comment" where id = $1`, [comment.id]);
await queryRunner.release();
expect(rows[0]["context"]).to.be.eq(comment.context);

View File

@ -16,7 +16,7 @@ describe("jsonb type", () => {
it("should make correct schema with Postgres' jsonb type", () => Promise.all(connections.map(async connection => {
await connection.syncSchema(true);
const queryRunner = connection.driver.createQueryRunner();
const queryRunner = connection.createQueryRunner();
let schema = await queryRunner.loadTableSchema("record");
await queryRunner.release();
expect(schema).not.to.be.empty;

View File

@ -22,7 +22,7 @@ describe("uuid type", () => {
it("should make correct schema with Postgres' uuid type", () => Promise.all(connections.map(async connection => {
await connection.syncSchema(true);
const queryRunner = connection.driver.createQueryRunner();
const queryRunner = connection.createQueryRunner();
let schema = await queryRunner.loadTableSchema("record");
await queryRunner.release();
expect(schema).not.to.be.empty;