@igojs/db 6.0.0-beta.4 → 6.0.0-beta.6
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/package.json +5 -5
- package/src/Db.js +3 -2
- package/src/PaginatedOptimizedQuery.js +58 -2
- package/src/migrations.js +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@igojs/db",
|
|
3
|
-
"version": "6.0.0-beta.
|
|
3
|
+
"version": "6.0.0-beta.6",
|
|
4
4
|
"description": "Igo ORM - Database abstraction layer for MySQL and PostgreSQL",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -17,16 +17,16 @@
|
|
|
17
17
|
"homepage": "https://github.com/igocreate/igo",
|
|
18
18
|
"repository": {
|
|
19
19
|
"type": "git",
|
|
20
|
-
"url": "git@github.com
|
|
20
|
+
"url": "git+ssh://git@github.com/igocreate/igo.git"
|
|
21
21
|
},
|
|
22
22
|
"publishConfig": {
|
|
23
23
|
"access": "public"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"lodash": "^4.17.
|
|
26
|
+
"lodash": "^4.17.23"
|
|
27
27
|
},
|
|
28
28
|
"optionalDependencies": {
|
|
29
|
-
"mysql2": "^3.16.
|
|
30
|
-
"pg": "^8.
|
|
29
|
+
"mysql2": "^3.16.3",
|
|
30
|
+
"pg": "^8.18.0"
|
|
31
31
|
}
|
|
32
32
|
}
|
package/src/Db.js
CHANGED
|
@@ -379,8 +379,9 @@ module.exports = class PaginatedOptimizedQuery extends Query {
|
|
|
379
379
|
// Retourner un tableau d'IDs (ou objets de clés composites)
|
|
380
380
|
if (primaryKeys.length === 1) {
|
|
381
381
|
return rows.map(row => row[primaryKeys[0]]);
|
|
382
|
+
} else {
|
|
383
|
+
return rows.map(row => _.pick(row, primaryKeys));
|
|
382
384
|
}
|
|
383
|
-
return rows.map(row => _.pick(row, primaryKeys));
|
|
384
385
|
}
|
|
385
386
|
|
|
386
387
|
/**
|
|
@@ -434,7 +435,62 @@ module.exports = class PaginatedOptimizedQuery extends Query {
|
|
|
434
435
|
}
|
|
435
436
|
|
|
436
437
|
const rows = await fullQuery.execute();
|
|
437
|
-
|
|
438
|
+
|
|
439
|
+
// Dédupliquer les résultats si nécessaire
|
|
440
|
+
// Les LEFT JOIN 1-N (comme beneficiary.folder_id = folders.id) créent des doublons
|
|
441
|
+
// qu'on doit éliminer manuellement en gardant la première occurrence de chaque ID
|
|
442
|
+
const uniqueRows = this._deduplicateRows(rows, ids.length);
|
|
443
|
+
|
|
444
|
+
return uniqueRows;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* Déduplique les lignes retournées par SELECT FULL en gardant la première occurrence de chaque ID
|
|
449
|
+
*
|
|
450
|
+
* Cette méthode est nécessaire car les LEFT JOIN 1-N (ex: beneficiary.folder_id = folders.id)
|
|
451
|
+
* créent plusieurs lignes pour le même objet principal. On garde uniquement la première occurrence.
|
|
452
|
+
*
|
|
453
|
+
* @param {Array} rows - Lignes retournées par SELECT FULL
|
|
454
|
+
* @param {number} expectedCount - Nombre d'IDs attendus (pour logging)
|
|
455
|
+
* @returns {Array} Lignes dédupliquées
|
|
456
|
+
*/
|
|
457
|
+
_deduplicateRows(rows, expectedCount) {
|
|
458
|
+
if (!rows || rows.length === 0) {
|
|
459
|
+
return rows;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
// Si le nombre de lignes correspond au nombre d'IDs, pas de doublons
|
|
463
|
+
if (rows.length === expectedCount) {
|
|
464
|
+
return rows;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
const primaryKeys = this.schema.primary || ['id'];
|
|
468
|
+
const seenIds = new Set();
|
|
469
|
+
const uniqueRows = [];
|
|
470
|
+
|
|
471
|
+
for (const row of rows) {
|
|
472
|
+
// Construire la clé composite si nécessaire
|
|
473
|
+
let key;
|
|
474
|
+
if (primaryKeys.length === 1) {
|
|
475
|
+
key = row[primaryKeys[0]];
|
|
476
|
+
} else {
|
|
477
|
+
key = primaryKeys.map(k => row[k]).join('|');
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
// Garder seulement la première occurrence de chaque ID
|
|
481
|
+
if (!seenIds.has(key)) {
|
|
482
|
+
seenIds.add(key);
|
|
483
|
+
uniqueRows.push(row);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
// Logger si des doublons ont été éliminés (uniquement en cas de doublons)
|
|
488
|
+
const duplicatesRemoved = rows.length - uniqueRows.length;
|
|
489
|
+
if (duplicatesRemoved > 0) {
|
|
490
|
+
logger.info(`[PaginatedOptimizedQuery] ${duplicatesRemoved} duplicate(s) removed by LEFT JOIN 1-N deduplication`);
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
return uniqueRows;
|
|
438
494
|
}
|
|
439
495
|
|
|
440
496
|
/**
|