* The function takes the result of the query execution and groups * the associated data by the callee. * * Example: * groupJoinData([ * { * some: 'data', * id: 1, * association: { foo: 'bar', id: 1 } * }, { * some: 'data', * id
(rows, includeOptions, options)
| 426 | * @private |
| 427 | */ |
| 428 | static _groupJoinData(rows, includeOptions, options) { |
| 429 | |
| 430 | /* |
| 431 | * Assumptions |
| 432 | * ID is not necessarily the first field |
| 433 | * All fields for a level is grouped in the same set (i.e. Panel.id, Task.id, Panel.title is not possible) |
| 434 | * Parent keys will be seen before any include/child keys |
| 435 | * Previous set won't necessarily be parent set (one parent could have two children, one child would then be previous set for the other) |
| 436 | */ |
| 437 | |
| 438 | /* |
| 439 | * Author (MH) comment: This code is an unreadable mess, but it's performant. |
| 440 | * groupJoinData is a performance critical function so we prioritize perf over readability. |
| 441 | */ |
| 442 | if (!rows.length) { |
| 443 | return []; |
| 444 | } |
| 445 | |
| 446 | // Generic looping |
| 447 | let i; |
| 448 | let length; |
| 449 | let $i; |
| 450 | let $length; |
| 451 | // Row specific looping |
| 452 | let rowsI; |
| 453 | let row; |
| 454 | const rowsLength = rows.length; |
| 455 | // Key specific looping |
| 456 | let keys; |
| 457 | let key; |
| 458 | let keyI; |
| 459 | let keyLength; |
| 460 | let prevKey; |
| 461 | let values; |
| 462 | let topValues; |
| 463 | let topExists; |
| 464 | const checkExisting = options.checkExisting; |
| 465 | // If we don't have to deduplicate we can pre-allocate the resulting array |
| 466 | let itemHash; |
| 467 | let parentHash; |
| 468 | let topHash; |
| 469 | const results = checkExisting ? [] : new Array(rowsLength); |
| 470 | const resultMap = {}; |
| 471 | const includeMap = {}; |
| 472 | // Result variables for the respective functions |
| 473 | let $keyPrefix; |
| 474 | let $keyPrefixString; |
| 475 | let $prevKeyPrefixString; // eslint-disable-line |
| 476 | let $prevKeyPrefix; |
| 477 | let $lastKeyPrefix; |
| 478 | let $current; |
| 479 | let $parent; |
| 480 | // Map each key to an include option |
| 481 | let previousPiece; |
| 482 | const buildIncludeMap = piece => { |
| 483 | if (Object.prototype.hasOwnProperty.call($current.includeMap, piece)) { |
| 484 | includeMap[key] = $current = $current.includeMap[piece]; |
| 485 | if (previousPiece) { |
no test coverage detected