This commit is contained in:
Umed Khudoiberdiev 2017-07-27 17:38:54 +05:00
parent cd757e0a0e
commit f536c1144d
13 changed files with 65 additions and 98 deletions

View File

@ -152,4 +152,18 @@ getConnectionOptions().then(connectionOptions => {
logger: new MyCustomLogger()
}))
});
```
Logger methods can accept `QueryRunner` when its available. Its helpful if you want to log additional data.
Also via query runner you can get access to additional data passed during persist/remove. For example:
```typescript
// user sends request during entity save
postRepository.save(post, { data: { request: request } });
// in logger you can access it this way:
logQuery(query: string, parameters?: any[], queryRunner?: QueryRunner) {
const requestUrl = queryRunner && queryRunner.data["request"] ? "(" + queryRunner.data["request"].url + ") " : "";
console.log(requestUrl + "executing query: " + sql);
}
```

View File

@ -71,6 +71,12 @@ export class MongoQueryRunner implements QueryRunner {
*/
isTransactionActive = false;
/**
* Stores temporarily user data.
* Useful for sharing data with subscribers.
*/
data = {};
/**
* Real database connection from a connection pool used to perform queries.
*/

View File

@ -51,6 +51,12 @@ export class MysqlQueryRunner implements QueryRunner {
*/
isTransactionActive = false;
/**
* Stores temporarily user data.
* Useful for sharing data with subscribers.
*/
data = {};
// -------------------------------------------------------------------------
// Protected Properties
// -------------------------------------------------------------------------

View File

@ -52,6 +52,12 @@ export class OracleQueryRunner implements QueryRunner {
*/
isTransactionActive = false;
/**
* Stores temporarily user data.
* Useful for sharing data with subscribers.
*/
data = {};
// -------------------------------------------------------------------------
// Protected Properties
// -------------------------------------------------------------------------

View File

@ -51,6 +51,12 @@ export class PostgresQueryRunner implements QueryRunner {
*/
isTransactionActive = false;
/**
* Stores temporarily user data.
* Useful for sharing data with subscribers.
*/
data = {};
// -------------------------------------------------------------------------
// Protected Properties
// -------------------------------------------------------------------------

View File

@ -56,6 +56,12 @@ export class SqliteQueryRunner implements QueryRunner {
*/
isTransactionActive = false;
/**
* Stores temporarily user data.
* Useful for sharing data with subscribers.
*/
data = {};
// -------------------------------------------------------------------------
// Protected Properties
// -------------------------------------------------------------------------

View File

@ -51,6 +51,12 @@ export class SqlServerQueryRunner implements QueryRunner {
*/
isTransactionActive = false;
/**
* Stores temporarily user data.
* Useful for sharing data with subscribers.
*/
data = {};
// -------------------------------------------------------------------------
// Protected Properties
// -------------------------------------------------------------------------

View File

@ -56,6 +56,12 @@ export class WebsqlQueryRunner implements QueryRunner {
*/
isTransactionActive = false;
/**
* Stores temporarily user data.
* Useful for sharing data with subscribers.
*/
data = {};
// -------------------------------------------------------------------------
// Protected Properties
// -------------------------------------------------------------------------

View File

@ -2,7 +2,6 @@ import {Connection} from "../connection/Connection";
import {FindManyOptions} from "../find-options/FindManyOptions";
import {ObjectType} from "../common/ObjectType";
import {QueryRunnerProviderAlreadyReleasedError} from "../error/QueryRunnerProviderAlreadyReleasedError";
import {ObjectLiteral} from "../common/ObjectLiteral";
import {FindOneOptions} from "../find-options/FindOneOptions";
import {DeepPartial} from "../common/DeepPartial";
import {RemoveOptions} from "../repository/RemoveOptions";
@ -54,12 +53,6 @@ export class EntityManager {
// Protected Properties
// -------------------------------------------------------------------------
/**
* Stores temporarily user data.
* Useful for sharing data with subscribers.
*/
protected data: ObjectLiteral = {};
/**
* Once created and then reused by en repositories.
*/
@ -147,23 +140,6 @@ export class EntityManager {
}
}
/**
* Gets user data by a given key.
* Used get stored data stored in a transactional entity manager.
*/
getData(key: string): any {
return this.data[key];
}
/**
* Sets value for the given key in user data.
* Used to store data in a transactional entity manager which can be accessed in subscribers then.
*/
setData(key: string, value: any): this {
this.data[key] = value;
return this;
}
/**
* Checks if entity has an id.
*/
@ -308,7 +284,7 @@ export class EntityManager {
const queryRunner = this.queryRunner || this.connection.createQueryRunner();
const transactionEntityManager = new EntityManagerFactory().create(this.connection, queryRunner);
if (options && options.data)
transactionEntityManager.data = options.data;
Object.assign(queryRunner.data, options.data);
try {
const executors: SubjectOperationExecutor[] = [];
@ -505,7 +481,7 @@ export class EntityManager {
const queryRunner = this.queryRunner || this.connection.createQueryRunner();
const transactionEntityManager = new EntityManagerFactory().create(this.connection, queryRunner);
if (options && options.data)
transactionEntityManager.data = options.data;
Object.assign(queryRunner.data, options.data);
try {
const executors: SubjectOperationExecutor[] = [];

View File

@ -6,6 +6,7 @@ import {Connection} from "../connection/Connection";
import {ReadStream} from "fs";
import {InsertResult} from "../driver/InsertResult";
import {EntityManager} from "../entity-manager/EntityManager";
import {ObjectLiteral} from "../common/ObjectLiteral";
/**
* Runs queries on a single database connection.
@ -35,6 +36,12 @@ export interface QueryRunner {
*/
readonly isTransactionActive: boolean;
/**
* Stores temporarily user data.
* Useful for sharing data with subscribers.
*/
data: ObjectLiteral;
/**
* Creates/uses database connection from the connection pool to perform further operations.
* Returns obtained database connection.

View File

@ -1,42 +0,0 @@
import "reflect-metadata";
import {closeTestingConnections, createTestingConnections, reloadTestingDatabases} from "../../../utils/test-utils";
import {Connection} from "../../../../src/connection/Connection";
import {Post} from "./entity/Post";
import {expect} from "chai";
describe.skip("entity manager > custom data", () => {
let connections: Connection[];
before(async () => connections = await createTestingConnections({
entities: [__dirname + "/entity/*{.js,.ts}"],
subscribers: [__dirname + "/subscriber/*{.js,.ts}"],
schemaCreate: true,
dropSchemaOnConnection: true,
}));
beforeEach(() => reloadTestingDatabases(connections));
after(() => closeTestingConnections(connections));
it("should set data into entity manager and retrieve it successfully", () => Promise.all(connections.map(async connection => {
const user = { name: "Dima" };
connection.manager.setData("user", user);
expect(connection.manager.getData("user")).to.be.not.empty;
connection.manager.getData("user").should.be.equal(user);
})));
it("change in subscriber should update data set in entity manager", () => Promise.all(connections.map(async connection => {
const user = { name: "Dima" };
connection.manager.setData("user", user);
const post = new Post();
post.title = "New post";
await connection.manager.save(post);
expect(connection.manager.getData("user")).to.be.not.empty;
connection.manager.getData("user").should.be.eql({ name: "Updated Dima" });
})));
});

View File

@ -1,14 +0,0 @@
import {Entity} from "../../../../../src/decorator/entity/Entity";
import {PrimaryGeneratedColumn} from "../../../../../src/decorator/columns/PrimaryGeneratedColumn";
import {Column} from "../../../../../src/decorator/columns/Column";
@Entity()
export class Post {
@PrimaryGeneratedColumn()
id: number;
@Column()
title: string;
}

View File

@ -1,16 +0,0 @@
import {EventSubscriber} from "../../../../../src/decorator/listeners/EventSubscriber";
import {EntitySubscriberInterface} from "../../../../../src/subscriber/EntitySubscriberInterface";
import {InsertEvent} from "../../../../../src/subscriber/event/InsertEvent";
@EventSubscriber()
export class PostSubscriber implements EntitySubscriberInterface<any> {
/**
* Called before entity insertion.
*/
beforeInsert(event: InsertEvent<any>) {
const user = event.manager.getData("user");
user.name = "Updated Dima";
}
}