diff --git a/Cargo.lock b/Cargo.lock index a9a9b6685..875968f0c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1266,6 +1266,50 @@ dependencies = [ "serde", ] +[[package]] +name = "diesel" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62d6dcd069e7b5fe49a302411f759d4cf1cf2c27fe798ef46fb8baefc053dd2b" +dependencies = [ + "diesel_derives", + "libsqlite3-sys", + "time", +] + +[[package]] +name = "diesel_derives" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59de76a222c2b8059f789cbe07afbfd8deb8c31dd0bc2a21f85e256c1def8259" +dependencies = [ + "diesel_table_macro_syntax", + "dsl_auto_type", + "proc-macro2", + "quote", + "syn 2.0.68", +] + +[[package]] +name = "diesel_migrations" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a73ce704bad4231f001bff3314d91dce4aba0770cee8b233991859abc15c1f6" +dependencies = [ + "diesel", + "migrations_internals", + "migrations_macros", +] + +[[package]] +name = "diesel_table_macro_syntax" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "209c735641a413bc68c4923a9d6ad4bcb3ca306b794edaa7eb0b3228a99ffb25" +dependencies = [ + "syn 2.0.68", +] + [[package]] name = "diff" version = "0.1.13" @@ -1373,6 +1417,20 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" +[[package]] +name = "dsl_auto_type" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0892a17df262a24294c382f0d5997571006e7a4348b4327557c4ff1cd4a8bccc" +dependencies = [ + "darling", + "either", + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.68", +] + [[package]] name = "dtoa" version = "1.0.9" @@ -2129,6 +2187,7 @@ dependencies = [ "git2", "git2-hooks", "gitbutler-git", + "gitbutler-project-store", "gitbutler-testsupport", "gix", "glob", @@ -2198,6 +2257,16 @@ dependencies = [ "walkdir", ] +[[package]] +name = "gitbutler-project-store" +version = "0.0.0" +dependencies = [ + "anyhow", + "diesel", + "diesel_migrations", + "libsqlite3-sys", +] + [[package]] name = "gitbutler-tauri" version = "0.0.0" @@ -3859,6 +3928,17 @@ dependencies = [ "libc", ] +[[package]] +name = "libsqlite3-sys" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29f835d03d717946d28b1d1ed632eb6f0e24a299388ee623d0c23118d3e8a7fa" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + [[package]] name = "libssh2-sys" version = "0.3.0" @@ -4030,6 +4110,27 @@ dependencies = [ "autocfg", ] +[[package]] +name = "migrations_internals" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd01039851e82f8799046eabbb354056283fb265c8ec0996af940f4e85a380ff" +dependencies = [ + "serde", + "toml 0.8.14", +] + +[[package]] +name = "migrations_macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb161cc72176cb37aa47f1fc520d3ef02263d67d661f44f05d05a079e1237fd" +dependencies = [ + "migrations_internals", + "proc-macro2", + "quote", +] + [[package]] name = "mime" version = "0.3.17" diff --git a/Cargo.toml b/Cargo.toml index 001ffb302..dc00894a3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ members = [ "crates/gitbutler-watcher/vendor/debouncer", "crates/gitbutler-testsupport", "crates/gitbutler-cli", + "crates/gitbutler-project-store" ] resolver = "2" @@ -25,6 +26,7 @@ gitbutler-core = { path = "crates/gitbutler-core" } gitbutler-watcher = { path = "crates/gitbutler-watcher" } gitbutler-testsupport = { path = "crates/gitbutler-testsupport" } gitbutler-cli ={ path = "crates/gitbutler-cli" } +gitbutler-project-store = { path = "crates/gitbutler-project-store" } [profile.release] codegen-units = 1 # Compile crates one after another so the compiler can optimize better diff --git a/crates/gitbutler-core/Cargo.toml b/crates/gitbutler-core/Cargo.toml index 8e2d25527..dad48da78 100644 --- a/crates/gitbutler-core/Cargo.toml +++ b/crates/gitbutler-core/Cargo.toml @@ -57,6 +57,7 @@ uuid.workspace = true walkdir = "2.5.0" zip = "0.6.5" gitbutler-git.workspace = true +gitbutler-project-store.workspace = true [features] # by default Tauri runs in production mode diff --git a/crates/gitbutler-project-store/Cargo.toml b/crates/gitbutler-project-store/Cargo.toml new file mode 100644 index 000000000..4876a545a --- /dev/null +++ b/crates/gitbutler-project-store/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "gitbutler-project-store" +version = "0.0.0" +edition = "2021" +publish = false + +[lib] +path = "src/lib.rs" +doctest = false +test = false + +[dependencies] +diesel = { version = "2.2.0", features = ["sqlite"] } +diesel_migrations = { version = "2.2.0" } +libsqlite3-sys = { version = "0.25.2", features = ["bundled"] } +anyhow = "1.0.86" \ No newline at end of file diff --git a/crates/gitbutler-project-store/diesel.toml b/crates/gitbutler-project-store/diesel.toml new file mode 100644 index 000000000..126d532c9 --- /dev/null +++ b/crates/gitbutler-project-store/diesel.toml @@ -0,0 +1,9 @@ +# For documentation on how to configure this file, +# see https://diesel.rs/guides/configuring-diesel-cli + +[print_schema] +file = "src/schema.rs" +custom_type_derives = ["diesel::query_builder::QueryId", "Clone"] + +[migrations_directory] +dir = "/Users/calebowens/code/gitbutler-client/crates/gitbutler-project-store/migrations" diff --git a/crates/gitbutler-project-store/migrations/.keep b/crates/gitbutler-project-store/migrations/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/crates/gitbutler-project-store/src/lib.rs b/crates/gitbutler-project-store/src/lib.rs new file mode 100644 index 000000000..fadf9aa63 --- /dev/null +++ b/crates/gitbutler-project-store/src/lib.rs @@ -0,0 +1,35 @@ +use anyhow::{anyhow, Result}; +use std::path::Path; + +use diesel::{Connection, SqliteConnection}; +use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness}; + +const DATABASE_NAME: &str = "project.sqlite"; +const MIGRATIONS: EmbeddedMigrations = embed_migrations!(); + +/// ProjectStore provides a light wrapper around a sqlite database +struct ProjectStore { + connection: SqliteConnection, +} + +/// Database setup +impl ProjectStore { + /// Creates an instance of ProjectStore and runs any pending sqlite migrations + /// gitbutler_project_directory should be the `.git/gitbutler` path of a given + /// repository + pub fn initialize(gitbutler_project_directory: &Path) -> Result { + let database_path = gitbutler_project_directory.join(DATABASE_NAME); + let database_path = database_path.to_str().ok_or(anyhow!( + "Failed to get database {}", + gitbutler_project_directory.display() + ))?; + let mut connection = SqliteConnection::establish(database_path)?; + + // Run any pending migrations + connection + .run_pending_migrations(MIGRATIONS) + .map_err(|err| anyhow!("{}", err))?; + + Ok(ProjectStore { connection }) + } +}