minor fixes;

working on RelationId tests;
This commit is contained in:
Zotov Dmitry 2017-05-22 15:39:57 +05:00
parent f91537b48d
commit cdae9fb31c
49 changed files with 1305 additions and 49 deletions

View File

@ -382,7 +382,7 @@ export class SubjectBuilder<Entity extends ObjectLiteral> {
// (example) here we seek a Details loaded from the database in the subjects
// (example) here relatedSubject.databaseEntity is a Details
// (example) and we need to compare details.id === post.detailsId
return relation.entityMetadata.compareIds(relationIdInDatabaseEntity, relation.getEntityValue(relatedSubject.databaseEntity)); // relation.joinColumns[0].referencedColumn!.getEntityValue(relatedSubject.databaseEntity) === relationIdInDatabaseEntity;
return relation.entityMetadata.compareIds(relationIdInDatabaseEntity, relation.getEntityValue(relatedSubject.databaseEntity));
});
// if not loaded yet then load it from the database

View File

@ -126,9 +126,12 @@ export class RelationIdLoader {
if (mappedColumns.length === 0)
return { relationIdAttribute: relationIdAttr, results: [] };
const joinColumnConditions = mappedColumns.map(mappedColumn => {
const parameters: ObjectLiteral = {};
const joinColumnConditions = mappedColumns.map((mappedColumn, index) => {
return Object.keys(mappedColumn).map(key => {
return junctionAlias + "." + key + " = " + mappedColumn[key];
const parameterName = key + index;
parameters[parameterName] = mappedColumn[key];
return junctionAlias + "." + key + " = :" + parameterName;
}).join(" AND ");
});
@ -153,7 +156,8 @@ export class RelationIdLoader {
});
qb.fromTable(inverseSideTableName, inverseSideTableAlias)
.innerJoin(junctionTableName, junctionAlias, condition);
.innerJoin(junctionTableName, junctionAlias, condition)
.setParameters(parameters);
// apply condition (custom query builder factory)
if (relationIdAttr.queryBuilderFactory)

View File

@ -1,11 +1,8 @@
import "reflect-metadata";
import * as chai from "chai";
import {Connection} from "../../../src/connection/Connection";
import {closeTestingConnections, createTestingConnections, reloadTestingDatabases} from "../../utils/test-utils";
import {Post} from "./entity/Post";
const should = chai.should();
describe.skip("benchmark > bulk-save", () => {
let connections: Connection[];
@ -18,11 +15,11 @@ describe.skip("benchmark > bulk-save", () => {
after(() => closeTestingConnections(connections));
it("testing bulk save of 100 objects", () => Promise.all(connections.map(async connection => {
it("testing bulk save of 1000 objects", () => Promise.all(connections.map(async connection => {
const posts: Post[] = [];
for (let i = 1; i <= 100; i++) {
for (let i = 1; i <= 1000; i++) {
const post = new Post();
post.title = `Post #${i}`;
post.text = `Post #${i} text`;

View File

@ -220,7 +220,7 @@ describe("decorators > relation-id-decorator > many-to-many", () => {
})));
it("should load ids when RelationId decorator used on inherit relation", () => Promise.all(connections.map(async connection => {
it("should load ids when RelationId decorator used on nested relation", () => Promise.all(connections.map(async connection => {
const image1 = new Image();
image1.name = "photo1";
@ -300,7 +300,7 @@ describe("decorators > relation-id-decorator > many-to-many", () => {
})));
it("should not load ids of inherit relations when RelationId decorator used on inherit relation and parent relation was not found", () => Promise.all(connections.map(async connection => {
it("should not load ids of nested relations when RelationId decorator used on inherit relation and parent relation was not found", () => Promise.all(connections.map(async connection => {
const image1 = new Image();
image1.name = "photo1";
@ -332,7 +332,7 @@ describe("decorators > relation-id-decorator > many-to-many", () => {
})));
it("should load ids when RelationId decorator used on inherit relation with additional conditions", () => Promise.all(connections.map(async connection => {
it("should load ids when RelationId decorator used on nested relation with additional conditions", () => Promise.all(connections.map(async connection => {
const image1 = new Image();
image1.name = "photo1";

View File

@ -6,7 +6,7 @@ import {expect} from "chai";
import {closeTestingConnections, createTestingConnections, reloadTestingDatabases} from "../../../utils/test-utils";
import {Subcounters} from "./entity/Subcounters";
describe("embedded > multiple-primary-columns-with-inherit-embed", () => {
describe("embedded > multiple-primary-columns-with-nested-embed", () => {
let connections: Connection[];
before(async () => connections = await createTestingConnections({

View File

@ -1,7 +1,7 @@
import "reflect-metadata";
import * as chai from "chai";
import {expect} from "chai";
import {createTestingConnections, closeTestingConnections, reloadTestingDatabases} from "../../../../utils/test-utils";
import {closeTestingConnections, createTestingConnections, reloadTestingDatabases} from "../../../../utils/test-utils";
import {Connection} from "../../../../../src/connection/Connection";
import {Category} from "./entity/Category";
import {Post} from "./entity/Post";
@ -61,7 +61,7 @@ describe("query builder > load-relation-count-and-map > one-to-many", () => {
expect(loadedPost!.categoryCount).to.be.equal(2);
})));
it("should load relation count on inherit relations", () => Promise.all(connections.map(async connection => {
it("should load relation count on nested relations", () => Promise.all(connections.map(async connection => {
const image1 = new Image();
image1.name = "image #1";

View File

@ -280,7 +280,7 @@ describe("query builder > relation-id > many-to-many > basic-functionality", ()
})));
it("should load ids when loadRelationIdAndMap used on inherit relation", () => Promise.all(connections.map(async connection => {
it("should load ids when loadRelationIdAndMap used on nested relation", () => Promise.all(connections.map(async connection => {
const image1 = new Image();
image1.name = "photo1";
@ -328,7 +328,7 @@ describe("query builder > relation-id > many-to-many > basic-functionality", ()
})));
it("should load ids when loadRelationIdAndMap used on inherit relation with additional conditions", () => Promise.all(connections.map(async connection => {
it("should load ids when loadRelationIdAndMap used on nested relation with additional conditions", () => Promise.all(connections.map(async connection => {
const image1 = new Image();
image1.name = "photo1";
@ -374,7 +374,7 @@ describe("query builder > relation-id > many-to-many > basic-functionality", ()
})));
it("should not load ids of inherit relations when loadRelationIdAndMap used on inherit relation and parent relation was not found", () => Promise.all(connections.map(async connection => {
it("should not load ids of nested relations when loadRelationIdAndMap used on inherit relation and parent relation was not found", () => Promise.all(connections.map(async connection => {
const image1 = new Image();
image1.name = "photo1";

View File

@ -0,0 +1,328 @@
import "reflect-metadata";
import * as chai from "chai";
import {expect} from "chai";
import {
closeTestingConnections,
createTestingConnections,
reloadTestingDatabases
} from "../../../../../utils/test-utils";
import {Connection} from "../../../../../../src/connection/Connection";
import {Post} from "./entity/Post";
import {Category} from "./entity/Category";
import {Counters} from "./entity/Counters";
import {User} from "./entity/User";
import {Subcounters} from "./entity/Subcounters";
const should = chai.should();
describe("query builder > relation-id > many-to-many > embedded-with-multiple-pk", () => {
let connections: Connection[];
before(async () => connections = await createTestingConnections({
entities: [__dirname + "/entity/*{.js,.ts}"],
schemaCreate: true,
dropSchemaOnConnection: true,
}));
beforeEach(() => reloadTestingDatabases(connections));
after(() => closeTestingConnections(connections));
describe("owner side", () => {
it("should load ids when loadRelationIdAndMap used on embedded table and each table have primary key", () => Promise.all(connections.map(async connection => {
const user1 = new User();
user1.id = 1;
user1.name = "Alice";
await connection.manager.save(user1);
const user2 = new User();
user2.id = 2;
user2.name = "Bob";
await connection.manager.save(user2);
const user3 = new User();
user3.id = 3;
user3.name = "Clara";
await connection.manager.save(user3);
const category1 = new Category();
category1.id = 1;
category1.name = "cars";
await connection.manager.save(category1);
const category2 = new Category();
category2.id = 2;
category2.name = "BMW";
await connection.manager.save(category2);
const category3 = new Category();
category3.id = 3;
category3.name = "airplanes";
await connection.manager.save(category3);
const category4 = new Category();
category4.id = 4;
category4.name = "Boeing";
await connection.manager.save(category4);
const post1 = new Post();
post1.id = 1;
post1.title = "About BMW";
post1.counters = new Counters();
post1.counters.code = 111;
post1.counters.likes = 1;
post1.counters.comments = 2;
post1.counters.favorites = 3;
post1.counters.categories = [category1, category2];
post1.counters.subcounters = new Subcounters();
post1.counters.subcounters.version = 1;
post1.counters.subcounters.watches = 2;
post1.counters.subcounters.watchedUsers = [user1, user2];
await connection.manager.save(post1);
const post2 = new Post();
post2.id = 2;
post2.title = "About Boeing";
post2.counters = new Counters();
post2.counters.code = 222;
post2.counters.likes = 3;
post2.counters.comments = 4;
post2.counters.favorites = 5;
post2.counters.categories = [category3, category4];
post2.counters.subcounters = new Subcounters();
post2.counters.subcounters.version = 1;
post2.counters.subcounters.watches = 1;
post2.counters.subcounters.watchedUsers = [user3];
await connection.manager.save(post2);
const loadedPosts = await connection.manager
.createQueryBuilder(Post, "post")
.loadRelationIdAndMap("post.counters.categoryIds", "post.counters.categories")
.loadRelationIdAndMap("post.counters.subcounters.watchedUserIds", "post.counters.subcounters.watchedUsers")
.orderBy("post.id")
.getMany();
expect(loadedPosts[0].should.be.eql(
{
id: 1,
title: "About BMW",
counters: {
code: 111,
likes: 1,
comments: 2,
favorites: 3,
categoryIds: [
{ id: 1, name: "cars"},
{ id: 2, name: "BMW"}
],
subcounters: {
version: 1,
watches: 2,
watchedUserIds: [
{ id: 1, name: "Alice"},
{ id: 2, name: "Bob"}
]
}
}
}
));
expect(loadedPosts[1].should.be.eql(
{
id: 2,
title: "About Boeing",
counters: {
code: 222,
likes: 3,
comments: 4,
favorites: 5,
categoryIds: [
{ id: 3, name: "airplanes"},
{ id: 4, name: "Boeing"}
],
subcounters: {
version: 1,
watches: 1,
watchedUserIds: [
{ id: 3, name: "Clara"}
]
}
}
}
));
const loadedPost = await connection.manager
.createQueryBuilder(Post, "post")
.loadRelationIdAndMap("post.counters.categoryIds", "post.counters.categories")
.loadRelationIdAndMap("post.counters.subcounters.watchedUserIds", "post.counters.subcounters.watchedUsers")
.where("post.id = :id", { id: 1 })
.andWhere("post.counters.code = :code", { code: 111 })
.andWhere("post.counters.subcounters.version = :version", { version: 1 })
.getOne();
expect(loadedPost!.should.be.eql(
{
id: 1,
title: "About BMW",
counters: {
code: 111,
likes: 1,
comments: 2,
favorites: 3,
categoryIds: [
{ id: 1, name: "cars"},
{ id: 2, name: "BMW"}
],
subcounters: {
version: 1,
watches: 2,
watchedUserIds: [
{ id: 1, name: "Alice"},
{ id: 2, name: "Bob"}
]
}
}
}
));
})));
});
describe("inverse side", () => {
it("should load ids when loadRelationIdAndMap used on embedded table and each table have primary key", () => Promise.all(connections.map(async connection => {
const post1 = new Post();
post1.id = 1;
post1.title = "About BMW";
post1.counters = new Counters();
post1.counters.code = 111;
post1.counters.likes = 1;
post1.counters.comments = 2;
post1.counters.favorites = 3;
post1.counters.subcounters = new Subcounters();
post1.counters.subcounters.version = 1;
post1.counters.subcounters.watches = 2;
await connection.manager.save(post1);
const post2 = new Post();
post2.id = 2;
post2.title = "About Audi";
post2.counters = new Counters();
post2.counters.code = 222;
post2.counters.likes = 3;
post2.counters.comments = 4;
post2.counters.favorites = 5;
post2.counters.subcounters = new Subcounters();
post2.counters.subcounters.version = 1;
post2.counters.subcounters.watches = 5;
await connection.manager.save(post2);
const post3 = new Post();
post3.id = 3;
post3.title = "About Boeing";
post3.counters = new Counters();
post3.counters.code = 333;
post3.counters.likes = 6;
post3.counters.comments = 7;
post3.counters.favorites = 8;
post3.counters.subcounters = new Subcounters();
post3.counters.subcounters.version = 2;
post3.counters.subcounters.watches = 10;
await connection.manager.save(post3);
const post4 = new Post();
post4.id = 4;
post4.title = "About Airbus";
post4.counters = new Counters();
post4.counters.code = 444;
post4.counters.likes = 9;
post4.counters.comments = 10;
post4.counters.favorites = 11;
post4.counters.subcounters = new Subcounters();
post4.counters.subcounters.version = 3;
post4.counters.subcounters.watches = 10;
await connection.manager.save(post4);
const category1 = new Category();
category1.id = 1;
category1.name = "cars";
category1.posts = [post1, post2];
await connection.manager.save(category1);
const category2 = new Category();
category2.id = 2;
category2.name = "airplanes";
category2.posts = [post3, post4];
await connection.manager.save(category2);
const user1 = new User();
user1.id = 1;
user1.name = "Alice";
user1.posts = [post1, post2];
await connection.manager.save(user1);
const user2 = new User();
user2.id = 2;
user2.name = "Bob";
user2.posts = [post3, post4];
await connection.manager.save(user2);
const loadedCategories = await connection.manager
.createQueryBuilder(Category, "category")
.loadRelationIdAndMap("category.postIds", "category.posts")
.orderBy("category.id")
.getMany();
expect(loadedCategories[0].postIds).to.not.be.empty;
expect(loadedCategories[0].postIds.length).to.be.equal(2);
expect(loadedCategories[0].postIds[0]).to.be.eql({ id: 1, counters: { code: 111, subcounters: { version: 1 }} });
expect(loadedCategories[0].postIds[1]).to.be.eql({ id: 2, counters: { code: 222, subcounters: { version: 1 }} });
expect(loadedCategories[1].postIds).to.not.be.empty;
expect(loadedCategories[1].postIds.length).to.be.equal(2);
expect(loadedCategories[1].postIds[0]).to.be.eql({ id: 3, counters: { code: 333, subcounters: { version: 2 }} });
expect(loadedCategories[1].postIds[1]).to.be.eql({ id: 4, counters: { code: 444, subcounters: { version: 3 }} });
const loadedCategory = await connection.manager
.createQueryBuilder(Category, "category")
.loadRelationIdAndMap("category.postIds", "category.posts")
.where("category.id = :id", { id: 1 })
.andWhere("category.name = :name", { name: "cars" })
.getOne();
expect(loadedCategory!.postIds).to.not.be.empty;
expect(loadedCategory!.postIds.length).to.be.equal(2);
expect(loadedCategory!.postIds[0]).to.be.eql({ id: 1, counters: { code: 111, subcounters: { version: 1 }} });
expect(loadedCategory!.postIds[1]).to.be.eql({ id: 2, counters: { code: 222, subcounters: { version: 1 }} });
const loadedUsers = await connection.manager
.createQueryBuilder(User, "user")
.loadRelationIdAndMap("user.postIds", "user.posts")
.orderBy("user.id")
.getMany();
expect(loadedUsers[0].postIds).to.not.be.empty;
expect(loadedUsers[0].postIds.length).to.be.equal(2);
expect(loadedUsers[0].postIds[0]).to.be.eql({ id: 1, counters: { code: 111, subcounters: { version: 1 }} });
expect(loadedUsers[0].postIds[1]).to.be.eql({ id: 2, counters: { code: 222, subcounters: { version: 1 }} });
expect(loadedUsers[1].postIds).to.not.be.empty;
expect(loadedUsers[1].postIds.length).to.be.equal(2);
expect(loadedUsers[1].postIds[0]).to.be.eql({ id: 3, counters: { code: 333, subcounters: { version: 2 }} });
expect(loadedUsers[1].postIds[1]).to.be.eql({ id: 4, counters: { code: 444, subcounters: { version: 3 }} });
const loadedUser = await connection.manager
.createQueryBuilder(User, "user")
.loadRelationIdAndMap("user.postIds", "user.posts")
.where("user.id = :id", { id: 1 })
.andWhere("user.name = :name", { name: "Alice" })
.getOne();
expect(loadedUser!.postIds).to.not.be.empty;
expect(loadedUser!.postIds.length).to.be.equal(2);
expect(loadedUser!.postIds[0]).to.be.eql({ id: 1, counters: { code: 111, subcounters: { version: 1 }} });
expect(loadedUser!.postIds[1]).to.be.eql({ id: 2, counters: { code: 222, subcounters: { version: 1 }} });
})));
});
});

View File

@ -0,0 +1,22 @@
import {Entity} from "../../../../../../../src/decorator/entity/Entity";
import {ManyToMany} from "../../../../../../../src/decorator/relations/ManyToMany";
import {PrimaryColumn} from "../../../../../../../src/decorator/columns/PrimaryColumn";
import {Post} from "./Post";
import {Index} from "../../../../../../../src/decorator/Index";
@Entity()
@Index(["id", "name"])
export class Category {
@PrimaryColumn()
id: number;
@PrimaryColumn()
name: string;
@ManyToMany(type => Post, post => post.counters.categories)
posts: Post[];
postIds: number[];
}

View File

@ -0,0 +1,32 @@
import {Column} from "../../../../../../../src/decorator/columns/Column";
import {ManyToMany} from "../../../../../../../src/decorator/relations/ManyToMany";
import {JoinTable} from "../../../../../../../src/decorator/relations/JoinTable";
import {Embedded} from "../../../../../../../src/decorator/Embedded";
import {PrimaryColumn} from "../../../../../../../src/decorator/columns/PrimaryColumn";
import {Category} from "./Category";
import {Subcounters} from "./Subcounters";
export class Counters {
@PrimaryColumn()
code: number;
@Column()
likes: number;
@Column()
comments: number;
@Column()
favorites: number;
@ManyToMany(type => Category, category => category.posts)
@JoinTable()
categories: Category[];
@Embedded(() => Subcounters)
subcounters: Subcounters;
categoryIds: number[];
}

View File

@ -0,0 +1,21 @@
import {Entity} from "../../../../../../../src/decorator/entity/Entity";
import {Column} from "../../../../../../../src/decorator/columns/Column";
import {Embedded} from "../../../../../../../src/decorator/Embedded";
import {Index} from "../../../../../../../src/decorator/Index";
import {Counters} from "./Counters";
import {PrimaryColumn} from "../../../../../../../src/decorator/columns/PrimaryColumn";
@Entity()
@Index(["id", "counters.code", "counters.subcounters.version"], { unique: true })
export class Post {
@PrimaryColumn()
id: number;
@Column()
title: string;
@Embedded(() => Counters)
counters: Counters;
}

View File

@ -0,0 +1,21 @@
import {Column} from "../../../../../../../src/decorator/columns/Column";
import {ManyToMany} from "../../../../../../../src/decorator/relations/ManyToMany";
import {JoinTable} from "../../../../../../../src/decorator/relations/JoinTable";
import {PrimaryColumn} from "../../../../../../../src/decorator/columns/PrimaryColumn";
import {User} from "./User";
export class Subcounters {
@PrimaryColumn()
version: number;
@Column()
watches: number;
@ManyToMany(type => User, user => user.posts)
@JoinTable()
watchedUsers: User[];
watchedUserIds: number[];
}

View File

@ -0,0 +1,22 @@
import {Entity} from "../../../../../../../src/decorator/entity/Entity";
import {PrimaryColumn} from "../../../../../../../src/decorator/columns/PrimaryColumn";
import {Index} from "../../../../../../../src/decorator/Index";
import {ManyToMany} from "../../../../../../../src/decorator/relations/ManyToMany";
import {Post} from "./Post";
@Entity()
@Index(["id", "name"])
export class User {
@PrimaryColumn()
id: number;
@PrimaryColumn()
name: string;
@ManyToMany(type => Post, post => post.counters.subcounters.watchedUsers)
posts: Post[];
postIds: number[];
}

View File

@ -91,7 +91,6 @@ describe("query builder > relation-id > many-to-many > embedded", () => {
expect(loadedPosts[0].should.be.eql(
{
id: 1,
title: "About BMW",
counters: {
likes: 1,
@ -99,6 +98,7 @@ describe("query builder > relation-id > many-to-many > embedded", () => {
favorites: 3,
categoryIds: [1, 2],
subcounters: {
id: 1,
version: 1,
watches: 2,
watchedUserIds: [1, 2]
@ -108,7 +108,6 @@ describe("query builder > relation-id > many-to-many > embedded", () => {
));
expect(loadedPosts[1].should.be.eql(
{
id: 2,
title: "About Boeing",
counters: {
likes: 3,
@ -116,6 +115,7 @@ describe("query builder > relation-id > many-to-many > embedded", () => {
favorites: 5,
categoryIds: [3, 4],
subcounters: {
id: 2,
version: 1,
watches: 1,
watchedUserIds: [3]

View File

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

View File

@ -1,10 +1,14 @@
import {Column} from "../../../../../../../src/decorator/columns/Column";
import {ManyToMany} from "../../../../../../../src/decorator/relations/ManyToMany";
import {User} from "./User";
import {JoinTable} from "../../../../../../../src/decorator/relations/JoinTable";
import {PrimaryGeneratedColumn} from "../../../../../../../src/decorator/columns/PrimaryGeneratedColumn";
import {User} from "./User";
export class Subcounters {
@PrimaryGeneratedColumn()
id: number;
@Column()
version: number;

View File

@ -91,7 +91,7 @@ describe("query builder > relation-id > many-to-many > multiple-pk", () => {
})));
it("should load ids when only one entity have multiple primary keys", () => Promise.all(connections.map(async connection => {
it("should load ids when only one entity have multiple primary key", () => Promise.all(connections.map(async connection => {
const image1 = new Image();
image1.name = "Image #1";
@ -472,7 +472,7 @@ describe("query builder > relation-id > many-to-many > multiple-pk", () => {
})));
it("should load ids when only one entity have multiple primary keys", () => Promise.all(connections.map(async connection => {
it("should load ids when only one entity have multiple primary key", () => Promise.all(connections.map(async connection => {
const category1 = new Category();
category1.id = 1;

View File

@ -110,7 +110,7 @@ describe("query builder > relation-id > many-to-one > basic-functionality", () =
expect(loadedPostCategory!.postId).to.be.equal(1);
})));
it("should load ids when loadRelationIdAndMap used on inherit relation and target entity has multiple primary keys", () => Promise.all(connections.map(async connection => {
it("should load ids when loadRelationIdAndMap used on nested relation and target entity has multiple primary keys", () => Promise.all(connections.map(async connection => {
const category = new Category();
category.name = "cars";

View File

@ -0,0 +1,155 @@
import "reflect-metadata";
import * as chai from "chai";
import {expect} from "chai";
import {
closeTestingConnections,
createTestingConnections,
reloadTestingDatabases
} from "../../../../../utils/test-utils";
import {Connection} from "../../../../../../src/connection/Connection";
import {Post} from "./entity/Post";
import {Category} from "./entity/Category";
import {Counters} from "./entity/Counters";
import {User} from "./entity/User";
import {Subcounters} from "./entity/Subcounters";
const should = chai.should();
describe("query builder > relation-id > many-to-one > embedded-with-multiple-pk", () => {
let connections: Connection[];
before(async () => connections = await createTestingConnections({
entities: [__dirname + "/entity/*{.js,.ts}"],
schemaCreate: true,
dropSchemaOnConnection: true,
}));
beforeEach(() => reloadTestingDatabases(connections));
after(() => closeTestingConnections(connections));
it("should load ids when loadRelationIdAndMap used on embedded table and each table have primary key", () => Promise.all(connections.map(async connection => {
const user1 = new User();
user1.id = 1;
user1.name = "Alice";
await connection.manager.save(user1);
const user2 = new User();
user2.id = 2;
user2.name = "Bob";
await connection.manager.save(user2);
const category1 = new Category();
category1.id = 1;
category1.name = "cars";
await connection.manager.save(category1);
const category2 = new Category();
category2.id = 2;
category2.name = "airplanes";
await connection.manager.save(category2);
const post1 = new Post();
post1.id = 1;
post1.title = "About BMW";
post1.counters = new Counters();
post1.counters.code = 111;
post1.counters.likes = 1;
post1.counters.comments = 2;
post1.counters.favorites = 3;
post1.counters.category = category1;
post1.counters.subcounters = new Subcounters();
post1.counters.subcounters.version = 1;
post1.counters.subcounters.watches = 2;
post1.counters.subcounters.watchedUser = user1;
await connection.manager.save(post1);
const post2 = new Post();
post2.id = 2;
post2.title = "About Boeing";
post2.counters = new Counters();
post2.counters.code = 222;
post2.counters.likes = 3;
post2.counters.comments = 4;
post2.counters.favorites = 5;
post2.counters.category = category2;
post2.counters.subcounters = new Subcounters();
post2.counters.subcounters.version = 1;
post2.counters.subcounters.watches = 1;
post2.counters.subcounters.watchedUser = user2;
await connection.manager.save(post2);
const loadedPosts = await connection.manager
.createQueryBuilder(Post, "post")
.loadRelationIdAndMap("post.counters.categoryId", "post.counters.category")
.loadRelationIdAndMap("post.counters.subcounters.watchedUserId", "post.counters.subcounters.watchedUser")
.orderBy("post.id")
.getMany();
expect(loadedPosts[0].should.be.eql(
{
id: 1,
title: "About BMW",
counters: {
code: 111,
likes: 1,
comments: 2,
favorites: 3,
categoryId: { id: 1, name: "cars"},
subcounters: {
version: 1,
watches: 2,
watchedUserId: { id: 1, name: "Alice"}
}
}
}
));
expect(loadedPosts[1].should.be.eql(
{
id: 2,
title: "About Boeing",
counters: {
code: 222,
likes: 3,
comments: 4,
favorites: 5,
categoryId: { id: 2, name: "airplanes"},
subcounters: {
version: 1,
watches: 1,
watchedUserId: { id: 2, name: "Bob"}
}
}
}
));
const loadedPost = await connection.manager
.createQueryBuilder(Post, "post")
.loadRelationIdAndMap("post.counters.categoryId", "post.counters.category")
.loadRelationIdAndMap("post.counters.subcounters.watchedUserId", "post.counters.subcounters.watchedUser")
.where("post.id = :id", { id: 1 })
.andWhere("post.counters.code = :code", { code: 111 })
.andWhere("post.counters.subcounters.version = :version", { version: 1 })
.getOne();
expect(loadedPost!.should.be.eql(
{
id: 1,
title: "About BMW",
counters: {
code: 111,
likes: 1,
comments: 2,
favorites: 3,
categoryId: { id: 1, name: "cars"},
subcounters: {
version: 1,
watches: 2,
watchedUserId: { id: 1, name: "Alice"}
}
}
}
));
})));
});

View File

@ -0,0 +1,15 @@
import {Entity} from "../../../../../../../src/decorator/entity/Entity";
import {PrimaryColumn} from "../../../../../../../src/decorator/columns/PrimaryColumn";
import {Index} from "../../../../../../../src/decorator/Index";
@Entity()
@Index(["id", "name"])
export class Category {
@PrimaryColumn()
id: number;
@PrimaryColumn()
name: string;
}

View File

@ -0,0 +1,30 @@
import {Column} from "../../../../../../../src/decorator/columns/Column";
import {Embedded} from "../../../../../../../src/decorator/Embedded";
import {PrimaryColumn} from "../../../../../../../src/decorator/columns/PrimaryColumn";
import {ManyToOne} from "../../../../../../../src/decorator/relations/ManyToOne";
import {Category} from "./Category";
import {Subcounters} from "./Subcounters";
export class Counters {
@PrimaryColumn()
code: number;
@Column()
likes: number;
@Column()
comments: number;
@Column()
favorites: number;
@ManyToOne(type => Category)
category: Category;
@Embedded(() => Subcounters)
subcounters: Subcounters;
categoryId: number[];
}

View File

@ -0,0 +1,21 @@
import {Entity} from "../../../../../../../src/decorator/entity/Entity";
import {Column} from "../../../../../../../src/decorator/columns/Column";
import {Embedded} from "../../../../../../../src/decorator/Embedded";
import {Index} from "../../../../../../../src/decorator/Index";
import {Counters} from "./Counters";
import {PrimaryColumn} from "../../../../../../../src/decorator/columns/PrimaryColumn";
@Entity()
@Index(["id", "counters.code", "counters.subcounters.version"], { unique: true })
export class Post {
@PrimaryColumn()
id: number;
@Column()
title: string;
@Embedded(() => Counters)
counters: Counters;
}

View File

@ -0,0 +1,19 @@
import {Column} from "../../../../../../../src/decorator/columns/Column";
import {PrimaryColumn} from "../../../../../../../src/decorator/columns/PrimaryColumn";
import {User} from "./User";
import {ManyToOne} from "../../../../../../../src/decorator/relations/ManyToOne";
export class Subcounters {
@PrimaryColumn()
version: number;
@Column()
watches: number;
@ManyToOne(type => User)
watchedUser: User;
watchedUserId: number;
}

View File

@ -0,0 +1,15 @@
import {Entity} from "../../../../../../../src/decorator/entity/Entity";
import {PrimaryColumn} from "../../../../../../../src/decorator/columns/PrimaryColumn";
import {Index} from "../../../../../../../src/decorator/Index";
@Entity()
@Index(["id", "name"])
export class User {
@PrimaryColumn()
id: number;
@PrimaryColumn()
name: string;
}

View File

@ -79,7 +79,6 @@ describe("query builder > relation-id > many-to-one > embedded", () => {
expect(loadedPosts[0].should.be.eql(
{
id: 1,
title: "About BMW",
counters: {
likes: 1,
@ -87,6 +86,7 @@ describe("query builder > relation-id > many-to-one > embedded", () => {
favorites: 3,
categoryId: 1,
subcounters: {
id: 1,
version: 1,
watches: 2,
watchedUserId: 1
@ -96,7 +96,6 @@ describe("query builder > relation-id > many-to-one > embedded", () => {
));
expect(loadedPosts[1].should.be.eql(
{
id: 2,
title: "About Boeing",
counters: {
likes: 3,
@ -104,6 +103,7 @@ describe("query builder > relation-id > many-to-one > embedded", () => {
favorites: 5,
categoryId: 2,
subcounters: {
id: 2,
version: 1,
watches: 1,
watchedUserId: 2

View File

@ -1,5 +1,4 @@
import {Column} from "../../../../../../../src/decorator/columns/Column";
import {JoinTable} from "../../../../../../../src/decorator/relations/JoinTable";
import {Embedded} from "../../../../../../../src/decorator/Embedded";
import {ManyToOne} from "../../../../../../../src/decorator/relations/ManyToOne";
import {Category} from "./Category";
@ -17,7 +16,6 @@ export class Counters {
favorites: number;
@ManyToOne(type => Category, category => category.posts)
@JoinTable()
category: Category;
@Embedded(() => Subcounters)

View File

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

View File

@ -1,9 +1,13 @@
import {Column} from "../../../../../../../src/decorator/columns/Column";
import {ManyToOne} from "../../../../../../../src/decorator/relations/ManyToOne";
import {PrimaryGeneratedColumn} from "../../../../../../../src/decorator/columns/PrimaryGeneratedColumn";
import {User} from "./User";
export class Subcounters {
@PrimaryGeneratedColumn()
id: number;
@Column()
version: number;

View File

@ -0,0 +1,187 @@
import "reflect-metadata";
import * as chai from "chai";
import {expect} from "chai";
import {
closeTestingConnections,
createTestingConnections,
reloadTestingDatabases
} from "../../../../../utils/test-utils";
import {Connection} from "../../../../../../src/connection/Connection";
import {Post} from "./entity/Post";
import {Category} from "./entity/Category";
import {Counters} from "./entity/Counters";
import {User} from "./entity/User";
import {Subcounters} from "./entity/Subcounters";
const should = chai.should();
describe("query builder > relation-id > one-to-many > embedded-with-multiple-pk", () => {
let connections: Connection[];
before(async () => connections = await createTestingConnections({
entities: [__dirname + "/entity/*{.js,.ts}"],
schemaCreate: true,
dropSchemaOnConnection: true,
}));
beforeEach(() => reloadTestingDatabases(connections));
after(() => closeTestingConnections(connections));
it("should load ids when loadRelationIdAndMap used on embedded table and each table have primary key", () => Promise.all(connections.map(async connection => {
const user1 = new User();
user1.id = 1;
user1.name = "Alice";
await connection.manager.save(user1);
const user2 = new User();
user2.id = 2;
user2.name = "Bob";
await connection.manager.save(user2);
const user3 = new User();
user3.id = 3;
user3.name = "Clara";
await connection.manager.save(user3);
const category1 = new Category();
category1.id = 1;
category1.name = "cars";
await connection.manager.save(category1);
const category2 = new Category();
category2.id = 2;
category2.name = "BMW";
await connection.manager.save(category2);
const category3 = new Category();
category3.id = 3;
category3.name = "airplanes";
await connection.manager.save(category3);
const category4 = new Category();
category4.id = 4;
category4.name = "Boeing";
await connection.manager.save(category4);
const post1 = new Post();
post1.id = 1;
post1.title = "About BMW";
post1.counters = new Counters();
post1.counters.code = 111;
post1.counters.likes = 1;
post1.counters.comments = 2;
post1.counters.favorites = 3;
post1.counters.categories = [category1, category2];
post1.counters.subcounters = new Subcounters();
post1.counters.subcounters.version = 1;
post1.counters.subcounters.watches = 2;
post1.counters.subcounters.watchedUsers = [user1, user2];
await connection.manager.save(post1);
const post2 = new Post();
post2.id = 2;
post2.title = "About Boeing";
post2.counters = new Counters();
post2.counters.code = 222;
post2.counters.likes = 3;
post2.counters.comments = 4;
post2.counters.favorites = 5;
post2.counters.categories = [category3, category4];
post2.counters.subcounters = new Subcounters();
post2.counters.subcounters.version = 1;
post2.counters.subcounters.watches = 1;
post2.counters.subcounters.watchedUsers = [user3];
await connection.manager.save(post2);
const loadedPosts = await connection.manager
.createQueryBuilder(Post, "post")
.loadRelationIdAndMap("post.counters.categoryIds", "post.counters.categories")
.loadRelationIdAndMap("post.counters.subcounters.watchedUserIds", "post.counters.subcounters.watchedUsers")
.orderBy("post.id")
.getMany();
expect(loadedPosts[0].should.be.eql(
{
id: 1,
title: "About BMW",
counters: {
code: 111,
likes: 1,
comments: 2,
favorites: 3,
categoryIds: [
{ id: 1, name: "cars"},
{ id: 2, name: "BMW"}
],
subcounters: {
version: 1,
watches: 2,
watchedUserIds: [
{ id: 1, name: "Alice"},
{ id: 2, name: "Bob"}
]
}
}
}
));
expect(loadedPosts[1].should.be.eql(
{
id: 2,
title: "About Boeing",
counters: {
code: 222,
likes: 3,
comments: 4,
favorites: 5,
categoryIds: [
{ id: 3, name: "airplanes"},
{ id: 4, name: "Boeing"}
],
subcounters: {
version: 1,
watches: 1,
watchedUserIds: [
{ id: 3, name: "Clara"}
]
}
}
}
));
const loadedPost = await connection.manager
.createQueryBuilder(Post, "post")
.loadRelationIdAndMap("post.counters.categoryIds", "post.counters.categories")
.loadRelationIdAndMap("post.counters.subcounters.watchedUserIds", "post.counters.subcounters.watchedUsers")
.where("post.id = :id", { id: 1 })
.andWhere("post.counters.code = :code", { code: 111 })
.andWhere("post.counters.subcounters.version = :version", { version: 1 })
.getOne();
expect(loadedPost!.should.be.eql(
{
id: 1,
title: "About BMW",
counters: {
code: 111,
likes: 1,
comments: 2,
favorites: 3,
categoryIds: [
{ id: 1, name: "cars"},
{ id: 2, name: "BMW"}
],
subcounters: {
version: 1,
watches: 2,
watchedUserIds: [
{ id: 1, name: "Alice"},
{ id: 2, name: "Bob"}
]
}
}
}
));
})));
});

View File

@ -0,0 +1,20 @@
import {Entity} from "../../../../../../../src/decorator/entity/Entity";
import {PrimaryColumn} from "../../../../../../../src/decorator/columns/PrimaryColumn";
import {Index} from "../../../../../../../src/decorator/Index";
import {Post} from "./Post";
import {ManyToOne} from "../../../../../../../src/decorator/relations/ManyToOne";
@Entity()
@Index(["id", "name"])
export class Category {
@PrimaryColumn()
id: number;
@PrimaryColumn()
name: string;
@ManyToOne(type => Post, post => post.counters.categories)
post: Post;
}

View File

@ -0,0 +1,30 @@
import {Column} from "../../../../../../../src/decorator/columns/Column";
import {Embedded} from "../../../../../../../src/decorator/Embedded";
import {PrimaryColumn} from "../../../../../../../src/decorator/columns/PrimaryColumn";
import {OneToMany} from "../../../../../../../src/decorator/relations/OneToMany";
import {Category} from "./Category";
import {Subcounters} from "./Subcounters";
export class Counters {
@PrimaryColumn()
code: number;
@Column()
likes: number;
@Column()
comments: number;
@Column()
favorites: number;
@OneToMany(type => Category, category => category.post)
categories: Category[];
@Embedded(() => Subcounters)
subcounters: Subcounters;
categoryIds: number[];
}

View File

@ -0,0 +1,21 @@
import {Entity} from "../../../../../../../src/decorator/entity/Entity";
import {Column} from "../../../../../../../src/decorator/columns/Column";
import {Embedded} from "../../../../../../../src/decorator/Embedded";
import {Index} from "../../../../../../../src/decorator/Index";
import {Counters} from "./Counters";
import {PrimaryColumn} from "../../../../../../../src/decorator/columns/PrimaryColumn";
@Entity()
@Index(["id", "counters.code", "counters.subcounters.version"], { unique: true })
export class Post {
@PrimaryColumn()
id: number;
@Column()
title: string;
@Embedded(() => Counters)
counters: Counters;
}

View File

@ -0,0 +1,19 @@
import {Column} from "../../../../../../../src/decorator/columns/Column";
import {PrimaryColumn} from "../../../../../../../src/decorator/columns/PrimaryColumn";
import {OneToMany} from "../../../../../../../src/decorator/relations/OneToMany";
import {User} from "./User";
export class Subcounters {
@PrimaryColumn()
version: number;
@Column()
watches: number;
@OneToMany(type => User, user => user.post)
watchedUsers: User[];
watchedUserIds: number[];
}

View File

@ -0,0 +1,20 @@
import {Entity} from "../../../../../../../src/decorator/entity/Entity";
import {PrimaryColumn} from "../../../../../../../src/decorator/columns/PrimaryColumn";
import {Index} from "../../../../../../../src/decorator/Index";
import {ManyToOne} from "../../../../../../../src/decorator/relations/ManyToOne";
import {Post} from "./Post";
@Entity()
@Index(["id", "name"])
export class User {
@PrimaryColumn()
id: number;
@PrimaryColumn()
name: string;
@ManyToOne(type => Post, post => post.counters.subcounters.watchedUsers)
post: Post;
}

View File

@ -91,7 +91,6 @@ describe("query builder > relation-id > many-to-many > embedded", () => {
expect(loadedPosts[0].should.be.eql(
{
id: 1,
title: "About BMW",
counters: {
likes: 1,
@ -99,6 +98,7 @@ describe("query builder > relation-id > many-to-many > embedded", () => {
favorites: 3,
categoryIds: [1, 2],
subcounters: {
id: 1,
version: 1,
watches: 2,
watchedUserIds: [1, 2]
@ -108,7 +108,6 @@ describe("query builder > relation-id > many-to-many > embedded", () => {
));
expect(loadedPosts[1].should.be.eql(
{
id: 2,
title: "About Boeing",
counters: {
likes: 3,
@ -116,6 +115,7 @@ describe("query builder > relation-id > many-to-many > embedded", () => {
favorites: 5,
categoryIds: [3, 4],
subcounters: {
id: 2,
version: 1,
watches: 1,
watchedUserIds: [3]

View File

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

View File

@ -1,9 +1,13 @@
import {Column} from "../../../../../../../src/decorator/columns/Column";
import {OneToMany} from "../../../../../../../src/decorator/relations/OneToMany";
import {PrimaryGeneratedColumn} from "../../../../../../../src/decorator/columns/PrimaryGeneratedColumn";
import {User} from "./User";
export class Subcounters {
@PrimaryGeneratedColumn()
id: number;
@Column()
version: number;

View File

@ -0,0 +1,155 @@
import "reflect-metadata";
import * as chai from "chai";
import {expect} from "chai";
import {
closeTestingConnections,
createTestingConnections,
reloadTestingDatabases
} from "../../../../../utils/test-utils";
import {Connection} from "../../../../../../src/connection/Connection";
import {Post} from "./entity/Post";
import {Category} from "./entity/Category";
import {Counters} from "./entity/Counters";
import {User} from "./entity/User";
import {Subcounters} from "./entity/Subcounters";
const should = chai.should();
describe("query builder > relation-id > one-to-one > embedded-with-multiple-pk", () => {
let connections: Connection[];
before(async () => connections = await createTestingConnections({
entities: [__dirname + "/entity/*{.js,.ts}"],
schemaCreate: true,
dropSchemaOnConnection: true,
}));
beforeEach(() => reloadTestingDatabases(connections));
after(() => closeTestingConnections(connections));
it("should load ids when loadRelationIdAndMap used on embedded table and each table have primary key", () => Promise.all(connections.map(async connection => {
const user1 = new User();
user1.id = 1;
user1.name = "Alice";
await connection.manager.save(user1);
const user2 = new User();
user2.id = 2;
user2.name = "Bob";
await connection.manager.save(user2);
const category1 = new Category();
category1.id = 1;
category1.name = "cars";
await connection.manager.save(category1);
const category2 = new Category();
category2.id = 2;
category2.name = "airplanes";
await connection.manager.save(category2);
const post1 = new Post();
post1.id = 1;
post1.title = "About BMW";
post1.counters = new Counters();
post1.counters.code = 111;
post1.counters.likes = 1;
post1.counters.comments = 2;
post1.counters.favorites = 3;
post1.counters.category = category1;
post1.counters.subcounters = new Subcounters();
post1.counters.subcounters.version = 1;
post1.counters.subcounters.watches = 2;
post1.counters.subcounters.watchedUser = user1;
await connection.manager.save(post1);
const post2 = new Post();
post2.id = 2;
post2.title = "About Boeing";
post2.counters = new Counters();
post2.counters.code = 222;
post2.counters.likes = 3;
post2.counters.comments = 4;
post2.counters.favorites = 5;
post2.counters.category = category2;
post2.counters.subcounters = new Subcounters();
post2.counters.subcounters.version = 1;
post2.counters.subcounters.watches = 1;
post2.counters.subcounters.watchedUser = user2;
await connection.manager.save(post2);
const loadedPosts = await connection.manager
.createQueryBuilder(Post, "post")
.loadRelationIdAndMap("post.counters.categoryId", "post.counters.category")
.loadRelationIdAndMap("post.counters.subcounters.watchedUserId", "post.counters.subcounters.watchedUser")
.orderBy("post.id")
.getMany();
expect(loadedPosts[0].should.be.eql(
{
id: 1,
title: "About BMW",
counters: {
code: 111,
likes: 1,
comments: 2,
favorites: 3,
categoryId: { id: 1, name: "cars"},
subcounters: {
version: 1,
watches: 2,
watchedUserId: { id: 1, name: "Alice"}
}
}
}
));
expect(loadedPosts[1].should.be.eql(
{
id: 2,
title: "About Boeing",
counters: {
code: 222,
likes: 3,
comments: 4,
favorites: 5,
categoryId: { id: 2, name: "airplanes"},
subcounters: {
version: 1,
watches: 1,
watchedUserId: { id: 2, name: "Bob"}
}
}
}
));
const loadedPost = await connection.manager
.createQueryBuilder(Post, "post")
.loadRelationIdAndMap("post.counters.categoryId", "post.counters.category")
.loadRelationIdAndMap("post.counters.subcounters.watchedUserId", "post.counters.subcounters.watchedUser")
.where("post.id = :id", { id: 1 })
.andWhere("post.counters.code = :code", { code: 111 })
.andWhere("post.counters.subcounters.version = :version", { version: 1 })
.getOne();
expect(loadedPost!.should.be.eql(
{
id: 1,
title: "About BMW",
counters: {
code: 111,
likes: 1,
comments: 2,
favorites: 3,
categoryId: { id: 1, name: "cars"},
subcounters: {
version: 1,
watches: 2,
watchedUserId: { id: 1, name: "Alice"}
}
}
}
));
})));
});

View File

@ -0,0 +1,15 @@
import {Entity} from "../../../../../../../src/decorator/entity/Entity";
import {PrimaryColumn} from "../../../../../../../src/decorator/columns/PrimaryColumn";
import {Index} from "../../../../../../../src/decorator/Index";
@Entity()
@Index(["id", "name"])
export class Category {
@PrimaryColumn()
id: number;
@PrimaryColumn()
name: string;
}

View File

@ -0,0 +1,32 @@
import {Column} from "../../../../../../../src/decorator/columns/Column";
import {Embedded} from "../../../../../../../src/decorator/Embedded";
import {PrimaryColumn} from "../../../../../../../src/decorator/columns/PrimaryColumn";
import {OneToOne} from "../../../../../../../src/decorator/relations/OneToOne";
import {JoinColumn} from "../../../../../../../src/decorator/relations/JoinColumn";
import {Category} from "./Category";
import {Subcounters} from "./Subcounters";
export class Counters {
@PrimaryColumn()
code: number;
@Column()
likes: number;
@Column()
comments: number;
@Column()
favorites: number;
@OneToOne(type => Category)
@JoinColumn()
category: Category;
@Embedded(() => Subcounters)
subcounters: Subcounters;
categoryId: number[];
}

View File

@ -0,0 +1,21 @@
import {Entity} from "../../../../../../../src/decorator/entity/Entity";
import {Column} from "../../../../../../../src/decorator/columns/Column";
import {Embedded} from "../../../../../../../src/decorator/Embedded";
import {Index} from "../../../../../../../src/decorator/Index";
import {Counters} from "./Counters";
import {PrimaryColumn} from "../../../../../../../src/decorator/columns/PrimaryColumn";
@Entity()
@Index(["id", "counters.code", "counters.subcounters.version"], { unique: true })
export class Post {
@PrimaryColumn()
id: number;
@Column()
title: string;
@Embedded(() => Counters)
counters: Counters;
}

View File

@ -0,0 +1,21 @@
import {Column} from "../../../../../../../src/decorator/columns/Column";
import {PrimaryColumn} from "../../../../../../../src/decorator/columns/PrimaryColumn";
import {OneToOne} from "../../../../../../../src/decorator/relations/OneToOne";
import {JoinColumn} from "../../../../../../../src/decorator/relations/JoinColumn";
import {User} from "./User";
export class Subcounters {
@PrimaryColumn()
version: number;
@Column()
watches: number;
@OneToOne(type => User)
@JoinColumn()
watchedUser: User;
watchedUserId: number;
}

View File

@ -0,0 +1,15 @@
import {Entity} from "../../../../../../../src/decorator/entity/Entity";
import {PrimaryColumn} from "../../../../../../../src/decorator/columns/PrimaryColumn";
import {Index} from "../../../../../../../src/decorator/Index";
@Entity()
@Index(["id", "name"])
export class User {
@PrimaryColumn()
id: number;
@PrimaryColumn()
name: string;
}

View File

@ -79,7 +79,6 @@ describe("query builder > relation-id > one-to-one > embedded", () => {
expect(loadedPosts[0].should.be.eql(
{
id: 1,
title: "About BMW",
counters: {
likes: 1,
@ -87,6 +86,7 @@ describe("query builder > relation-id > one-to-one > embedded", () => {
favorites: 3,
categoryId: 1,
subcounters: {
id: 1,
version: 1,
watches: 2,
watchedUserId: 1
@ -96,7 +96,6 @@ describe("query builder > relation-id > one-to-one > embedded", () => {
));
expect(loadedPosts[1].should.be.eql(
{
id: 2,
title: "About Boeing",
counters: {
likes: 3,
@ -104,6 +103,7 @@ describe("query builder > relation-id > one-to-one > embedded", () => {
favorites: 5,
categoryId: 2,
subcounters: {
id: 2,
version: 1,
watches: 1,
watchedUserId: 2

View File

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

View File

@ -1,10 +1,14 @@
import {Column} from "../../../../../../../src/decorator/columns/Column";
import {User} from "./User";
import {OneToOne} from "../../../../../../../src/decorator/relations/OneToOne";
import {JoinColumn} from "../../../../../../../src/decorator/relations/JoinColumn";
import {PrimaryGeneratedColumn} from "../../../../../../../src/decorator/columns/PrimaryGeneratedColumn";
import {User} from "./User";
export class Subcounters {
@PrimaryGeneratedColumn()
id: number;
@Column()
version: number;