mirror of
https://github.com/typeorm/typeorm.git
synced 2025-12-08 21:26:23 +00:00
some refactoring + changed findById method name to findOneById
This commit is contained in:
parent
ae26df1d1e
commit
376bc1d014
@ -47,7 +47,7 @@ Finds entities that match given conditions or given find options.
|
||||
|
||||
Finds the first entity that match given conditions or given find options.
|
||||
|
||||
* `findById(entityClass: Function, id: any, options?: FindOptions): Promise<Entity>`
|
||||
* `findOneById(entityClass: Function, id: any, options?: FindOptions): Promise<Entity>`
|
||||
|
||||
Finds entity with a given entity id.
|
||||
|
||||
|
||||
@ -44,7 +44,7 @@ Finds entities that match given conditions or given find options.
|
||||
|
||||
Finds the first entity that match given conditions or given find options.
|
||||
|
||||
* `findById(id: any, options?: FindOptions): Promise<Entity>`
|
||||
* `findOneById(id: any, options?: FindOptions): Promise<Entity>`
|
||||
|
||||
Finds entity with a given entity id.
|
||||
|
||||
|
||||
@ -80,7 +80,7 @@ createConnection(options).then(connection => {
|
||||
return postRepository.persist(entity);
|
||||
})
|
||||
.then(entity => {
|
||||
return postRepository.findById(entity.id);
|
||||
return postRepository.findOneById(entity.id);
|
||||
})
|
||||
.then(entity => {
|
||||
console.log("Entity is loaded: ", entity);
|
||||
|
||||
@ -64,7 +64,7 @@ createConnection(options).then(connection => {
|
||||
.persist(post)
|
||||
.then(post => {
|
||||
console.log("Post has been saved");
|
||||
return postRepository.findById(post.id);
|
||||
return postRepository.findOneById(post.id);
|
||||
})
|
||||
.then(loadedPost => {
|
||||
console.log("post is loaded: ", loadedPost);
|
||||
@ -72,7 +72,7 @@ createConnection(options).then(connection => {
|
||||
})
|
||||
.then(blog => {
|
||||
console.log("Blog has been saved");
|
||||
return blogRepository.findById(blog.id);
|
||||
return blogRepository.findOneById(blog.id);
|
||||
})
|
||||
.then(loadedBlog => {
|
||||
console.log("blog is loaded: ", loadedBlog);
|
||||
|
||||
@ -42,7 +42,7 @@ createConnection(options).then(connection => {
|
||||
.persist(post)
|
||||
.then(post => {
|
||||
console.log("Post has been saved");
|
||||
return postRepository.findById(post.id);
|
||||
return postRepository.findOneById(post.id);
|
||||
})
|
||||
.then(loadedPost => {
|
||||
console.log("---------------------------");
|
||||
|
||||
@ -56,7 +56,7 @@ createConnection(options).then(connection => {
|
||||
.persist(post)
|
||||
.then(post => {
|
||||
console.log("Post has been saved");
|
||||
return postRepository.findById(post.id);
|
||||
return postRepository.findOneById(post.id);
|
||||
})
|
||||
.then(loadedPost => {
|
||||
console.log("post is loaded: ", loadedPost);
|
||||
@ -64,7 +64,7 @@ createConnection(options).then(connection => {
|
||||
})
|
||||
.then(blog => {
|
||||
console.log("Blog has been saved");
|
||||
return blogRepository.findById(blog.id);
|
||||
return blogRepository.findOneById(blog.id);
|
||||
})
|
||||
.then(loadedBlog => {
|
||||
console.log("blog is loaded: ", loadedBlog);
|
||||
|
||||
@ -40,7 +40,7 @@ createConnection(options).then(connection => {
|
||||
.then(post => {
|
||||
console.log("Post has been saved");
|
||||
console.log("---------------------------");
|
||||
return postRepository.findById(post.id);
|
||||
return postRepository.findOneById(post.id);
|
||||
})
|
||||
.then(loadedPost => {
|
||||
console.log("post is loaded. Its uid is " + loadedPost.uid);
|
||||
|
||||
@ -45,8 +45,7 @@ export class EntityPersistOperationBuilder {
|
||||
// Constructor
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
constructor(private connection: Connection,
|
||||
private entityMetadatas: EntityMetadata[]) {
|
||||
constructor(private entityMetadatas: EntityMetadata[]) {
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@ -196,8 +196,8 @@ export class EntityManager {
|
||||
/**
|
||||
* Finds entity with given id.
|
||||
*/
|
||||
findById<Entity>(entityClass: ConstructorFunction<Entity>|Function, id: any, options?: FindOptions): Promise<Entity> {
|
||||
return this.getRepository(entityClass).findById(id, options);
|
||||
findOneById<Entity>(entityClass: ConstructorFunction<Entity>|Function, id: any, options?: FindOptions): Promise<Entity> {
|
||||
return this.getRepository(entityClass).findOneById(id, options);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -9,6 +9,7 @@ import {EntityWithId} from "../persistment/operation/PersistOperation";
|
||||
import {FindOptions, FindOptionsUtils} from "./FindOptions";
|
||||
import {EntityMetadataCollection} from "../metadata/collection/EntityMetadataCollection";
|
||||
import {Broadcaster} from "../subscriber/Broadcaster";
|
||||
import {Driver} from "../driver/Driver";
|
||||
|
||||
/**
|
||||
* Repository is supposed to work with your entity objects. Find entities, insert, update, delete, etc.
|
||||
@ -19,8 +20,12 @@ export class Repository<Entity> {
|
||||
// Private Properties
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
private driver: Driver;
|
||||
private broadcaster: Broadcaster;
|
||||
private persister: PersistOperationExecutor;
|
||||
private persistOperationExecutor: PersistOperationExecutor;
|
||||
private entityPersistOperationBuilder: EntityPersistOperationBuilder;
|
||||
private plainObjectToEntityTransformer: PlainObjectToNewEntityTransformer;
|
||||
private plainObjectToDatabaseEntityTransformer: PlainObjectToDatabaseEntityTransformer<Entity>;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Constructor
|
||||
@ -29,8 +34,12 @@ export class Repository<Entity> {
|
||||
constructor(private connection: Connection,
|
||||
private entityMetadatas: EntityMetadataCollection,
|
||||
private metadata: EntityMetadata) {
|
||||
this.driver = connection.driver;
|
||||
this.broadcaster = new Broadcaster(entityMetadatas, connection.eventSubscribers, connection.entityListeners);
|
||||
this.persister = new PersistOperationExecutor(connection.driver, entityMetadatas, this.broadcaster);
|
||||
this.persistOperationExecutor = new PersistOperationExecutor(connection.driver, entityMetadatas, this.broadcaster);
|
||||
this.entityPersistOperationBuilder = new EntityPersistOperationBuilder(entityMetadatas);
|
||||
this.plainObjectToEntityTransformer = new PlainObjectToNewEntityTransformer();
|
||||
this.plainObjectToDatabaseEntityTransformer = new PlainObjectToDatabaseEntityTransformer();
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
@ -42,19 +51,17 @@ export class Repository<Entity> {
|
||||
*/
|
||||
hasId(entity: Entity): boolean {
|
||||
return entity &&
|
||||
this.metadata.primaryColumn &&
|
||||
entity.hasOwnProperty(this.metadata.primaryColumn.propertyName) &&
|
||||
(<any> entity)[this.metadata.primaryColumn.propertyName] !== null &&
|
||||
(<any> entity)[this.metadata.primaryColumn.propertyName] !== undefined;
|
||||
(<any> entity)[this.metadata.primaryColumn.propertyName] !== undefined &&
|
||||
(<any> entity)[this.metadata.primaryColumn.propertyName] !== "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new query builder that can be used to build a sql query.
|
||||
*/
|
||||
createQueryBuilder(alias: string): QueryBuilder<Entity> {
|
||||
// const qb = this.connection.driver.createQueryBuilder<Entity>();
|
||||
const qb = new QueryBuilder(this.connection.driver, this.entityMetadatas, this.broadcaster);
|
||||
return qb
|
||||
return new QueryBuilder(this.driver, this.entityMetadatas, this.broadcaster)
|
||||
.select(alias)
|
||||
.from(this.metadata.target, alias);
|
||||
}
|
||||
@ -64,15 +71,14 @@ export class Repository<Entity> {
|
||||
* from this object into a new entity (copies only properties that should be in a new entity).
|
||||
*/
|
||||
create(fromRawEntity?: Object): Entity {
|
||||
if (fromRawEntity) {
|
||||
const transformer = new PlainObjectToNewEntityTransformer();
|
||||
return transformer.transform(fromRawEntity, this.metadata);
|
||||
}
|
||||
if (fromRawEntity)
|
||||
return this.plainObjectToEntityTransformer.transform(fromRawEntity, this.metadata);
|
||||
|
||||
return <Entity> this.metadata.create();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a entities from the given array of plain javascript objects.
|
||||
* Creates entities from a given array of plain javascript objects.
|
||||
*/
|
||||
createMany(copyFromObjects: Object[]): Entity[] {
|
||||
return copyFromObjects.map(object => this.create(object));
|
||||
@ -85,9 +91,8 @@ export class Repository<Entity> {
|
||||
* replaced from the new object.
|
||||
*/
|
||||
initialize(object: Object): Promise<Entity> {
|
||||
const transformer = new PlainObjectToDatabaseEntityTransformer();
|
||||
const queryBuilder = this.createQueryBuilder(this.metadata.table.name);
|
||||
return transformer.transform(object, this.metadata, queryBuilder);
|
||||
return this.plainObjectToDatabaseEntityTransformer.transform(object, this.metadata, queryBuilder);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -103,7 +108,6 @@ export class Repository<Entity> {
|
||||
*/
|
||||
persist(entity: Entity): Promise<Entity> {
|
||||
let loadedDbEntity: any;
|
||||
const builder = new EntityPersistOperationBuilder(this.connection, this.entityMetadatas);
|
||||
const allPersistedEntities = this.extractObjectsById(entity, this.metadata);
|
||||
const promise: Promise<Entity> = !this.hasId(entity) ? Promise.resolve<Entity|null>(null) : this.initialize(entity);
|
||||
return promise
|
||||
@ -113,8 +117,8 @@ export class Repository<Entity> {
|
||||
return this.findNotLoadedIds(entityWithIds, allPersistedEntities);
|
||||
}) // need to find db entities that were not loaded by initialize method
|
||||
.then(allDbEntities => {
|
||||
const persistOperation = builder.buildFullPersistment(this.metadata, loadedDbEntity, entity, allDbEntities, allPersistedEntities);
|
||||
return this.persister.executePersistOperation(persistOperation);
|
||||
const persistOperation = this.entityPersistOperationBuilder.buildFullPersistment(this.metadata, loadedDbEntity, entity, allDbEntities, allPersistedEntities);
|
||||
return this.persistOperationExecutor.executePersistOperation(persistOperation);
|
||||
}).then(() => entity);
|
||||
}
|
||||
|
||||
@ -124,11 +128,10 @@ export class Repository<Entity> {
|
||||
remove(entity: Entity): Promise<Entity> {
|
||||
return this.initialize(entity).then(dbEntity => {
|
||||
(<any> entity)[this.metadata.primaryColumn.name] = undefined;
|
||||
const builder = new EntityPersistOperationBuilder(this.connection, this.entityMetadatas);
|
||||
const dbEntities = this.extractObjectsById(dbEntity, this.metadata);
|
||||
const allPersistedEntities = this.extractObjectsById(entity, this.metadata);
|
||||
const persistOperation = builder.buildOnlyRemovement(this.metadata, dbEntity, entity, dbEntities, allPersistedEntities);
|
||||
return this.persister.executePersistOperation(persistOperation);
|
||||
const persistOperation = this.entityPersistOperationBuilder.buildOnlyRemovement(this.metadata, dbEntity, entity, dbEntities, allPersistedEntities);
|
||||
return this.persistOperationExecutor.executePersistOperation(persistOperation);
|
||||
}).then(() => entity);
|
||||
}
|
||||
|
||||
@ -219,7 +222,7 @@ export class Repository<Entity> {
|
||||
/**
|
||||
* Finds entity with given id.
|
||||
*/
|
||||
findById(id: any, options?: FindOptions): Promise<Entity> {
|
||||
findOneById(id: any, options?: FindOptions): Promise<Entity> {
|
||||
return this.createFindQueryBuilder({ [this.metadata.primaryColumn.name]: id }, options)
|
||||
.getSingleResult();
|
||||
}
|
||||
@ -228,7 +231,7 @@ export class Repository<Entity> {
|
||||
* Executes raw SQL query and returns raw database results.
|
||||
*/
|
||||
query(query: string): Promise<any> {
|
||||
return this.connection.driver.query(query);
|
||||
return this.driver.query(query);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -236,12 +239,12 @@ export class Repository<Entity> {
|
||||
*/
|
||||
transaction(runInTransaction: () => Promise<any>): Promise<any> {
|
||||
let runInTransactionResult: any;
|
||||
return this.connection.driver
|
||||
return this.driver
|
||||
.beginTransaction()
|
||||
.then(() => runInTransaction())
|
||||
.then(result => {
|
||||
runInTransactionResult = result;
|
||||
return this.connection.driver.endTransaction();
|
||||
return this.driver.endTransaction();
|
||||
})
|
||||
.then(() => runInTransactionResult);
|
||||
}
|
||||
@ -281,10 +284,9 @@ export class Repository<Entity> {
|
||||
.filter(entityWithId => entityWithId.id !== null && entityWithId.id !== undefined)
|
||||
.filter(entityWithId => !dbEntities.find(dbEntity => dbEntity.entity.constructor === entityWithId.entity.constructor && dbEntity.id === entityWithId.id))
|
||||
.map(entityWithId => {
|
||||
// const metadata = this.connection.getEntityMetadata(entityWithId.entity.constructor);
|
||||
const metadata = this.entityMetadatas.find(metadata => metadata.target === entityWithId.entity.constructor);
|
||||
const metadata = this.entityMetadatas.findByTarget(entityWithId.entity.constructor);
|
||||
const repository = this.connection.getRepository(entityWithId.entity.constructor);
|
||||
return repository.findById(entityWithId.id).then(loadedEntity => {
|
||||
return repository.findOneById(entityWithId.id).then(loadedEntity => {
|
||||
if (!loadedEntity) return undefined;
|
||||
|
||||
return <EntityWithId> {
|
||||
|
||||
@ -78,7 +78,7 @@ describe("insertion", function() {
|
||||
|
||||
it("should have inserted post in the database", function() {
|
||||
// postRepository.findById(savedPost.id).then(p => console.log(p));
|
||||
return postRepository.findById(savedPost.id).should.eventually.eql({
|
||||
return postRepository.findOneById(savedPost.id).should.eventually.eql({
|
||||
id: savedPost.id,
|
||||
text: "Hello post",
|
||||
title: "this is post title"
|
||||
|
||||
@ -108,7 +108,7 @@ describe("one-to-one", function() {
|
||||
expectedPost.text = savedPost.text;
|
||||
expectedPost.title = savedPost.title;
|
||||
|
||||
return postRepository.findById(savedPost.id).should.eventually.eql(expectedPost);
|
||||
return postRepository.findOneById(savedPost.id).should.eventually.eql(expectedPost);
|
||||
});
|
||||
|
||||
it("should have inserted post details in the database", function() {
|
||||
@ -118,7 +118,7 @@ describe("one-to-one", function() {
|
||||
expectedDetails.comment = savedPost.details.comment;
|
||||
expectedDetails.metadata = savedPost.details.metadata;
|
||||
|
||||
return postDetailsRepository.findById(savedPost.details.id).should.eventually.eql(expectedDetails);
|
||||
return postDetailsRepository.findOneById(savedPost.details.id).should.eventually.eql(expectedDetails);
|
||||
});
|
||||
|
||||
it("should load post and its details if left join used", function() {
|
||||
@ -227,14 +227,14 @@ describe("one-to-one", function() {
|
||||
expectedPost.id = savedPost.id;
|
||||
expectedPost.text = savedPost.text;
|
||||
expectedPost.title = savedPost.title;
|
||||
return postRepository.findById(savedPost.id).should.eventually.eql(expectedPost);
|
||||
return postRepository.findOneById(savedPost.id).should.eventually.eql(expectedPost);
|
||||
});
|
||||
|
||||
it("should have inserted category in the database", function() {
|
||||
const expectedPost = new PostCategory();
|
||||
expectedPost.id = savedPost.category.id;
|
||||
expectedPost.name = "technology";
|
||||
return postCategoryRepository.findById(savedPost.category.id).should.eventually.eql(expectedPost);
|
||||
return postCategoryRepository.findOneById(savedPost.category.id).should.eventually.eql(expectedPost);
|
||||
});
|
||||
|
||||
it("should load post and its category if left join used", function() {
|
||||
|
||||
@ -105,7 +105,7 @@ describe("many-to-one", function() {
|
||||
expectedPost.text = savedPost.text;
|
||||
expectedPost.title = savedPost.title;
|
||||
|
||||
return postRepository.findById(savedPost.id).should.eventually.eql(expectedPost);
|
||||
return postRepository.findOneById(savedPost.id).should.eventually.eql(expectedPost);
|
||||
});
|
||||
|
||||
it("should have inserted post details in the database", function() {
|
||||
@ -115,7 +115,7 @@ describe("many-to-one", function() {
|
||||
expectedDetails.comment = savedPost.details.comment;
|
||||
expectedDetails.metadata = savedPost.details.metadata;
|
||||
|
||||
return postDetailsRepository.findById(savedPost.details.id).should.eventually.eql(expectedDetails);
|
||||
return postDetailsRepository.findOneById(savedPost.details.id).should.eventually.eql(expectedDetails);
|
||||
});
|
||||
|
||||
it("should load post and its details if left join used", function() {
|
||||
@ -226,14 +226,14 @@ describe("many-to-one", function() {
|
||||
expectedPost.id = savedPost.id;
|
||||
expectedPost.text = savedPost.text;
|
||||
expectedPost.title = savedPost.title;
|
||||
return postRepository.findById(savedPost.id).should.eventually.eql(expectedPost);
|
||||
return postRepository.findOneById(savedPost.id).should.eventually.eql(expectedPost);
|
||||
});
|
||||
|
||||
it("should have inserted category in the database", function() {
|
||||
const expectedPost = new PostCategory();
|
||||
expectedPost.id = savedPost.category.id;
|
||||
expectedPost.name = "technology";
|
||||
return postCategoryRepository.findById(savedPost.category.id).should.eventually.eql(expectedPost);
|
||||
return postCategoryRepository.findOneById(savedPost.category.id).should.eventually.eql(expectedPost);
|
||||
});
|
||||
|
||||
it("should load post and its category if left join used", function() {
|
||||
@ -473,14 +473,14 @@ describe("many-to-one", function() {
|
||||
expectedPost.id = newPost.id;
|
||||
expectedPost.text = newPost.text;
|
||||
expectedPost.title = newPost.title;
|
||||
return postRepository.findById(savedDetails.id).should.eventually.eql(expectedPost);
|
||||
return postRepository.findOneById(savedDetails.id).should.eventually.eql(expectedPost);
|
||||
});
|
||||
|
||||
it("should have inserted details in the database", function() {
|
||||
const expectedDetails = new PostDetails();
|
||||
expectedDetails.id = details.id;
|
||||
expectedDetails.comment = details.comment;
|
||||
return postDetailsRepository.findById(details.id).should.eventually.eql(expectedDetails);
|
||||
return postDetailsRepository.findOneById(details.id).should.eventually.eql(expectedDetails);
|
||||
});
|
||||
|
||||
it("should load post and its details if left join used", function() {
|
||||
|
||||
@ -109,7 +109,7 @@ describe("many-to-many", function() {
|
||||
expectedPost.text = savedPost.text;
|
||||
expectedPost.title = savedPost.title;
|
||||
|
||||
return postRepository.findById(savedPost.id).should.eventually.eql(expectedPost);
|
||||
return postRepository.findOneById(savedPost.id).should.eventually.eql(expectedPost);
|
||||
});
|
||||
|
||||
it("should have inserted post details in the database", function() {
|
||||
@ -119,7 +119,7 @@ describe("many-to-many", function() {
|
||||
expectedDetails.comment = savedPost.details[0].comment;
|
||||
expectedDetails.metadata = savedPost.details[0].metadata;
|
||||
|
||||
return postDetailsRepository.findById(savedPost.details[0].id).should.eventually.eql(expectedDetails);
|
||||
return postDetailsRepository.findOneById(savedPost.details[0].id).should.eventually.eql(expectedDetails);
|
||||
});
|
||||
|
||||
it("should load post and its details if left join used", function() {
|
||||
@ -230,14 +230,14 @@ describe("many-to-many", function() {
|
||||
expectedPost.id = savedPost.id;
|
||||
expectedPost.text = savedPost.text;
|
||||
expectedPost.title = savedPost.title;
|
||||
return postRepository.findById(savedPost.id).should.eventually.eql(expectedPost);
|
||||
return postRepository.findOneById(savedPost.id).should.eventually.eql(expectedPost);
|
||||
});
|
||||
|
||||
it("should have inserted category in the database", function() {
|
||||
const expectedPost = new PostCategory();
|
||||
expectedPost.id = savedPost.categories[0].id;
|
||||
expectedPost.name = "technology";
|
||||
return postCategoryRepository.findById(savedPost.categories[0].id).should.eventually.eql(expectedPost);
|
||||
return postCategoryRepository.findOneById(savedPost.categories[0].id).should.eventually.eql(expectedPost);
|
||||
});
|
||||
|
||||
it("should load post and its category if left join used", function() {
|
||||
@ -503,14 +503,14 @@ describe("many-to-many", function() {
|
||||
expectedPost.id = newPost.id;
|
||||
expectedPost.text = newPost.text;
|
||||
expectedPost.title = newPost.title;
|
||||
return postRepository.findById(savedDetails.id).should.eventually.eql(expectedPost);
|
||||
return postRepository.findOneById(savedDetails.id).should.eventually.eql(expectedPost);
|
||||
});
|
||||
|
||||
it("should have inserted details in the database", function() {
|
||||
const expectedDetails = new PostDetails();
|
||||
expectedDetails.id = details.id;
|
||||
expectedDetails.comment = details.comment;
|
||||
return postDetailsRepository.findById(details.id).should.eventually.eql(expectedDetails);
|
||||
return postDetailsRepository.findOneById(details.id).should.eventually.eql(expectedDetails);
|
||||
});
|
||||
|
||||
it("should load post and its details if left join used", function() {
|
||||
@ -573,14 +573,14 @@ describe("many-to-many", function() {
|
||||
});
|
||||
|
||||
it("should not have post in the database", function() {
|
||||
return postRepository.findById(savedPostId).should.eventually.eql(undefined);
|
||||
return postRepository.findOneById(savedPostId).should.eventually.eql(undefined);
|
||||
});
|
||||
|
||||
it("should have details in the database because it was not removed because cascades do not allow it", function() {
|
||||
const details = new PostDetails();
|
||||
details.id = savedDetailsId;
|
||||
details.comment = "post details comment";
|
||||
return postDetailsRepository.findById(savedDetailsId).should.eventually.eql(details);
|
||||
return postDetailsRepository.findOneById(savedDetailsId).should.eventually.eql(details);
|
||||
});
|
||||
|
||||
});
|
||||
@ -626,15 +626,15 @@ describe("many-to-many", function() {
|
||||
});
|
||||
|
||||
it("should not have post in the database", function() {
|
||||
return postRepository.findById(savedPostId).should.eventually.eql(undefined);
|
||||
return postRepository.findOneById(savedPostId).should.eventually.eql(undefined);
|
||||
});
|
||||
|
||||
it("should not have category1 in the database", function() {
|
||||
return postCategoryRepository.findById(savedCategory1Id).should.eventually.eql(undefined);
|
||||
return postCategoryRepository.findOneById(savedCategory1Id).should.eventually.eql(undefined);
|
||||
});
|
||||
|
||||
it("should not have category2 in the database", function() {
|
||||
return postCategoryRepository.findById(savedCategory2Id).should.eventually.eql(undefined);
|
||||
return postCategoryRepository.findOneById(savedCategory2Id).should.eventually.eql(undefined);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user