orange-orm 4.3.0 → 4.4.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/changelog.md +0 -2
- package/getManyDto4.js +313 -0
- package/getManyDtoFast.js +530 -0
- package/package.json +1 -1
- package/src/client/index.mjs +373 -784
- package/src/getManyDto.js +117 -102
- package/src/getManyDtoFast2.js +293 -0
- package/src/getManyDtoFastes.js +588 -0
- package/src/table/column/binary/newEncode.js +7 -0
- package/src/table/column/boolean/newEncode.js +12 -0
- package/src/table/column/date/newEncode.js +13 -2
- package/src/table/column/dateWithTimeZone/newEncode.js +10 -0
- package/src/table/column/guid/newEncode.js +10 -0
- package/src/table/column/in.js +11 -14
- package/src/table/column/json/newEncode.js +15 -0
- package/src/table/column/numeric/newEncode.js +10 -0
- package/src/table/column/string/newEncode.js +10 -1
- package/src/table/getManyDtoFast3.js +313 -0
package/src/getManyDto.js
CHANGED
|
@@ -19,62 +19,92 @@ async function getManyDto(table, filter, strategy, spanFromParent) {
|
|
|
19
19
|
return decode(strategy, span, await res[0]);
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
// function newCreateRow(span) {
|
|
23
|
+
// let columnsMap = span.columns;
|
|
24
|
+
// const columns = span.table._columns.filter(column => !columnsMap || columnsMap.get(column));
|
|
25
|
+
// const protoRow = createProto(columns, span);
|
|
26
|
+
// const manyNames = [];
|
|
27
|
+
|
|
28
|
+
// const c = {};
|
|
29
|
+
// c.visitJoin = () => { };
|
|
30
|
+
// c.visitOne = () => { };
|
|
31
|
+
// c.visitMany = function(leg) {
|
|
32
|
+
// manyNames.push(leg.name);
|
|
33
|
+
// };
|
|
34
|
+
|
|
35
|
+
// span.legs.forEach(onEachLeg);
|
|
36
|
+
// return createRow;
|
|
37
|
+
|
|
38
|
+
// function onEachLeg(leg) {
|
|
39
|
+
// leg.accept(c);
|
|
40
|
+
// }
|
|
41
|
+
|
|
42
|
+
// function createRow() {
|
|
43
|
+
// const obj = Object.create(protoRow);
|
|
44
|
+
// for (let i = 0; i < manyNames.length; i++) {
|
|
45
|
+
// obj[manyNames[i]] = [];
|
|
46
|
+
// }
|
|
47
|
+
// return obj;
|
|
48
|
+
// }
|
|
49
|
+
// }
|
|
50
|
+
|
|
51
|
+
|
|
22
52
|
function newCreateRow(span) {
|
|
23
|
-
|
|
53
|
+
const columnsMap = span.columns;
|
|
24
54
|
const columns = span.table._columns.filter(column => !columnsMap || columnsMap.get(column));
|
|
25
|
-
const
|
|
55
|
+
const ProtoRow = createProto(columns, span);
|
|
26
56
|
const manyNames = [];
|
|
27
57
|
|
|
28
|
-
const c = {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
58
|
+
const c = {
|
|
59
|
+
visitJoin: () => { },
|
|
60
|
+
visitOne: () => { },
|
|
61
|
+
visitMany: function(leg) {
|
|
62
|
+
manyNames.push(leg.name);
|
|
63
|
+
}
|
|
33
64
|
};
|
|
34
65
|
|
|
35
|
-
span.legs.forEach(
|
|
36
|
-
return createRow;
|
|
66
|
+
span.legs.forEach(leg => leg.accept(c));
|
|
37
67
|
|
|
38
|
-
|
|
39
|
-
leg.accept(c);
|
|
40
|
-
}
|
|
68
|
+
return createRow;
|
|
41
69
|
|
|
42
70
|
function createRow() {
|
|
43
|
-
const obj =
|
|
44
|
-
|
|
45
|
-
obj[
|
|
46
|
-
}
|
|
71
|
+
const obj = new ProtoRow();
|
|
72
|
+
manyNames.forEach(name => {
|
|
73
|
+
obj[name] = [];
|
|
74
|
+
});
|
|
47
75
|
return obj;
|
|
48
76
|
}
|
|
49
77
|
}
|
|
50
78
|
|
|
51
79
|
function createProto(columns, span) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
for (let key in span.aggregates) {
|
|
57
|
-
obj[key] = null;
|
|
58
|
-
}
|
|
59
|
-
const c = {};
|
|
80
|
+
function ProtoRow() {
|
|
81
|
+
columns.forEach(column => {
|
|
82
|
+
this[column.alias] = null;
|
|
83
|
+
});
|
|
60
84
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
c.visitOne = c.visitJoin;
|
|
65
|
-
c.visitMany = function(leg) {
|
|
66
|
-
obj[leg.name] = null;
|
|
67
|
-
};
|
|
85
|
+
for (const key in span.aggregates) {
|
|
86
|
+
this[key] = null;
|
|
87
|
+
}
|
|
68
88
|
|
|
69
|
-
|
|
89
|
+
const c = {
|
|
90
|
+
visitJoin: (leg) => {
|
|
91
|
+
this[leg.name] = null;
|
|
92
|
+
},
|
|
93
|
+
visitOne: (leg) => {
|
|
94
|
+
this[leg.name] = null;
|
|
95
|
+
},
|
|
96
|
+
visitMany: (leg) => {
|
|
97
|
+
this[leg.name] = null;
|
|
98
|
+
}
|
|
99
|
+
};
|
|
70
100
|
|
|
71
|
-
|
|
72
|
-
leg.accept(c);
|
|
101
|
+
span.legs.forEach(leg => leg.accept(c));
|
|
73
102
|
}
|
|
74
103
|
|
|
75
|
-
return
|
|
104
|
+
return ProtoRow;
|
|
76
105
|
}
|
|
77
106
|
|
|
107
|
+
|
|
78
108
|
function hasManyRelations(span) {
|
|
79
109
|
let result;
|
|
80
110
|
const c = {};
|
|
@@ -92,7 +122,7 @@ function hasManyRelations(span) {
|
|
|
92
122
|
}
|
|
93
123
|
}
|
|
94
124
|
|
|
95
|
-
async function decode(strategy, span, rows, keys = rows.length > 0 ? Object.keys(rows[0]) : []) {
|
|
125
|
+
async function decode(strategy, span, rows, keys = rows.length > 0 ? Object.keys(rows[0]) : [], parentRows, parentProp) {
|
|
96
126
|
const table = span.table;
|
|
97
127
|
let columnsMap = span.columns;
|
|
98
128
|
const columns = table._columns.filter(column => !columnsMap || columnsMap.get(column));
|
|
@@ -132,9 +162,11 @@ async function decode(strategy, span, rows, keys = rows.length > 0 ? Object.keys
|
|
|
132
162
|
}
|
|
133
163
|
|
|
134
164
|
outRows[i] = outRow;
|
|
165
|
+
if (parentRows)
|
|
166
|
+
parentRows[i][parentProp] = outRow;
|
|
135
167
|
if (shouldCreateMap) {
|
|
136
168
|
fkIds[i] = getIds(outRow);
|
|
137
|
-
addToMap(rowsMap,
|
|
169
|
+
addToMap(rowsMap, fkIds[i], outRow);
|
|
138
170
|
}
|
|
139
171
|
}
|
|
140
172
|
span._rowsMap = rowsMap;
|
|
@@ -185,18 +217,38 @@ async function decodeManyRelations(strategy, span) {
|
|
|
185
217
|
const name = leg.name;
|
|
186
218
|
const table = span.table;
|
|
187
219
|
const relation = table._relations[name];
|
|
188
|
-
const filter = createOneFilter(relation, span._ids);
|
|
189
220
|
const rowsMap = span._rowsMap;
|
|
221
|
+
|
|
222
|
+
const filter = createOneFilter(relation, span._ids);
|
|
223
|
+
const extractKey = createExtractKey(leg);
|
|
224
|
+
const extractFromMap = createExtractFromMap(rowsMap, table._primaryColumns);
|
|
190
225
|
const p = getManyDto(relation.childTable, filter, strategy[name], leg.span).then(subRows => {
|
|
191
226
|
for (let i = 0; i < subRows.length; i++) {
|
|
192
|
-
const key =
|
|
193
|
-
const parentRow =
|
|
227
|
+
const key = extractKey(subRows[i]);
|
|
228
|
+
const parentRow = extractFromMap(key);
|
|
194
229
|
parentRow[name].push(subRows[i]);
|
|
195
230
|
}
|
|
196
231
|
});
|
|
197
232
|
promises.push(p);
|
|
198
233
|
};
|
|
199
234
|
|
|
235
|
+
function createExtractKey(leg) {
|
|
236
|
+
if (leg.columns.length === 1) {
|
|
237
|
+
const alias = leg.columns[0].alias;
|
|
238
|
+
return (row) => row[alias];
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
const aliases = leg.columns.map(column => column.alias);
|
|
242
|
+
return (row) => aliases.map(alias => row[alias]);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
function createExtractFromMap(map, primaryColumns) {
|
|
246
|
+
if (primaryColumns.length === 1)
|
|
247
|
+
return (key) => map.get(key);
|
|
248
|
+
else
|
|
249
|
+
return getFromMap.bind(null, map, primaryColumns);
|
|
250
|
+
}
|
|
251
|
+
|
|
200
252
|
span.legs.forEach(onEachLeg);
|
|
201
253
|
|
|
202
254
|
function onEachLeg(leg) {
|
|
@@ -211,11 +263,7 @@ async function decodeRelations2(strategy, span, rawRows, resultRows, keys) {
|
|
|
211
263
|
const c = {};
|
|
212
264
|
c.visitJoin = function(leg) {
|
|
213
265
|
const name = leg.name;
|
|
214
|
-
const p = decode(strategy[name], leg.span, rawRows, keys
|
|
215
|
-
for (let i = 0; i < rows.length; i++) {
|
|
216
|
-
resultRows[i][name] = rows[i];
|
|
217
|
-
}
|
|
218
|
-
});
|
|
266
|
+
const p = decode(strategy[name], leg.span, rawRows, keys, resultRows, name);
|
|
219
267
|
promises.push(p);
|
|
220
268
|
};
|
|
221
269
|
|
|
@@ -233,47 +281,6 @@ async function decodeRelations2(strategy, span, rawRows, resultRows, keys) {
|
|
|
233
281
|
await Promise.all(promises);
|
|
234
282
|
}
|
|
235
283
|
|
|
236
|
-
|
|
237
|
-
// async function decodeRelations(strategy, span, rawRows, resultRows, keys) {
|
|
238
|
-
// const promises = [];
|
|
239
|
-
// const c = {};
|
|
240
|
-
// c.visitJoin = function (leg) {
|
|
241
|
-
// const name = leg.name;
|
|
242
|
-
// const p = decode(strategy[name], leg.span, rawRows, keys).then((rows) => {
|
|
243
|
-
// for (let i = 0; i < rows.length; i++) {
|
|
244
|
-
// resultRows[i][name] = rows[i];
|
|
245
|
-
// }
|
|
246
|
-
// });
|
|
247
|
-
// promises.push(p);
|
|
248
|
-
// };
|
|
249
|
-
|
|
250
|
-
// c.visitOne = c.visitJoin;
|
|
251
|
-
|
|
252
|
-
// c.visitMany = function (leg) {
|
|
253
|
-
// const name = leg.name;
|
|
254
|
-
// const table = span.table;
|
|
255
|
-
// const relation = table._relations[name];
|
|
256
|
-
// const filter = createOneFilter(relation, span._ids);
|
|
257
|
-
// const rowsMap = span._rowsMap;
|
|
258
|
-
// const p = getManyDto(relation.childTable, filter, strategy[name], leg.span).then(subRows => {
|
|
259
|
-
// for (let i = 0; i < subRows.length; i++) {
|
|
260
|
-
// const key = leg.columns.map(column => subRows[i][column.alias]);
|
|
261
|
-
// const parentRow = getFromMap(rowsMap, table._primaryColumns, key);
|
|
262
|
-
// parentRow[name].push(subRows[i]);
|
|
263
|
-
// }
|
|
264
|
-
// });
|
|
265
|
-
// promises.push(p);
|
|
266
|
-
// };
|
|
267
|
-
|
|
268
|
-
// span.legs.forEach(onEachLeg);
|
|
269
|
-
|
|
270
|
-
// function onEachLeg(leg) {
|
|
271
|
-
// leg.accept(c);
|
|
272
|
-
// }
|
|
273
|
-
|
|
274
|
-
// await Promise.all(promises);
|
|
275
|
-
// }
|
|
276
|
-
|
|
277
284
|
function createOneFilter(relation, ids) {
|
|
278
285
|
const columns = relation.joinRelation.columns;
|
|
279
286
|
|
|
@@ -299,28 +306,36 @@ function createOneFilter(relation, ids) {
|
|
|
299
306
|
}
|
|
300
307
|
}
|
|
301
308
|
|
|
302
|
-
function addToMap(map,
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
309
|
+
function addToMap(map, values, row) {
|
|
310
|
+
if (Array.isArray(values)) {
|
|
311
|
+
|
|
312
|
+
const lastIndex = values.length - 1;
|
|
313
|
+
for (let i = 0; i < lastIndex; i++) {
|
|
314
|
+
const id = values[i];
|
|
315
|
+
if (map.has(id))
|
|
316
|
+
map = map.get(id);
|
|
317
|
+
else {
|
|
318
|
+
const next = new Map();
|
|
319
|
+
map.set(id, next);
|
|
320
|
+
map = next;
|
|
321
|
+
}
|
|
313
322
|
}
|
|
323
|
+
map.set(values[lastIndex], row);
|
|
314
324
|
}
|
|
315
|
-
|
|
325
|
+
else
|
|
326
|
+
map.set(values, row);
|
|
316
327
|
}
|
|
317
328
|
|
|
318
329
|
function getFromMap(map, primaryColumns, values) {
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
330
|
+
if (Array.isArray(values)) {
|
|
331
|
+
const length = primaryColumns.length;
|
|
332
|
+
for (let i = 0; i < length; i++) {
|
|
333
|
+
map = map.get(values[i]);
|
|
334
|
+
}
|
|
335
|
+
return map;
|
|
322
336
|
}
|
|
323
|
-
|
|
337
|
+
else
|
|
338
|
+
return map.get(values);
|
|
324
339
|
}
|
|
325
340
|
|
|
326
341
|
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
const emptyFilter = require('./emptyFilter');
|
|
2
|
+
const newQuery = require('./getManyDto/newQuery');
|
|
3
|
+
const negotiateRawSqlFilter = require('./table/column/negotiateRawSqlFilter');
|
|
4
|
+
const strategyToSpan = require('./table/strategyToSpan');
|
|
5
|
+
const executeQueries = require('./table/executeQueries');
|
|
6
|
+
|
|
7
|
+
async function getManyDto(table, filter, strategy, spanFromParent) {
|
|
8
|
+
filter = negotiateRawSqlFilter(filter, table);
|
|
9
|
+
if (strategy && strategy.where) {
|
|
10
|
+
let arg = typeof strategy.where === 'function' ? strategy.where(table) : strategy.where;
|
|
11
|
+
filter = filter.and(arg);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
let span = spanFromParent || strategyToSpan(table, strategy);
|
|
15
|
+
let alias = table._dbName;
|
|
16
|
+
|
|
17
|
+
const query = newQuery(table, filter, span, alias);
|
|
18
|
+
const res = await executeQueries([query]);
|
|
19
|
+
return decode(strategy, span, await res[0]);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function newCreateRow(span) {
|
|
23
|
+
let columnsMap = span.columns;
|
|
24
|
+
const columns = span.table._columns.filter(column => !columnsMap || columnsMap.get(column));
|
|
25
|
+
const protoRow = createProto(columns, span);
|
|
26
|
+
const manyNames = [];
|
|
27
|
+
|
|
28
|
+
const c = {};
|
|
29
|
+
c.visitJoin = () => { };
|
|
30
|
+
c.visitOne = () => { };
|
|
31
|
+
c.visitMany = function (leg) {
|
|
32
|
+
manyNames.push(leg.name);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
span.legs.forEach(onEachLeg);
|
|
36
|
+
return createRow;
|
|
37
|
+
|
|
38
|
+
function onEachLeg(leg) {
|
|
39
|
+
leg.accept(c);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function createRow() {
|
|
43
|
+
const obj = Object.create(protoRow);
|
|
44
|
+
for (let i = 0; i < manyNames.length; i++) {
|
|
45
|
+
obj[manyNames[i]] = [];
|
|
46
|
+
}
|
|
47
|
+
return obj;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function createProto(columns, span) {
|
|
52
|
+
let obj = {};
|
|
53
|
+
for (let i = 0; i < columns.length; i++) {
|
|
54
|
+
obj[columns[i].alias] = null;
|
|
55
|
+
}
|
|
56
|
+
for (let key in span.aggregates) {
|
|
57
|
+
obj[key] = null;
|
|
58
|
+
}
|
|
59
|
+
const c = {};
|
|
60
|
+
|
|
61
|
+
c.visitJoin = function (leg) {
|
|
62
|
+
obj[leg.name] = null;
|
|
63
|
+
};
|
|
64
|
+
c.visitOne = c.visitJoin;
|
|
65
|
+
c.visitMany = function (leg) {
|
|
66
|
+
obj[leg.name] = null;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
span.legs.forEach(onEachLeg);
|
|
70
|
+
|
|
71
|
+
function onEachLeg(leg) {
|
|
72
|
+
leg.accept(c);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return obj;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function hasManyRelations(span) {
|
|
79
|
+
let result;
|
|
80
|
+
const c = {};
|
|
81
|
+
c.visitJoin = () => { };
|
|
82
|
+
c.visitOne = c.visitJoin;
|
|
83
|
+
c.visitMany = function () {
|
|
84
|
+
result = true;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
span.legs.forEach(onEachLeg);
|
|
88
|
+
return result;
|
|
89
|
+
|
|
90
|
+
function onEachLeg(leg) {
|
|
91
|
+
leg.accept(c);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
async function decode(strategy, span, rows, keys = rows.length > 0 ? Object.keys(rows[0]) : []) {
|
|
96
|
+
const table = span.table;
|
|
97
|
+
let columnsMap = span.columns;
|
|
98
|
+
const columns = table._columns.filter(column => !columnsMap || columnsMap.get(column));
|
|
99
|
+
const rowsLength = rows.length;
|
|
100
|
+
const columnsLength = columns.length;
|
|
101
|
+
const primaryColumns = table._primaryColumns;
|
|
102
|
+
const primaryColumnsLength = primaryColumns.length;
|
|
103
|
+
const rowsMap = new Map();
|
|
104
|
+
const fkIds = new Array(rows.length);
|
|
105
|
+
const getIds = createGetIds();
|
|
106
|
+
const aggregateKeys = Object.keys(span.aggregates);
|
|
107
|
+
|
|
108
|
+
const outRows = new Array(rowsLength);
|
|
109
|
+
const createRow = newCreateRow(span);
|
|
110
|
+
const shouldCreateMap = hasManyRelations(span);
|
|
111
|
+
const promises = [];
|
|
112
|
+
for (let i = 0; i < rowsLength; i++) {
|
|
113
|
+
const row = rows[i];
|
|
114
|
+
let outRow = createRow();
|
|
115
|
+
let pkWithNullCount = 0;
|
|
116
|
+
for (let j = 0; j < primaryColumnsLength; j++) {
|
|
117
|
+
if (row[keys[j]] === null)
|
|
118
|
+
pkWithNullCount++;
|
|
119
|
+
if (pkWithNullCount === primaryColumnsLength) {
|
|
120
|
+
outRow = null;
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
const column = columns[j];
|
|
124
|
+
outRow[column.alias] = column.decode(row[keys[j]]);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
outRows[i] = outRow;
|
|
128
|
+
if (outRow === null)
|
|
129
|
+
continue;
|
|
130
|
+
if (shouldCreateMap) {
|
|
131
|
+
fkIds[i] = getIds(outRow);
|
|
132
|
+
addToMap(rowsMap, primaryColumns, outRow);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Execute code inside start and stop in the next event loop and as a promise
|
|
136
|
+
promises.push(new Promise((resolve) => {
|
|
137
|
+
((currentRow, currentOutRow) => {
|
|
138
|
+
setTimeout(async () => {
|
|
139
|
+
for (let j = primaryColumnsLength; j < columnsLength; j++) {
|
|
140
|
+
const column = columns[j];
|
|
141
|
+
currentOutRow[column.alias] = column.decode(currentRow[keys[j]]);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
for (let j = 0; j < aggregateKeys.length; j++) {
|
|
145
|
+
const key = aggregateKeys[j];
|
|
146
|
+
const parse = span.aggregates[key].column?.decode || Number.parseFloat;
|
|
147
|
+
currentOutRow[key] = parse(currentRow[keys[j + columnsLength]]);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
resolve();
|
|
151
|
+
}, 0);
|
|
152
|
+
})(row, outRow);
|
|
153
|
+
}));
|
|
154
|
+
}
|
|
155
|
+
span._rowsMap = rowsMap;
|
|
156
|
+
span._ids = fkIds;
|
|
157
|
+
|
|
158
|
+
const many = decodeManyRelations(strategy, span);
|
|
159
|
+
|
|
160
|
+
const p = Promise.all(promises).then(() => {
|
|
161
|
+
keys.splice(0, columnsLength + aggregateKeys.length);
|
|
162
|
+
return decodeRelations(strategy, span, rows, outRows, keys)
|
|
163
|
+
});
|
|
164
|
+
await Promise.all([many, p]);
|
|
165
|
+
return outRows;
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
function createGetIds() {
|
|
169
|
+
const primaryColumns = table._primaryColumns;
|
|
170
|
+
const length = primaryColumns.length;
|
|
171
|
+
if (length === 1) {
|
|
172
|
+
const alias = table._primaryColumns[0].alias;
|
|
173
|
+
return (row) => row[alias];
|
|
174
|
+
}
|
|
175
|
+
else
|
|
176
|
+
return (row) => {
|
|
177
|
+
const result = new Array(length);
|
|
178
|
+
for (let i = 0; i < length; i++) {
|
|
179
|
+
result[i] = row[primaryColumns[i].alias];
|
|
180
|
+
}
|
|
181
|
+
return result;
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
async function decodeManyRelations(strategy, span) {
|
|
188
|
+
const promises = [];
|
|
189
|
+
const c = {};
|
|
190
|
+
c.visitJoin = () => { };
|
|
191
|
+
c.visitOne = c.visitJoin;
|
|
192
|
+
|
|
193
|
+
c.visitMany = function (leg) {
|
|
194
|
+
const name = leg.name;
|
|
195
|
+
const table = span.table;
|
|
196
|
+
const relation = table._relations[name];
|
|
197
|
+
const filter = createOneFilter(relation, span._ids);
|
|
198
|
+
const rowsMap = span._rowsMap;
|
|
199
|
+
const p = getManyDto(relation.childTable, filter, strategy[name], leg.span).then(subRows => {
|
|
200
|
+
for (let i = 0; i < subRows.length; i++) {
|
|
201
|
+
const key = leg.columns.map(column => subRows[i][column.alias]);
|
|
202
|
+
const parentRow = getFromMap(rowsMap, table._primaryColumns, key);
|
|
203
|
+
parentRow[name].push(subRows[i]);
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
promises.push(p);
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
span.legs.forEach(onEachLeg);
|
|
210
|
+
|
|
211
|
+
function onEachLeg(leg) {
|
|
212
|
+
leg.accept(c);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
await Promise.all(promises);
|
|
216
|
+
}
|
|
217
|
+
async function decodeRelations(strategy, span, rawRows, resultRows, keys) {
|
|
218
|
+
const promises = [];
|
|
219
|
+
const c = {};
|
|
220
|
+
c.visitJoin = function (leg) {
|
|
221
|
+
const name = leg.name;
|
|
222
|
+
const p = decode(strategy[name], leg.span, rawRows, keys).then((rows) => {
|
|
223
|
+
for (let i = 0; i < rows.length; i++) {
|
|
224
|
+
resultRows[i][name] = rows[i];
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
promises.push(p);
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
c.visitOne = c.visitJoin;
|
|
231
|
+
|
|
232
|
+
c.visitMany = () => { };
|
|
233
|
+
|
|
234
|
+
span.legs.forEach(onEachLeg);
|
|
235
|
+
|
|
236
|
+
function onEachLeg(leg) {
|
|
237
|
+
leg.accept(c);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
await Promise.all(promises);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
function createOneFilter(relation, ids) {
|
|
244
|
+
const columns = relation.joinRelation.columns;
|
|
245
|
+
|
|
246
|
+
if (columns.length === 1)
|
|
247
|
+
return columns[0].in(ids);
|
|
248
|
+
|
|
249
|
+
else
|
|
250
|
+
return createCompositeFilter();
|
|
251
|
+
|
|
252
|
+
function createCompositeFilter() {
|
|
253
|
+
let filter = emptyFilter;
|
|
254
|
+
for (let id of ids) {
|
|
255
|
+
let nextFilter;
|
|
256
|
+
for (let i = 0; i < columns.length; i++) {
|
|
257
|
+
if (nextFilter)
|
|
258
|
+
nextFilter = nextFilter.and(columns[i].eq(id[i]));
|
|
259
|
+
else
|
|
260
|
+
nextFilter = columns[i].eq(id[i]);
|
|
261
|
+
}
|
|
262
|
+
filter = filter.or(nextFilter);
|
|
263
|
+
}
|
|
264
|
+
return filter;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
function addToMap(map, primaryColumns, row) {
|
|
269
|
+
|
|
270
|
+
const lastIndex = primaryColumns.length - 1;
|
|
271
|
+
for (let i = 0; i < lastIndex; i++) {
|
|
272
|
+
const id = row[primaryColumns[i].alias];
|
|
273
|
+
if (map.has(id))
|
|
274
|
+
map = map.get(id);
|
|
275
|
+
else {
|
|
276
|
+
const next = new Map();
|
|
277
|
+
map.set(id, next);
|
|
278
|
+
map = next;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
map.set(row[primaryColumns[lastIndex].alias], row);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
function getFromMap(map, primaryColumns, values) {
|
|
285
|
+
const length = primaryColumns.length;
|
|
286
|
+
for (let i = 0; i < length; i++) {
|
|
287
|
+
map = map.get(values[i]);
|
|
288
|
+
}
|
|
289
|
+
return map;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
module.exports = getManyDto;
|