* 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)
| 402 | * @private |
| 403 | */ |
| 404 | static _groupJoinData(rows, includeOptions, options) { |
| 405 | |
| 406 | /* |
| 407 | * Assumptions |
| 408 | * ID is not necessarily the first field |
| 409 | * All fields for a level is grouped in the same set (i.e. Panel.id, Task.id, Panel.title is not possible) |
| 410 | * Parent keys will be seen before any include/child keys |
| 411 | * Previous set won't necessarily be parent set (one parent could have two children, one child would then be previous set for the other) |
| 412 | */ |
| 413 | |
| 414 | /* |
| 415 | * Author (MH) comment: This code is an unreadable mess, but it's performant. |
| 416 | * groupJoinData is a performance critical function so we prioritize perf over readability. |
| 417 | */ |
| 418 | if (!rows.length) { |
| 419 | return []; |
| 420 | } |
| 421 | |
| 422 | // Generic looping |
| 423 | let i; |
| 424 | let length; |
| 425 | let $i; |
| 426 | let $length; |
| 427 | // Row specific looping |
| 428 | let rowsI; |
| 429 | let row; |
| 430 | const rowsLength = rows.length; |
| 431 | // Key specific looping |
| 432 | let keys; |
| 433 | let key; |
| 434 | let keyI; |
| 435 | let keyLength; |
| 436 | let prevKey; |
| 437 | let values; |
| 438 | let topValues; |
| 439 | let topExists; |
| 440 | const checkExisting = options.checkExisting; |
| 441 | // If we don't have to deduplicate we can pre-allocate the resulting array |
| 442 | let itemHash; |
| 443 | let parentHash; |
| 444 | let topHash; |
| 445 | const results = checkExisting ? [] : new Array(rowsLength); |
| 446 | const resultMap = {}; |
| 447 | const includeMap = {}; |
| 448 | // Result variables for the respective functions |
| 449 | let $keyPrefix; |
| 450 | let $keyPrefixString; |
| 451 | let $prevKeyPrefixString; // eslint-disable-line |
| 452 | let $prevKeyPrefix; |
| 453 | let $lastKeyPrefix; |
| 454 | let $current; |
| 455 | let $parent; |
| 456 | // Map each key to an include option |
| 457 | let previousPiece; |
| 458 | const buildIncludeMap = piece => { |
| 459 | if (Object.prototype.hasOwnProperty.call($current.includeMap, piece)) { |
| 460 | includeMap[key] = $current = $current.includeMap[piece]; |
| 461 | if (previousPiece) { |
no test coverage detected