sharePatches

tcmts.store.sharePatches · #ju3jvvmg · term · runs anywhere

Layout step: patches kept whole for each branch (layout 8f648138…) go into sets branches share (85655ca2…). Main's are one set, and every branch reads a set of its own over it, holding where it differs (a patch main doesn't have, or one hiding a patch of main's it doesn't have); or a set of its own alone, where that's less.

import type { DatabaseSync } from "node:sqlite";

export function sharePatches(db: DatabaseSync) {
  db.exec(`ALTER TABLE patches RENAME TO patches_by_branch;
CREATE TABLE patch_sets (id INTEGER PRIMARY KEY, base INTEGER);
CREATE TABLE patches (set_id INTEGER NOT NULL, old_hash TEXT NOT NULL, new_hash TEXT NOT NULL, ts INTEGER NOT NULL, PRIMARY KEY (set_id, old_hash)) WITHOUT ROWID;
ALTER TABLE branches ADD COLUMN patches INTEGER NOT NULL DEFAULT 0;`);
  const set = (base: number) =>
    Number(
      db.prepare("INSERT INTO patch_sets (base) VALUES (?)").run(base || null).lastInsertRowid,
    );
  const count = (sql: string, ...args: number[]) =>
    (db.prepare(`SELECT count(*) AS n FROM (${sql})`).get(...args) as { n: number }).n;
  const main = (
    db.prepare("SELECT id FROM branches WHERE name = 'main'").get() as { id: number } | undefined
  )?.id;
  const mains =
    main === undefined ? 0 : count("SELECT 1 FROM patches_by_branch WHERE branch_id = ?", main);
  const shared = mains ? set(0) : 0;
  if (shared)
    db.prepare(
      "INSERT INTO patches SELECT ?, old_hash, new_hash, ts FROM patches_by_branch WHERE branch_id = ?",
    ).run(shared, main!);
  // (a branch's patches main doesn't have as they are; and main's it has none for, hidden: a patch to itself)
  const differ =
    "SELECT ? AS s, p.old_hash, p.new_hash, p.ts FROM patches_by_branch p WHERE p.branch_id = ? AND NOT EXISTS (SELECT 1 FROM patches m WHERE m.set_id = ? AND m.old_hash = p.old_hash AND m.new_hash = p.new_hash)";
  const hidden =
    "SELECT ? AS s, m.old_hash, m.old_hash, m.ts FROM patches m WHERE m.set_id = ? AND NOT EXISTS (SELECT 1 FROM patches_by_branch p WHERE p.branch_id = ? AND p.old_hash = m.old_hash)";
  for (const { id } of db.prepare("SELECT id FROM branches").all() as { id: number }[]) {
    const own = count("SELECT 1 FROM patches_by_branch WHERE branch_id = ?", id);
    const over = shared ? count(differ, 0, id, shared) + count(hidden, 0, shared, id) : Infinity;
    let top = 0;
    if (over <= own) {
      top = set(shared);
      db.prepare(`INSERT INTO patches ${differ}`).run(top, id, shared);
      db.prepare(`INSERT INTO patches ${hidden}`).run(top, shared, id);
    } else if (own) {
      top = set(0);
      db.prepare(
        "INSERT INTO patches SELECT ?, old_hash, new_hash, ts FROM patches_by_branch WHERE branch_id = ?",
      ).run(top, id);
    }
    db.prepare("UPDATE branches SET patches = ? WHERE id = ?").run(top, id);
  }
  db.exec("DROP TABLE patches_by_branch");
}

used by