Skip to content
This repository was archived by the owner on May 18, 2024. It is now read-only.

Commit 19843c4

Browse files
authored
Merge pull request #58 from samchon/v1.0
Close #56 and Close #57
2 parents 64dadd8 + 32c2c99 commit 19843c4

13 files changed

+526
-146
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "safe-typeorm",
3-
"version": "1.0.5",
3+
"version": "1.0.6",
44
"description": "Safe Relationship Decorators for the TypeORM",
55
"main": "lib/index.js",
66
"typings": "lib/index.d.ts",

src/builders/AppJoinBuilder.ts

+11-22
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,7 @@ import { SpecialFields } from "../typings/SpecialFields";
66
import { ReflectAdaptor } from "../decorators/base/ReflectAdaptor";
77

88
import { IAppJoinChildTuple } from "./internal/IAppJoinChildTuple";
9-
import { app_join_belongs_many_to_one } from "./internal/app_join_belongs_many_to_one";
10-
import { app_join_belongs_one_to_one } from "./internal/app_join_belongs_one_to_one";
11-
import { app_join_has_many_to_many } from "./internal/app_join_has_many_to_many";
12-
import { app_join_has_one_to_many } from "./internal/app_join_has_one_to_many";
13-
import { app_join_has_one_to_one } from "./internal/app_join_has_one_to_one";
9+
import { get_app_join_function } from "./internal/get_app_join_function";
1410

1511
/**
1612
* Application level join builder.
@@ -74,8 +70,6 @@ export class AppJoinBuilder<Mine extends object>
7470
*/
7571
public constructor(mine: Creator<Mine>)
7672
{
77-
new Array(3)
78-
7973
this.mine_ = mine;
8074
this.children_ = new Map();
8175
}
@@ -209,21 +203,16 @@ export class AppJoinBuilder<Mine extends object>
209203
{
210204
for (const [field, child] of this.children_.entries())
211205
{
212-
// JOIN WITH RELATED ENTITIES
213-
let output: Relationship.TargetType<Mine, any>[];
214-
if (child.metadata.type === "Belongs.ManyToOne" || child.metadata.type === "Belongs.External.ManyToOne")
215-
output = await app_join_belongs_many_to_one(this.mine_, child as any, data, field);
216-
else if (child.metadata.type === "Belongs.OneToOne" || child.metadata.type === "Belongs.External.OneToOne")
217-
output = await app_join_belongs_one_to_one(child as any, data, field);
218-
else if (child.metadata.type === "Has.OneToOne" || child.metadata.type === "Has.External.OneToOne")
219-
output = await app_join_has_one_to_one(this.mine_, child as any, data, field);
220-
else if (child.metadata.type === "Has.OneToMany" || child.metadata.type === "Has.External.OneToMany")
221-
output = await app_join_has_one_to_many(this.mine_, child as any, data, field);
222-
else if (child.metadata.type === "Has.ManyToMany")
223-
output = await app_join_has_many_to_many(this.mine_, child as any, data, field);
224-
else
225-
continue;
226-
206+
// CALL APP JOIN FUNCTION
207+
const func: Function = get_app_join_function(child.metadata.type);
208+
const output: Relationship.TargetType<Mine, any>[] = await func
209+
(
210+
this.mine_,
211+
child.metadata,
212+
data,
213+
field
214+
);
215+
227216
// HIERARCHICAL CALL
228217
if (output.length !== 0)
229218
await child.builder._Execute(output);
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,68 @@
11
import { Belongs } from "../../decorators/Belongs";
22
import { Creator } from "../../typings/Creator";
3+
import { SpecialFields } from "../../typings/SpecialFields";
34
import { ITableInfo } from "../../functional/internal/ITableInfo";
45

5-
import { IAppJoinChildTuple } from "./IAppJoinChildTuple";
66
import { get_records_by_where_in } from "./get_records_by_where_in";
77

88
/**
99
* @internal
1010
*/
11-
export async function app_join_belongs_many_to_one
11+
export async function app_join_belongs_many_to_one<
12+
Mine extends object,
13+
Target extends object,
14+
Field extends SpecialFields<Mine, Belongs.ManyToOne<Target, any> | Belongs.External.ManyToOne<Target, any>>>
1215
(
13-
mine: Creator<any>,
14-
child: IAppJoinChildTuple<any, Belongs.ManyToOne.IMetadata<any> | Belongs.OneToOne.IMetadata<any>>,
15-
data: any[],
16-
field: any,
17-
): Promise<any[]>
16+
mine: Creator<Mine>,
17+
metadata: Belongs.ManyToOne.IMetadata<Target> | Belongs.External.ManyToOne.IMetadata<Target>,
18+
myData: Mine[],
19+
field: Field,
20+
targetData?: Target[]
21+
): Promise<Target[]>
1822
{
1923
// NO DATA
20-
if (data.length === 0)
24+
if (myData.length === 0)
2125
return [];
2226

2327
// NO REFERENCE
24-
const idList: any[] = data
25-
.map(elem => elem[field].id)
28+
const idList: any[] = myData
29+
.map(elem => (<any>elem[field] as Belongs.ManyToOne<Target, any>).id)
2630
.filter(id => id !== null);
2731
if (idList.length === 0)
2832
return [];
2933

3034
// THE TARGET INFO
31-
const target: Creator<any> = child.metadata.target();
35+
const target: Creator<Target> = metadata.target();
3236
const table: ITableInfo = ITableInfo.get(target);
3337

3438
// LOAD TARGET DATA
35-
const output: any[] = await get_records_by_where_in(target, table.primaryColumn, idList);
39+
const output: Target[]
40+
= targetData
41+
|| await get_records_by_where_in(target, table.primaryColumn, idList);
3642

3743
// LINK RELATIONSHIPS
38-
const dict: Map<any, any> = new Map(output.map(elem => [ elem[table.primaryColumn], elem ]));
39-
for (const elem of data)
44+
const dict: Map<any, any> = new Map(output.map(elem => [ (elem as any)[table.primaryColumn], elem ]));
45+
for (const elem of myData)
4046
{
41-
const id: any | null = elem[field].id;
42-
if (id === null)
47+
const accessor = <any>elem[field] as Belongs.ManyToOne<Target, any>;
48+
if (accessor.id === null)
4349
continue;
4450

45-
const reference: any = dict.get(id)!;
46-
await elem[field].set(reference);
51+
const reference: any = dict.get(accessor.id)!;
52+
await accessor.set(reference);
4753
}
4854

4955
// RECURSIVE
50-
if (target === mine)
51-
await app_join_belongs_many_to_one(mine, child, output, field);
52-
56+
if (<any>target === mine && targetData === undefined)
57+
{
58+
const surplus: Target[] = await app_join_belongs_many_to_one
59+
(
60+
mine,
61+
metadata,
62+
<any>output as Mine[],
63+
field
64+
);
65+
output.push(...surplus);
66+
}
5367
return output;
54-
}
68+
}
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,73 @@
11
import { Belongs } from "../../decorators/Belongs";
22
import { Creator } from "../../typings/Creator";
3+
import { SpecialFields } from "../../typings/SpecialFields";
34
import { ITableInfo } from "../../functional/internal/ITableInfo";
45

5-
import { IAppJoinChildTuple } from "./IAppJoinChildTuple";
66
import { get_records_by_where_in } from "./get_records_by_where_in";
77

88
/**
99
* @internal
1010
*/
11-
export async function app_join_belongs_one_to_one
11+
export async function app_join_belongs_one_to_one<
12+
Mine extends object,
13+
Target extends object,
14+
Field extends SpecialFields<Mine, Belongs.OneToOne<Target, any> | Belongs.External.OneToOne<Target, any>>>
1215
(
13-
child: IAppJoinChildTuple<any, Belongs.ManyToOne.IMetadata<any> | Belongs.OneToOne.IMetadata<any>>,
14-
data: any[],
15-
field: any,
16-
): Promise<any[]>
16+
mine: Creator<Mine>,
17+
metadata: Belongs.OneToOne.IMetadata<Target> | Belongs.External.OneToOne.IMetadata<Target>,
18+
myData: Mine[],
19+
field: Field,
20+
targetData?: Target[]
21+
): Promise<Target[]>
1722
{
1823
// NO DATA
19-
if (data.length === 0)
24+
if (myData.length === 0)
2025
return [];
2126

2227
// NO REFERENCE
23-
const idList: any[] = data
24-
.map(elem => elem[field].id)
28+
const idList: any[] = myData
29+
.map(elem => (<any>elem[field] as Belongs.ManyToOne<Target, any>).id)
2530
.filter(id => id !== null);
2631
if (idList.length === 0)
2732
return [];
2833

2934
// THE TARGET INFO
30-
const target: Creator<any> = child.metadata.target();
35+
const target: Creator<Target> = metadata.target();
3136
const table: ITableInfo = ITableInfo.get(target);
3237

3338
// LOAD TARGET DATA
34-
const output: any[] = await get_records_by_where_in(target, table.primaryColumn, idList);
39+
const output: Target[]
40+
= targetData
41+
|| await get_records_by_where_in(target, table.primaryColumn, idList);
3542

3643
// LINK RELATIONSHIPS
37-
const dict: Map<any, any> = new Map(output.map(elem => [ elem[table.primaryColumn], elem ]));
38-
for (const elem of data)
44+
const dict: Map<any, any> = new Map(output.map(elem => [ (elem as any)[table.primaryColumn], elem ]));
45+
for (const elem of myData)
3946
{
40-
const id: any | null = elem[field].id;
41-
if (id === null)
47+
const accessor = <any>elem[field] as Belongs.ManyToOne<Target, any>;
48+
if (accessor.id === null)
4249
continue;
4350

44-
const reference: any = dict.get(id)!;
45-
await elem[field].set(reference);
51+
const reference: any | undefined = dict.get(accessor.id);
52+
if (reference === undefined)
53+
continue;
54+
55+
await accessor.set(reference);
56+
if (metadata.inverse !== null)
57+
await reference[metadata.inverse].set(elem);
58+
}
4659

47-
if (child.metadata.inverse !== null)
48-
await reference[child.metadata.inverse].set(elem);
60+
// RECURSIVE
61+
if (<any>target === mine && targetData === undefined)
62+
{
63+
const surplus: Target[] = await app_join_belongs_one_to_one
64+
(
65+
mine,
66+
metadata,
67+
<any>output as Mine[],
68+
field
69+
);
70+
output.push(...surplus);
4971
}
5072
return output;
5173
}

0 commit comments

Comments
 (0)