orange-orm 4.3.0-beta.3 → 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.
@@ -0,0 +1,588 @@
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
+ for (let i = 0; i < rowsLength; i++) {
112
+ const row = rows[i];
113
+ let outRow = createRow();
114
+ let pkWithNullCount = 0;
115
+ for (let j = 0; j < columnsLength; j++) {
116
+ if (j < primaryColumnsLength) {
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
+ // fkId = outRow[column.alias];
126
+ }
127
+ else {
128
+ const column = columns[j];
129
+ outRow[column.alias] = column.decode(row[keys[j]]);
130
+ }
131
+ // const column = columns[j];
132
+ // outRow[column.alias] = column.decode(row[keys[j]]);
133
+
134
+ }
135
+
136
+ for (let j = 0; j < aggregateKeys.length; j++) {
137
+ const key = aggregateKeys[j];
138
+ const parse = span.aggregates[key].column?.decode || Number.parseFloat;
139
+ outRow[key] = parse(row[keys[j + columnsLength]]);
140
+ }
141
+
142
+ outRows[i] = outRow;
143
+ if (shouldCreateMap && outRow) {
144
+ // fkIds[i] = fkId;
145
+ fkIds[i] = getIds(outRow);
146
+ // console.dir(fkIds[i]);
147
+ addToMap(rowsMap, primaryColumns, outRow);
148
+ }
149
+ }
150
+ span._rowsMap = rowsMap;
151
+ span._ids = fkIds;
152
+
153
+ keys.splice(0, columnsLength + aggregateKeys.length);
154
+ if (span.legs.toArray().length === 0)
155
+ return outRows;
156
+
157
+ //alt 1
158
+ // 3.1 sec
159
+ // await new Promise((resolve, reject) => {
160
+ // setTimeout(() => {
161
+ // if (shouldCreateMap)
162
+ // decodeManyRelations(strategy, span, rows, outRows, keys)
163
+ // .then(() => decodeRelations2(strategy, span, rows, outRows, keys))
164
+ // .then(resolve)
165
+ // .catch(reject);
166
+ // else
167
+ // decodeRelations2(strategy, span, rows, outRows, keys)
168
+ // .then(resolve)
169
+ // .catch(reject);
170
+ // }, 0);
171
+ // });
172
+
173
+
174
+ //alt 1
175
+ // 3.2 sec
176
+ // await new Promise((resolve, reject) => {
177
+ // setTimeout(() => {
178
+ // const all = [];
179
+ // if (shouldCreateMap)
180
+ // all.push(decodeManyRelations(strategy, span, rows, outRows, keys))
181
+
182
+ // all.push(new Promise((resolve, reject) => {
183
+ // setTimeout(async () => {
184
+ // await decodeRelations2(strategy, span, rows, outRows, keys);
185
+ // resolve();
186
+
187
+ // }, 0);
188
+ // }));
189
+ // // const p2 = decodeRelations2(strategy, span, rows, outRows, keys);
190
+ // Promise.all(all).then(resolve, reject);
191
+ // }, 0);
192
+ // });
193
+
194
+
195
+ // let all = [];;
196
+ // if(shouldCreateMap) {
197
+
198
+ // await decodeManyRelations(strategy, span, rows, outRows, keys).then(() => decodeRelations2(strategy, span, rows, outRows, keys));
199
+ // }
200
+ // else
201
+ // await decodeRelations2(strategy, span, rows, outRows, keys);
202
+
203
+ // await Promise.all(all);
204
+
205
+
206
+
207
+ //alt 3
208
+ // 3.05 sec
209
+ let all = [];;
210
+
211
+ if(shouldCreateMap) {
212
+ // all.push( decodeRelations2(strategy, span, rows, outRows, keys).then(() => decodeManyRelations(strategy, span)));
213
+ all.push( decodeManyRelations(strategy, span));
214
+ all.push(decodeRelations2(strategy, span, rows, outRows, keys));
215
+ // all.push( decodeManyRelations(strategy, span).then(() => decodeRelations2(strategy, span, rows, outRows, keys)));
216
+ // all.push( decodeManyRelations(strategy, span));
217
+ // all.push(decodeRelations2(strategy, span, rows, outRows, keys));
218
+ // all.push( decodeRelations2(strategy, span, rows, outRows, keys) );
219
+ }
220
+ else
221
+ all.push( decodeRelations2(strategy, span, rows, outRows, keys) );
222
+
223
+ await Promise.all(all);
224
+
225
+ //alt 4
226
+ // 3.02 sec
227
+ // const all = [];
228
+ // if (shouldCreateMap)
229
+ // // all.push(new Promise((resolve, reject) => {
230
+ // // setTimeout(async () => {
231
+ // // await decodeManyRelations(strategy, span);
232
+ // // resolve();
233
+
234
+ // // }, 0)
235
+ // // }));
236
+ // all.push(decodeManyRelations(strategy, span));
237
+ // all.push(new Promise((resolve, reject) => {
238
+ // setTimeout(async () => {
239
+ // await decodeRelations2(strategy, span, rows, outRows, keys);
240
+ // resolve();
241
+
242
+ // }, 0);
243
+ // }));
244
+ // await Promise.all(all);
245
+
246
+ // all.push(decodeRelations2(strategy, span, rows, outRows, keys));
247
+
248
+ //alt 4
249
+ // 3.3 sec
250
+ // if(shouldCreateMap)
251
+ // await decodeRelations(strategy, span, rows, outRows, keys);
252
+ // else
253
+ // await decodeRelations2(strategy, span, rows, outRows, keys);
254
+
255
+ // await decodeRelationsNext(strategy, span, rows, outRows, keys);
256
+ // await decodeRelations(strategy, span, rows, outRows, keys);
257
+
258
+ return outRows;
259
+
260
+
261
+ function createGetIds() {
262
+ const primaryColumns = table._primaryColumns;
263
+ const length = primaryColumns.length;
264
+ if (length === 1) {
265
+ const alias = table._primaryColumns[0].alias;
266
+ return (row) => row[alias];
267
+ }
268
+ else
269
+ return (row) => {
270
+ const result = new Array(length);
271
+ for (let i = 0; i < length; i++) {
272
+ result[i] = row[primaryColumns[i].alias];
273
+ }
274
+ return result;
275
+ };
276
+ }
277
+
278
+ }
279
+ async function decodeRelations2(strategy, span, rawRows, resultRows, keys) {
280
+ const legs = span.legs.toArray();
281
+ if (legs.length === 0)
282
+ return;
283
+ const promises = [];
284
+ const c = {};
285
+ c.visitJoin = function (leg) {
286
+ const name = leg.name;
287
+ const p = decode(strategy[name], leg.span, rawRows, keys).then((rows) => {
288
+ for (let i = 0; i < rows.length; i++) {
289
+ resultRows[i][name] = rows[i];
290
+ }
291
+ });
292
+ promises.push(p);
293
+ };
294
+
295
+ c.visitOne = c.visitJoin;
296
+
297
+ c.visitMany = () => { };
298
+
299
+ function processLegs(index) {
300
+ if (index >= legs.length) {
301
+ return;
302
+ }
303
+ const leg = legs[index];
304
+ leg.accept(c);
305
+ Promise.all(promises).then(() => {
306
+ setImmediate(() => {
307
+ processLegs(index + 1);
308
+ });
309
+ });
310
+ }
311
+
312
+ processLegs(0);
313
+
314
+ await Promise.all(promises);
315
+ }
316
+
317
+ async function decodeRelations3(strategy, span, rawRows, resultRows, keys) {
318
+ const promises = [];
319
+ const c = {};
320
+ c.visitJoin = function (leg) {
321
+ const name = leg.name;
322
+ const p = decode(strategy[name], leg.span, rawRows, keys).then((rows) => {
323
+ for (let i = 0; i < rows.length; i++) {
324
+ resultRows[i][name] = rows[i];
325
+ }
326
+ });
327
+ promises.push(p);
328
+ };
329
+
330
+ c.visitOne = c.visitJoin;
331
+
332
+ c.visitMany = () => { };
333
+
334
+
335
+ span.legs.forEach(onEachLeg);
336
+
337
+ function onEachLeg(leg) {
338
+ leg.accept(c);
339
+ }
340
+
341
+ await Promise.all(promises);
342
+ }
343
+
344
+
345
+ async function decodeManyRelations(strategy, span, rawRows, resultRows, keys) {
346
+ const promises = [];
347
+ const c = {};
348
+ c.visitJoin = () => { };
349
+ c.visitOne = c.visitJoin;
350
+
351
+ c.visitMany = function (leg) {
352
+ const name = leg.name;
353
+ const table = span.table;
354
+ const relation = table._relations[name];
355
+ const filter = createOneFilter(relation, span._ids);
356
+ const rowsMap = span._rowsMap;
357
+ const p = getManyDto(relation.childTable, filter, strategy[name], leg.span).then(subRows => {
358
+ for (let i = 0; i < subRows.length; i++) {
359
+ const key = leg.columns.map(column => subRows[i][column.alias]);
360
+ const parentRow = getFromMap(rowsMap, table._primaryColumns, key);
361
+ parentRow[name].push(subRows[i]);
362
+ }
363
+ });
364
+ promises.push(p);
365
+ };
366
+
367
+ span.legs.forEach(onEachLeg);
368
+
369
+ function onEachLeg(leg) {
370
+ leg.accept(c);
371
+ }
372
+
373
+ // await Promise.all(promises);
374
+ // }
375
+
376
+ // async function decodeRelations2(strategy, span, rawRows, resultRows, keys) {
377
+ // const promises = [];
378
+ // const c = {};
379
+ // c.visitJoin = function (leg) {
380
+ // const name = leg.name;
381
+ // //todo avoid traverse twice noMany relations below
382
+ // const p = decode(strategy[name], leg.span, rawRows, keys).then((rows) => {
383
+ // for (let i = 0; i < rows.length; i++) {
384
+ // resultRows[i][name] = rows[i];
385
+ // }
386
+ // });
387
+ // promises.push(p);
388
+ // };
389
+
390
+ // c.visitOne = c.visitJoin;
391
+
392
+ // c.visitMany = () => { };
393
+
394
+ // span.legs.forEach(onEachLeg);
395
+
396
+ // function onEachLeg(leg) {
397
+ // leg.accept(c);
398
+ // }
399
+
400
+ await Promise.all(promises);
401
+ }
402
+
403
+ async function decodeRelations3(strategy, span, rawRows, resultRows, keys) {
404
+
405
+ let previous = new Promise((resolve) => setImmediate(() => resolve()));
406
+ const c = {};
407
+
408
+ c.visitJoin = function (leg) {
409
+ const name = leg.name;
410
+ const p = new Promise((resolve) => {
411
+ setImmediate(() => {
412
+ decode(strategy[name], leg.span, rawRows, keys).then((rows) => {
413
+ for (let i = 0; i < rows.length; i++) {
414
+ resultRows[i][name] = rows[i];
415
+ }
416
+ resolve();
417
+ });
418
+ });
419
+ });
420
+ previous = previous.then(() => p);
421
+ };
422
+
423
+ c.visitOne = c.visitJoin;
424
+
425
+ c.visitMany = () => { };
426
+
427
+ span.legs.forEach(onEachLeg);
428
+
429
+ function onEachLeg(leg) {
430
+ leg.accept(c);
431
+ }
432
+
433
+ await previous;
434
+
435
+ }
436
+
437
+
438
+ async function decodeRelationsNext(strategy, span, rawRows, resultRows, keys) {
439
+ // const promises = [];
440
+ let previous = new Promise((resolve) => setImmediate(() => resolve()));
441
+ const c = {};
442
+
443
+ c.visitJoin = function (leg) {
444
+ const name = leg.name;
445
+ const p = new Promise((resolve) => {
446
+ setImmediate(() => {
447
+ decode(strategy[name], leg.span, rawRows, keys).then((rows) => {
448
+ for (let i = 0; i < rows.length; i++) {
449
+ resultRows[i][name] = rows[i];
450
+ }
451
+ resolve();
452
+ });
453
+ });
454
+ });
455
+ previous = previous.then(() => p);
456
+ };
457
+
458
+ c.visitOne = c.visitJoin;
459
+
460
+ c.visitMany = function (leg) {
461
+ const p = new Promise((resolve, reject) => {
462
+ setImmediate(() => {
463
+
464
+ const name = leg.name;
465
+ const table = span.table;
466
+ const relation = table._relations[name];
467
+ const filter = createOneFilter(relation, span._ids);
468
+ const rowsMap = span._rowsMap;
469
+
470
+ getManyDto(relation.childTable, filter, strategy[name], leg.span).then(subRows => {
471
+ for (let i = 0; i < subRows.length; i++) {
472
+ const key = leg.columns.map(column => subRows[i][column.alias]);
473
+ const parentRow = getFromMap(rowsMap, table._primaryColumns, key);
474
+ parentRow[name].push(subRows[i]);
475
+ }
476
+ }).then(() => resolve(), reject);
477
+
478
+
479
+ });
480
+ });
481
+
482
+
483
+ previous = previous.then(() => p);
484
+ // promises.push(p);
485
+ };
486
+
487
+ span.legs.forEach(onEachLeg);
488
+
489
+ function onEachLeg(leg) {
490
+ leg.accept(c);
491
+ }
492
+
493
+ await previous
494
+ }
495
+
496
+
497
+ async function decodeRelations(strategy, span, rawRows, resultRows, keys) {
498
+ const promises = [];
499
+ const c = {};
500
+ c.visitJoin = function (leg) {
501
+ const name = leg.name;
502
+ const p = decode(strategy[name], leg.span, rawRows, keys).then((rows) => {
503
+ for (let i = 0; i < rows.length; i++) {
504
+ resultRows[i][name] = rows[i];
505
+ }
506
+ });
507
+ promises.push(p);
508
+ };
509
+
510
+ c.visitOne = c.visitJoin;
511
+
512
+ c.visitMany = function (leg) {
513
+ const name = leg.name;
514
+ const table = span.table;
515
+ const relation = table._relations[name];
516
+ const filter = createOneFilter(relation, span._ids);
517
+ const rowsMap = span._rowsMap;
518
+ const p = getManyDto(relation.childTable, filter, strategy[name], leg.span).then(subRows => {
519
+ for (let i = 0; i < subRows.length; i++) {
520
+ const key = leg.columns.map(column => subRows[i][column.alias]);
521
+ const parentRow = getFromMap(rowsMap, table._primaryColumns, key);
522
+ parentRow[name].push(subRows[i]);
523
+ }
524
+ });
525
+ promises.push(p);
526
+ };
527
+
528
+
529
+ span.legs.forEach(onEachLeg);
530
+
531
+ function onEachLeg(leg) {
532
+ leg.accept(c);
533
+ }
534
+
535
+ await Promise.all(promises);
536
+ }
537
+
538
+ function createOneFilter(relation, ids) {
539
+ const columns = relation.joinRelation.columns;
540
+
541
+ if (columns.length === 1)
542
+ return columns[0].in(ids);
543
+
544
+ else
545
+ return createCompositeFilter();
546
+
547
+ function createCompositeFilter() {
548
+ let filter = emptyFilter;
549
+ for (let id of ids) {
550
+ let nextFilter;
551
+ for (let i = 0; i < columns.length; i++) {
552
+ if (nextFilter)
553
+ nextFilter = nextFilter.and(columns[i].eq(id[i]));
554
+ else
555
+ nextFilter = columns[i].eq(id[i]);
556
+ }
557
+ filter = filter.or(nextFilter);
558
+ }
559
+ return filter;
560
+ }
561
+ }
562
+
563
+ function addToMap(map, primaryColumns, row) {
564
+
565
+ const lastIndex = primaryColumns.length - 1;
566
+ for (let i = 0; i < lastIndex; i++) {
567
+ const id = row[primaryColumns[i].alias];
568
+ if (map.has(id))
569
+ map = map.get(id);
570
+ else {
571
+ const next = new Map();
572
+ map.set(id, next);
573
+ map = next;
574
+ }
575
+ }
576
+ map.set(row[primaryColumns[lastIndex].alias], row);
577
+ }
578
+
579
+ function getFromMap(map, primaryColumns, values) {
580
+ const length = primaryColumns.length;
581
+ for (let i = 0; i < length; i++) {
582
+ map = map.get(values[i]);
583
+ }
584
+ return map;
585
+ }
586
+
587
+
588
+ module.exports = getManyDto;
@@ -17,6 +17,13 @@ function _new(_column) {
17
17
  return Buffer.from(value, 'base64');
18
18
  };
19
19
 
20
+ encode.direct = function(value) {
21
+ value = purify(value);
22
+ if (value === null)
23
+ return null;
24
+ return Buffer.from(value, 'base64');
25
+ };
26
+
20
27
  return encode;
21
28
  }
22
29
 
@@ -30,6 +30,18 @@ function _new(column) {
30
30
  return encodeCore(value);
31
31
  };
32
32
 
33
+ encode.direct = function(value) {
34
+ value = purify(value);
35
+ if (value === null) {
36
+ if (column.dbNull === null)
37
+ return null;
38
+ return column.dbNull ;
39
+ }
40
+ var encodeCore = getSessionSingleton('encodeBoolean');
41
+
42
+ return encodeCore(value);
43
+ };
44
+
33
45
  return encode;
34
46
  }
35
47
 
@@ -21,8 +21,19 @@ function _new(column) {
21
21
  value = purify(value);
22
22
  if (value == null) {
23
23
  if (column.dbNull === null)
24
- return newPara('null');
25
- return newPara('\'' + column.dbNull + '\'');
24
+ 'null';
25
+ return '\'' + column.dbNull + '\'';
26
+ }
27
+ var encodeCore = getSessionSingleton('encodeDate') || encodeDate;
28
+ return encodeCore(value);
29
+ };
30
+
31
+ encode.direct = function(value) {
32
+ value = purify(value);
33
+ if (value == null) {
34
+ if (column.dbNull === null)
35
+ null;
36
+ return column.dbNull;
26
37
  }
27
38
  var encodeCore = getSessionSingleton('encodeDate') || encodeDate;
28
39
  return encodeCore(value);
@@ -23,6 +23,16 @@ function _new(column) {
23
23
  return encodeDate(value);
24
24
  };
25
25
 
26
+ encode.direct = function(value) {
27
+ value = purify(value);
28
+ if (value == null) {
29
+ if (column.dbNull === null)
30
+ return null;
31
+ return column.dbNull;
32
+ }
33
+ return encodeDate(value);
34
+ };
35
+
26
36
  return encode;
27
37
 
28
38
 
@@ -23,6 +23,16 @@ function _new(column) {
23
23
  return '\'' + value + '\'';
24
24
  };
25
25
 
26
+ encode.direct = function(candidate) {
27
+ var value = purify(candidate);
28
+ if (value == null) {
29
+ if (column.dbNull === null)
30
+ return null;
31
+ return column.dbNull;
32
+ }
33
+ return value ;
34
+ };
35
+
26
36
 
27
37
  return encode;
28
38
  }
@@ -1,25 +1,22 @@
1
- var newParameterized = require('../query/newParameterized');
2
- var newBoolean = require('./newBoolean');
3
- var encodeFilterArg = require('./encodeFilterArg');
4
- var quote = require('../quote');
1
+ const newParameterized = require('../query/newParameterized');
2
+ const newBoolean = require('./newBoolean');
3
+ const quote = require('../quote');
5
4
 
6
5
  function _in(column,values,alias) {
7
- var filter;
6
+ let filter;
8
7
  if (values.length === 0) {
9
8
  filter = newParameterized('1=2');
10
9
  return newBoolean(filter);
11
10
  }
12
- var firstPart = quote(alias) + '.' + quote(column._dbName) + ' in ';
13
- var parameterized = newParameterized(firstPart);
14
- var separator = '(';
11
+ const firstPart = `${quote(alias)}.${quote(column._dbName)} in (`;
15
12
 
16
- for (var i = 0; i < values.length; i++) {
17
- var encoded = encodeFilterArg(column, values[i]);
18
- parameterized = parameterized.append(separator).append(encoded);
19
- separator = ',';
13
+ const encode = column.encode.direct;
14
+ const params = new Array(values.length);
15
+ for (let i = 0; i < values.length; i++) {
16
+ params[i] = encode(values[i]);
20
17
  }
21
- filter = parameterized.append(')');
22
- return newBoolean(filter);
18
+ const sql = `${firstPart + new Array(values.length).fill('?').join(',')})`;
19
+ return newBoolean(newParameterized(sql, params));
23
20
  }
24
21
 
25
22
  module.exports = _in;