diff --git a/frontend/js/db.js b/frontend/js/db.js index 96f4a7d..21b3f70 100644 --- a/frontend/js/db.js +++ b/frontend/js/db.js @@ -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); }