88 lines · 4.3 KB
-- LFS storage is content-addressed: one R2 copy per oid, shared by every repository that links it.
-- Each account is billed once per oid no matter how many of its repositories (forks) link it.
-- Dev-only data: the old per-repo tables are recreated rather than migrated.

DROP TABLE IF EXISTS lfs_objects;
DROP TABLE IF EXISTS lfs_usage;

-- Which repositories may serve an oid. owner_id is denormalized so triggers can bill without a join
-- (the repo row may already be gone during a cascading delete).
CREATE TABLE lfs_objects (
  repo_id TEXT NOT NULL REFERENCES repos(id) ON DELETE CASCADE,
  oid TEXT NOT NULL,
  owner_id TEXT NOT NULL,
  size INTEGER NOT NULL,
  created_at INTEGER NOT NULL,
  PRIMARY KEY (repo_id, oid)
);
CREATE INDEX lfs_objects_oid ON lfs_objects (oid);

-- The single stored copy. refs counts lfs_objects rows; at 0 the sweeper deletes it after a grace period.
CREATE TABLE lfs_blobs (
  oid TEXT PRIMARY KEY,
  size INTEGER NOT NULL,
  r2_key TEXT NOT NULL,
  refs INTEGER NOT NULL DEFAULT 0,
  orphaned_at INTEGER,
  created_at INTEGER NOT NULL
);
CREATE INDEX lfs_blobs_orphaned ON lfs_blobs (orphaned_at) WHERE orphaned_at IS NOT NULL;

-- Per-account billing: refs counts the account's repositories linking the oid; billed while refs > 0.
CREATE TABLE lfs_account_objects (
  owner_id TEXT NOT NULL,
  oid TEXT NOT NULL,
  size INTEGER NOT NULL,
  refs INTEGER NOT NULL,
  PRIMARY KEY (owner_id, oid)
);

CREATE TABLE lfs_usage (