diff options
author | Terin Stock <terinjokes@gmail.com> | 2022-04-25 00:17:08 -0700 |
---|---|---|
committer | Terin Stock <terinjokes@gmail.com> | 2022-04-25 00:17:08 -0700 |
commit | f9cfa54ff8c9bb44258666d96bc0fd5b65f27f18 (patch) | |
tree | fb04df85f37d141daed46a81e7e46780461f870d | |
parent | cmd/version: include fork and sqlite versions (diff) | |
download | tgif-2.36.tar.xz |
init-db: create sqlite database2.36
When creating a new repository, create a SQLite3 database in the git
directory. This database currently stores objects, refs, and the HEAD
pointer.
The upstream implementation mixes filesystem and system checks,
configuration updating, template copying, and creating the "objects" and
"refs" directories. A future revision of this patch should split this
logic apart such that the SQLite3 implementation can omit these directories.
-rw-r--r-- | builtin/init-db.c | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/builtin/init-db.c b/builtin/init-db.c index 546f9c595e..922a514084 100644 --- a/builtin/init-db.c +++ b/builtin/init-db.c @@ -11,6 +11,9 @@ #include "parse-options.h" #include "worktree.h" +#include <sqlite3.h> +#include <string.h> + #ifndef DEFAULT_GIT_TEMPLATE_DIR #define DEFAULT_GIT_TEMPLATE_DIR "/usr/share/git-core/templates" #endif @@ -381,6 +384,18 @@ static void validate_hash_algorithm(struct repository_format *repo_fmt, int hash } } +#if defined(USE_SQLITE) +static char *get_sqlite_dbname(const char *gitdir) +{ + struct strbuf path = STRBUF_INIT; + + strbuf_addstr(&path, gitdir); + strbuf_addstr(&path, "/git.sqlite"); + + return strbuf_detach(&path, NULL); +} +#endif + int init_db(const char *git_dir, const char *real_git_dir, const char *template_dir, int hash, const char *initial_branch, unsigned int flags) @@ -455,6 +470,84 @@ int init_db(const char *git_dir, const char *real_git_dir, git_config_set("receive.denyNonFastforwards", "true"); } +#if defined(USE_SQLITE) + sqlite3 *db; + int rc; + char *errMsg; + char *dbname; + char *ref; + + dbname = get_sqlite_dbname(git_dir); + + rc = sqlite3_open(dbname, &db); + if (rc) { + die(_("can't open database: %s"), sqlite3_errmsg(db)); + } + + // TODO: read sqlite options from gitconfig. + rc = sqlite3_exec(db, "PRAGMA journal_mode = WAL; PRAGMA synchronous = NORMAL; PRAGMA foreign_keys = ON;", NULL, NULL, &errMsg); + if (rc != SQLITE_OK) { + printf(_("SQL Error: %s\n"), errMsg); + sqlite3_free(errMsg); + die("sql error!"); + } + + if (!reinit) { + rc = sqlite3_exec(db, "CREATE TABLE objects(hash BLOB PRIMARY KEY NOT NULL, \ + content BLOB NOT NULL); \ + CREATE TABLE refs(name STRING PRIMARY KEY NOT NULL, \ + hash BLOB NOT NULL, \ + FOREIGN KEY(hash) REFERENCES objects(hash)); \ + CREATE TABLE head(id INTEGER PRIMARY KEY CHECK (id = 0), \ + head BLOB)", NULL, NULL, &errMsg); + if (rc != SQLITE_OK) { + printf(_("SQL Error: %s\n"), errMsg); + sqlite3_free(errMsg); + die("sql error!"); + } + + if (!initial_branch) + initial_branch = git_default_branch_name(flags & INIT_DB_QUIET); + + ref = xstrfmt("refs/heads/%s", initial_branch); + if (check_refname_format(ref, 0) < 0) + die(_("invalid initial branch name: '%s'"), + initial_branch); + + sqlite3_stmt *stmt; + rc = sqlite3_prepare_v2(db, "REPLACE INTO head(id, head) VALUES (0, ?)", -1, &stmt, NULL); + if (rc != SQLITE_OK) { + printf(_("[%d] SQL Error: %s\n"), __LINE__, errMsg); + sqlite3_free(errMsg); + die("sql error!"); + } + + rc = sqlite3_bind_text(stmt, 1, ref, strlen(ref)+1, free); + if (rc != SQLITE_OK) { + printf(_("[%d] SQL Error: %s\n"), __LINE__, errMsg); + sqlite3_free(errMsg); + die("sql error!"); + } + + rc = sqlite3_step(stmt); + if (rc != SQLITE_DONE) { + printf(_("[%d] SQL Error: %s\n"), __LINE__, errMsg); + sqlite3_free(errMsg); + die("sql error!"); + } + + rc = sqlite3_finalize(stmt); + if (rc != SQLITE_OK) { + printf(_("[%d] SQL Error: %s\n"), __LINE__, errMsg); + sqlite3_free(errMsg); + die("sql error!"); + } + } + + sqlite3_close(db); + free(dbname); +#endif + if (!(flags & INIT_DB_QUIET)) { int len = strlen(git_dir); |