summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--builtin/init-db.c93
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);