-
Notifications
You must be signed in to change notification settings - Fork 1
/
model-relationship.ts
156 lines (128 loc) · 4.07 KB
/
model-relationship.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
import { CardinalityType } from '../../metadata/';
import { assert } from '../../error/';
import { ModelTable, ModelColumn, RelationshipFormatter } from '../';
/**
* Helper class that stores relationship data for the model generator.
*/
export class ModelRelationship {
private localTable: ModelTable;
private referencedTable: ModelTable;
private columns: ModelColumn[][] = [];
private cardinality: CardinalityType;
/**
* Initialize the relationship.
* @param relFormatter - A [[RelationshipFormatter]] instances that is used
* to format relationship property names.
*/
constructor(
private relFormatter: RelationshipFormatter) {
}
/**
* Set the local and referenced tables.
* @param localTable - The [[ModelTable]] to which this relationship belongs.
* @param referencedTable - The [[ModelTable]] that the relationship references.
* @param cardinality - How the two tables relate.
*/
setTables(
localTable: ModelTable,
referencedTable: ModelTable,
cardinality: CardinalityType): this {
this.localTable = localTable;
this.referencedTable = referencedTable;
this.cardinality = cardinality;
return this;
}
/**
* Add a set of columns to join on.
* @param localColumn - The [[ModelColumn]] used in this relationship that is
* owned by the local [[ModelTable]].
* @param referencedColumn - The [[ModelColumn]] that is referenced in the
* foreign [[ModelTable]].
*/
addColumns(localColumn: ModelColumn, referencedColumn: ModelColumn): this {
this.columns.push([localColumn, referencedColumn]);
return this;
}
/**
* Get the array of columns. Each entry in the array has two [[ModelColumn]]
* instances: one for the local column; one for the remote column.
*/
getColumns(): ModelColumn[][] {
return this.columns;
}
/**
* Get the local table.
*/
getLocalTable(): ModelTable {
assert(this.localTable, 'ModelRelationship instance has no tables.');
return this.localTable;
}
/**
* Get the referenced table.
*/
getReferencedTable(): ModelTable {
assert(this.referencedTable, 'ModelRelationship instance has no tables.')
return this.referencedTable;
}
/**
* Get the local table's class name.
*/
getLocalClassName(): string {
return this.getLocalTable().getClassName();
}
/**
* Get the referenced table name.
*/
getReferencedClassName(): string {
return this.getReferencedTable().getClassName();
}
/**
* Get the on part of the decorator string.
*/
getOnString(): string {
assert(this.columns.length, 'ModelRelationship instance has no columns.');
const colSets = this.columns
.map(([local, remote]) => {
const lProp = local.getPropertyName();
const rProp = remote.getPropertyName();
return `[l.${lProp}, r.${rProp}]`;
});
if (colSets.length === 1)
return `(l, r) => ${colSets[0]}`;
return `(l, r) => [${colSets.join(', ')}]`;
}
/**
* Get the cardinality, which is the name of the decorator.
*/
getCardinality(): CardinalityType {
return this.cardinality;
}
/**
* Get the relationship decorator string.
*/
getDecoratorString(): string {
const locTblName = this.getLocalClassName();
const refTblName = this.getReferencedClassName();
const onString = this.getOnString();
const cardinality = this.getCardinality();
return ` @${cardinality}<${locTblName}, ${refTblName}>(() => ${refTblName}, ${onString})`;
}
/**
* Returns the property string.
*/
getPropertyString(): string {
const refTblName = this.getReferencedClassName();
const cardinality = this.getCardinality();
const propName = this.relFormatter.formatPropertyName(this);
const className = cardinality === 'OneToMany' ?
`${this.getReferencedClassName()}[]` :
this.getReferencedClassName();
return ` ${propName}: ${className};`;
}
/**
* Convert the relationship to a string (decorator and property).
*/
toString(): string {
return this.getDecoratorString() + '\n' + this.getPropertyString();
}
}