defmodule GitGud.Repo.Migrations.CreateGitCaches do
use Ecto.Migration
def change do
# Mutable: current state of refs. Authoritative storage is on-disk,
# but the UI reads here.
create table(:git_refs, primary_key: false) do
add :repository_id, references(:repositories, on_delete: :delete_all),
null: false,
primary_key: true
add :name, :string, null: false, primary_key: true
add :target_sha, :binary, null: false
add :peeled_sha, :binary
add :ref_type, :string, null: false, default: "branch"
timestamps(type: :utc_datetime, updated_at: :updated_at, inserted_at: false)
end
create index(:git_refs, [:repository_id, :ref_type])
# Immutable, content-addressed. SHA = raw 20-byte sha1.
create table(:git_commits, primary_key: false) do
add :repository_id, references(:repositories, on_delete: :delete_all),
null: false,
primary_key: true
add :sha, :binary, null: false, primary_key: true
add :tree_sha, :binary, null: false
add :parent_shas, {:array, :binary}, null: false, default: []
add :author_name, :string
add :author_email, :string
add :authored_at, :utc_datetime
add :committer_name, :string
add :committer_email, :string
add :committed_at, :utc_datetime
add :message, :text
# commit-graph generation number; supports paginated revwalk
add :generation, :integer
add :inserted_at, :utc_datetime, null: false, default: fragment("now()")
end
create index(:git_commits, [:repository_id, :committed_at])
create index(:git_commits, [:repository_id, :author_email])
# Tree entries stored as a single jsonb blob per tree. Keeps reads to
# one row per directory listing.
create table(:git_trees, primary_key: false) do
add :repository_id, references(:repositories, on_delete: :delete_all),
null: false,
primary_key: true
add :sha, :binary, null: false, primary_key: true
# [{name, mode, type, sha, size}, ...]
add :entries, :map, null: false
add :inserted_at, :utc_datetime, null: false, default: fragment("now()")
end
# Cheap metadata about blobs. Bytes themselves stay in the git
# object store on disk (or LFS in Garage).
create table(:git_blob_meta, primary_key: false) do
add :repository_id, references(:repositories, on_delete: :delete_all),
null: false,
primary_key: true
add :sha, :binary, null: false, primary_key: true
add :size, :bigint, null: false
add :mime, :string
add :is_binary, :boolean, null: false, default: false
add :line_count, :integer
add :detected_language, :string
add :inserted_at, :utc_datetime, null: false, default: fragment("now()")
end
# Per-commit diff summary for fast "x files +y -z" rendering.
create table(:git_commit_diffstats, primary_key: false) do
add :repository_id, references(:repositories, on_delete: :delete_all),
null: false,
primary_key: true
add :sha, :binary, null: false, primary_key: true
add :files_changed, :integer, null: false, default: 0
add :insertions, :integer, null: false, default: 0
add :deletions, :integer, null: false, default: 0
# Touched paths kept for "files in this commit" listing and for
# cheap path-filtered log queries.
add :paths, {:array, :string}, null: false, default: []
add :inserted_at, :utc_datetime, null: false, default: fragment("now()")
end
# LRU-evictable render cache. kind = markdown | highlight | plain.
# renderer_version lets us invalidate on MDEx / highlighter upgrades.
create table(:git_renders, primary_key: false) do
add :repository_id, references(:repositories, on_delete: :delete_all),
null: false,
primary_key: true
add :blob_sha, :binary, null: false, primary_key: true
add :kind, :string, null: false, primary_key: true
add :renderer_version, :integer, null: false, primary_key: true
add :body, :text, null: false
add :touched_at, :utc_datetime, null: false, default: fragment("now()")
add :inserted_at, :utc_datetime, null: false, default: fragment("now()")
end
create index(:git_renders, [:repository_id, :touched_at])
end
end
4.3 KiB · text
5af55d9