Fix dedup migration: 3 bulk SQL queries instead of per-dupe loop
Was: for loop with 3 IPC calls per duplicate group = thousands of round-trips = 10+ minutes on phone. Now: 3 bulk UPDATE/DELETE statements that run in SQLite directly. One-time migration, subsequent launches skip (COUNT=0).
This commit is contained in:
parent
0136b8ae0e
commit
d365554a7b
1 changed files with 15 additions and 14 deletions
|
|
@ -1141,21 +1141,22 @@ async function runMigrations() {
|
|||
await addSuppCol("omega6_mg", "REAL"); // омега-6
|
||||
await addSuppCol("omega9_mg", "REAL"); // омега-9
|
||||
|
||||
// Deduplicate products: keep lowest id, reassign food_log and recipe_ingredients
|
||||
// Deduplicate products: keep lowest id per name_lower, reassign refs, delete dupes
|
||||
// All in bulk SQL — no per-row loop
|
||||
try {
|
||||
const dupes = await select(
|
||||
"SELECT name_lower, MIN(id) as keep_id, COUNT(*) as cnt FROM products WHERE name_lower IS NOT NULL GROUP BY name_lower HAVING cnt > 1"
|
||||
);
|
||||
if (dupes.length > 0) {
|
||||
for (const d of dupes) {
|
||||
// Reassign food_log entries to the kept product
|
||||
await execute("UPDATE food_log SET product_id = ?1 WHERE product_id IN (SELECT id FROM products WHERE name_lower = ?2 AND id != ?1)", [d.keep_id, d.name_lower]);
|
||||
// Reassign recipe_ingredients
|
||||
await execute("UPDATE recipe_ingredients SET product_id = ?1 WHERE product_id IN (SELECT id FROM products WHERE name_lower = ?2 AND id != ?1)", [d.keep_id, d.name_lower]);
|
||||
// Delete duplicates
|
||||
await execute("DELETE FROM products WHERE name_lower = ?1 AND id != ?2", [d.name_lower, d.keep_id]);
|
||||
}
|
||||
console.log(`[db.js] Deduplicated ${dupes.length} product groups`);
|
||||
const dupeCount = await select("SELECT COUNT(*) as cnt FROM products WHERE name_lower IS NOT NULL AND id NOT IN (SELECT MIN(id) FROM products WHERE name_lower IS NOT NULL GROUP BY name_lower)");
|
||||
if (dupeCount[0].cnt > 0) {
|
||||
// Reassign food_log to kept (MIN) id
|
||||
await execute(`UPDATE food_log SET product_id = (
|
||||
SELECT MIN(p2.id) FROM products p2 WHERE p2.name_lower = (SELECT p3.name_lower FROM products p3 WHERE p3.id = food_log.product_id)
|
||||
) WHERE product_id IN (SELECT id FROM products WHERE name_lower IS NOT NULL AND id NOT IN (SELECT MIN(id) FROM products WHERE name_lower IS NOT NULL GROUP BY name_lower))`);
|
||||
// Reassign recipe_ingredients
|
||||
await execute(`UPDATE recipe_ingredients SET product_id = (
|
||||
SELECT MIN(p2.id) FROM products p2 WHERE p2.name_lower = (SELECT p3.name_lower FROM products p3 WHERE p3.id = recipe_ingredients.product_id)
|
||||
) WHERE product_id IN (SELECT id FROM products WHERE name_lower IS NOT NULL AND id NOT IN (SELECT MIN(id) FROM products WHERE name_lower IS NOT NULL GROUP BY name_lower))`);
|
||||
// Delete dupes
|
||||
await execute("DELETE FROM products WHERE name_lower IS NOT NULL AND id NOT IN (SELECT MIN(id) FROM products WHERE name_lower IS NOT NULL GROUP BY name_lower)");
|
||||
console.log(`[db.js] Deduplicated ${dupeCount[0].cnt} products`);
|
||||
}
|
||||
} catch (e) { console.error("[db.js] dedup error:", e); }
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue