Libra Database Scheme

Introduction

Libra use sea-orm to interact with sqlite database. The data model is defined in libra/src/internal/model, with two tables: config and reference.

The config table is used to store the configuration of the project, which corresponds to the config file in git. The reference table is used to store the reference of the project, which corresponds to the HEAD and refs/* files in git.

The relationship between the git file and the sqlite table is as follows:

reference:

CategoryDescriptionDatabase format
.git/HEADCurrent head pointer (branch or commit hash)Reference(name=<branch>; kind=HEAD;commit=null;remote=null)

Reference(name=null; kind=HEAD;commit=<commit hash>;remote=null)
.git/refs/heads/<branch>Branch name, can’t be “HEAD”Reference(name=<branch>, kind=Branch; commit=<commit hash>; remote=null)
.git/refs/tags/<tag> Similar to branchReference(name=<tag>, kind=Tag; commit=<commit hash>; remote=null)
.git/refs/remotes/<remote>/<branch>Contains branch heads and HEADRemote HEAD can’t be detached.Reference(name=<branch>, kind=Branch; commit=<commit hash>; remote=<remote>)

Reference(name=<branch>; type=HEAD; commit=null; remote=<remote>)

config:

# config Example
[core]
        filemode = true
        ignorecase = false
[remote "origin"]
        url = url.git
        fetch = +refs/heads……
CategoryDescriptionDatabase format
.gitconfigIni format configurationConfig(configuration=”core”; name=null; key=”filemode”;value=”true” )

Config(configuration=”core”; name=null; key=”ignorecase”;value=”false” )

Config(configuration=”remote”; name=”origin”; key=”url”;value=”url.git” )

Config(configuration=”remote”; name=”null”; key=”fetch”;value=”+refs……” )

Business Model Design

For decoupling, the sea-orm model is not directly used in the code, and the business model is redefined (located in libra/src/internal), and common CRUD operations are implemented.

Currently, the config, head and reference models are implemented.

SQL Statement

CREATE TABLE IF NOT EXISTS `config` (
    `id` INTEGER PRIMARY KEY AUTOINCREMENT,
    `configuration` TEXT NOT NULL,
    `name` TEXT,
    `key` TEXT NOT NULL,
    `value` TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS `reference` (
    `id` INTEGER PRIMARY KEY AUTOINCREMENT,
    -- name can't be ''
    `name` TEXT CHECK (name <> '' OR name IS NULL),
    `kind` TEXT NOT NULL CHECK (kind IN ('Branch', 'Tag', 'Head')),
    `commit` TEXT,
    -- remote can't be ''. If kind is Tag, remote must be NULL.
    `remote` TEXT CHECK (remote <> '' OR remote IS NULL),
    CHECK (
        (kind <> 'Tag' OR (kind = 'Tag' AND remote IS NULL))
    )
);
--  (name, kind, remote) as unique key when remote is not null
CREATE UNIQUE INDEX idx_name_kind_remote ON `reference`(`name`, `kind`, `remote`)
WHERE `remote` IS NOT NULL;

-- (name, kind) as unique key when remote is null
CREATE UNIQUE INDEX idx_name_kind ON `reference`(`name`, `kind`)
WHERE `remote` IS NULL;