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:
Category | Description | Database format |
---|---|---|
.git/HEAD | Current 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 branch | Reference(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……
Category | Description | Database format |
---|---|---|
.gitconfig | Ini format configuration | Config(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;