Skip to content

Commit

Permalink
Merge branch 'master' into next
Browse files Browse the repository at this point in the history
* master:
  updated changelog
  fixed typeorm#1504
  removed only test
  Update one-to-one-relations.md
  Handle SQLite in-memory db in ConnectionOptionsReader
  Update eager-and-lazy-relations.md
  Update eager-and-lazy-relations.md
  Update issue-1569.ts
  skipped test typeorm#1569 (need to fix in @next)
  Update entities.md
  Update entities.md
  added test for typeorm#1581
  Update select-query-builder.md
  create failing test case for issue 1569

# Conflicts:
#	docs/eager-and-lazy-relations.md
  • Loading branch information
Umed Khudoiberdiev committed Feb 20, 2018
2 parents 7ce144e + 6c005d9 commit 43f89d4
Show file tree
Hide file tree
Showing 22 changed files with 328 additions and 7 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,10 @@ By default its true.
This fixed various issues on how real arrays must work

## 0.1.13

* added simple-json column type ([#1448](https://github.com/typeorm/typeorm/pull/1488))
* fixed transform behaviour for timestamp columns ([#1140](https://github.com/typeorm/typeorm/issues/1140))
* fixed issue with multi-level relations loading ([#1504](https://github.com/typeorm/typeorm/issues/1504))

## 0.1.12

Expand Down
4 changes: 2 additions & 2 deletions docs/eager-and-lazy-relations.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,8 @@ Example how to load objects inside lazy relations:

```typescript
const question = await connection.getRepository(Question).findOne(1);
const answers = await question.answers;
// you'll have all question's answers inside "answers" variable now
const categories = await question.categories;
// you'll have all question's categories inside "categories" variable now
```

Note: if you came from other languages (Java, PHP, etc.) and are used to use lazy relations everywhere - be careful.
Expand Down
2 changes: 2 additions & 0 deletions docs/entities.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ const connection: Connection = await createConnection({
If you want to use an alternative table name for the `User` entity you can specify it in `@Entity`: `@Entity("my_users")`.
If you want to set a base prefix for all database tables in your application you can specify `entityPrefix` in connection options.

When using an entity constructor its arguments **must be optional**. Since ORM creates instances of entity classes when loading from the database, therefore it is not aware of your constructor arguments.

Learn more about parameters @Entity in [Decorators reference](decorator-reference.md).

## Entity columns
Expand Down
2 changes: 1 addition & 1 deletion docs/one-to-one-relations.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# One-to-one relations

One-to-one is a relation where A contains only once instance of B, and B contains only one instance of A.
One-to-one is a relation where A contains only one instance of B, and B contains only one instance of A.
Let's take for example `User` and `Profile` entities.
User can have only a single profile, and a single profile is owned by only a single user.

Expand Down
2 changes: 1 addition & 1 deletion docs/select-query-builder.md
Original file line number Diff line number Diff line change
Expand Up @@ -936,7 +936,7 @@ export class User {
}
```
Using a standard `find` or query, you will not recieve the `name` property for the model. However, if you do the following:
Using a standard `find` or query, you will not recieve the `password` property for the model. However, if you do the following:
```typescript
const users = await connection.getRepository(User)
Expand Down
2 changes: 1 addition & 1 deletion src/connection/ConnectionOptionsReader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ export class ConnectionOptionsReader {

// make database path file in sqlite relative to package.json
if (options.type === "sqlite") {
if (typeof options.database === "string" && options.database.substr(0, 1) !== "/") {
if (typeof options.database === "string" && options.database.substr(0, 1) !== "/" && options.database !== ":memory:") {
Object.assign(options, {
database: this.baseDirectory + "/" + options.database
});
Expand Down
2 changes: 1 addition & 1 deletion src/find-options/FindOptionsUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ export class FindOptionsUtils {

// try to find sub-relations
const join = qb.expressionMap.joinAttributes.find(join => join.entityOrProperty === selection);
this.applyRelationsRecursively(qb, allRelations, join!.alias.name, join!.metadata!, relation);
this.applyRelationsRecursively(qb, allRelations, join!.alias.name, join!.metadata!, prefix ? prefix + "." + relation : relation);
});
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module.exports = [{
type: "sqlite",
name: "file",
database: "test"
}, {
type: "sqlite",
name: "memory",
database: ":memory:",
}];
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,13 @@ describe("ConnectionOptionsReader", () => {
const entities: EntititesList = options.entities as EntititesList;
expect(entities.length).to.equal(1);
});
});

it("properly loads sqlite in-memory/path config", async () => {
const connectionOptionsReader = new ConnectionOptionsReader({ root: __dirname, configName: "configs/sqlite-memory" });
const inmemoryOptions: ConnectionOptions = await connectionOptionsReader.get("memory");
expect(inmemoryOptions.database).to.equal(":memory:");
const fileOptions: ConnectionOptions = await connectionOptionsReader.get("file");
expect(fileOptions.database).to.have.string("/test");
});

});
15 changes: 15 additions & 0 deletions test/github-issues/1504/entity/TestEntity1.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import {Column, Entity, JoinColumn, OneToOne, PrimaryGeneratedColumn} from "../../../../src";
import {TestEntity2} from "./TestEntity2";

@Entity()
export class TestEntity1 {

@PrimaryGeneratedColumn()
id: number;

@Column() name: string;

@OneToOne(t => TestEntity2, a => a.Entity1)
@JoinColumn()
Entity2: TestEntity2;
}
21 changes: 21 additions & 0 deletions test/github-issues/1504/entity/TestEntity2.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import {Column, Entity, JoinColumn, OneToOne, PrimaryGeneratedColumn} from "../../../../src";
import {TestEntity1} from "./TestEntity1";
import {TestEntity3} from "./TestEntity3";

@Entity()
export class TestEntity2 {

@PrimaryGeneratedColumn()
id: number;

@Column()
name: string;

@OneToOne(t => TestEntity1, a => a.Entity2)
Entity1: TestEntity1;

@OneToOne(t => TestEntity3, a => a.Entity2)
@JoinColumn()
Entity3: TestEntity3;

}
18 changes: 18 additions & 0 deletions test/github-issues/1504/entity/TestEntity3.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {Column, Entity, OneToMany, OneToOne, PrimaryGeneratedColumn} from "../../../../src";
import {TestEntity2} from "./TestEntity2";
import {TestEntity4} from "./TestEntity4";

@Entity()
export class TestEntity3 {
@PrimaryGeneratedColumn()
id: number;

@OneToOne(t => TestEntity2, a => a.Entity3)
Entity2: TestEntity2;

@Column()
name: string;

@OneToMany(t => TestEntity4, entity4 => entity4.Entity3)
Entity4: TestEntity4[];
}
15 changes: 15 additions & 0 deletions test/github-issues/1504/entity/TestEntity4.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import {Column, Entity, ManyToOne, PrimaryGeneratedColumn} from "../../../../src";
import {TestEntity3} from "./TestEntity3";

@Entity()
export class TestEntity4 {

@PrimaryGeneratedColumn()
id: number;

@Column()
name: string;

@ManyToOne(t => TestEntity3, entity3 => entity3.Entity4)
Entity3: TestEntity3;
}
28 changes: 28 additions & 0 deletions test/github-issues/1504/issue-1504.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import "reflect-metadata";
import {closeTestingConnections, createTestingConnections, reloadTestingDatabases} from "../../utils/test-utils";
import {Connection} from "../../../src/connection/Connection";
import {TestEntity1} from "./entity/TestEntity1";

describe("github issues > #1504 Cannot eagerly query Entity with relation more than 3 levels deep", () => {

let connections: Connection[];
before(async () => connections = await createTestingConnections({
entities: [__dirname + "/entity/*{.js,.ts}"],
enabledDrivers: ["postgres"]
}));
beforeEach(() => reloadTestingDatabases(connections));
after(() => closeTestingConnections(connections));

it("should not throw an error", () => Promise.all(connections.map(async connection => {

await connection
.getRepository(TestEntity1)
.findOne(1, { relations: [
"Entity2",
"Entity2.Entity3",
"Entity2.Entity3.Entity4",
]});

})));

});
18 changes: 18 additions & 0 deletions test/github-issues/1569/entity/Item.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Entity, Column, PrimaryGeneratedColumn } from "../../../../src/index";

export class EmbeddedItem {
@Column({ type: "integer", array: true })
arrayInsideEmbedded: number[];
}

@Entity()
export class Item {
@PrimaryGeneratedColumn()
id: number;

@Column()
someText: string;

@Column(type => EmbeddedItem)
embedded: EmbeddedItem;
}
39 changes: 39 additions & 0 deletions test/github-issues/1569/issue-1569.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import "reflect-metadata";
import { expect } from "chai";
import { Connection } from "../../../src/connection/Connection";
import { closeTestingConnections, createTestingConnections, reloadTestingDatabases } from "../../utils/test-utils";
import { Item, EmbeddedItem } from "./entity/Item";

describe.skip("github issue > #1569 updateById generates wrong SQL with arrays inside embeddeds", () => {

let connections: Connection[] = [];
before(async () => connections = await createTestingConnections({
entities: [__dirname + "/entity/*{.js,.ts}"],
enabledDrivers: ["postgres"],
}));
beforeEach(() => reloadTestingDatabases(connections));
after(() => closeTestingConnections(connections));

it("should properly updateById arrays inside embeddeds", () => Promise.all(connections.map(async connection => {
const item = new Item();
item.someText = "some";
const embedded = new EmbeddedItem();
embedded.arrayInsideEmbedded = [1, 2, 3];
item.embedded = embedded;

await connection.getRepository(Item).save(item);

await connection.getRepository(Item).updateById(item.id, {
someText: "some2",
embedded: {
arrayInsideEmbedded: [1, 2],
},
});

const loadedItem = await connection.getRepository(Item).findOneById(item.id);

expect(loadedItem!.embedded.arrayInsideEmbedded).to.eql([1, 2]);

})));

});
12 changes: 12 additions & 0 deletions test/github-issues/1581/entity/DeliverySlot.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import {Column, Entity, PrimaryGeneratedColumn} from "../../../../src";

@Entity()
export class DeliverySlot {

@PrimaryGeneratedColumn()
id: number;

@Column()
name: string;

}
20 changes: 20 additions & 0 deletions test/github-issues/1581/entity/Order.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {DeliverySlot} from "./DeliverySlot";
import {User} from "./User";
import {OrderItem} from "./OrderItem";
import {Column, Entity, ManyToOne, OneToMany} from "../../../../src";

@Entity()
export class Order {

@ManyToOne(type => DeliverySlot, { primary: true })
deliverySlot: DeliverySlot;

@ManyToOne(type => User, user => user.recurringOrders, { primary: true })
user: User;

@Column()
enabled: boolean;

@OneToMany(type => OrderItem, item => item.order)
items: OrderItem[];
}
17 changes: 17 additions & 0 deletions test/github-issues/1581/entity/OrderItem.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import {Column, Entity, ManyToOne} from "../../../../src";
import {Order} from "./Order";
import {Product} from "./Product";

@Entity()
export class OrderItem {

@ManyToOne(type => Order, recurringOrder => recurringOrder.items, { primary: true })
order: Order;

@ManyToOne(type => Product, { primary: true })
product: Product;

@Column()
amount: number;

}
12 changes: 12 additions & 0 deletions test/github-issues/1581/entity/Product.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import {Column, Entity} from "../../../../src";

@Entity()
export class Product {

@Column({ primary: true })
id: number;

@Column()
name: string;

}
16 changes: 16 additions & 0 deletions test/github-issues/1581/entity/User.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import {Column, Entity, OneToMany, PrimaryGeneratedColumn} from "../../../../src";
import {Order} from "./Order";

@Entity()
export class User {

@PrimaryGeneratedColumn()
id: number;

@Column({ unique: true })
email: string;

@OneToMany(type => Order, recurringOrder => recurringOrder.user)
recurringOrders: Order[];

}
Loading

0 comments on commit 43f89d4

Please sign in to comment.