diff --git a/Cargo.lock b/Cargo.lock index 75a9dbae4e5e..e5fe7cbc3bfb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4531,6 +4531,16 @@ dependencies = [ "trie-rs", ] +[[package]] +name = "tabby-repositories" +version = "0.10.0-dev.0" +dependencies = [ + "anyhow", + "serde_json", + "sqlx", + "tabby-common", +] + [[package]] name = "tabby-scheduler" version = "0.10.0-dev.0" diff --git a/Cargo.toml b/Cargo.toml index 7712878600ec..f385bb6159b8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,12 +6,13 @@ members = [ "crates/tabby-scheduler", "crates/tabby-download", "crates/tabby-inference", + "crates/tabby-repositories", "crates/llama-cpp-bindings", "crates/http-api-bindings", "crates/aim-downloader", "crates/juniper-axum", "ee/tabby-webserver", - "ee/tabby-db", "ee/tabby-db-macros", + "ee/tabby-db", "ee/tabby-db-macros", "crates/tabby-repositories", ] [workspace.package] @@ -21,6 +22,7 @@ authors = ["Meng Zhang"] homepage = "https://github.com/TabbyML/tabby" [workspace.dependencies] +sqlx = { version = "0.7.3", features = ["sqlite", "chrono", "runtime-tokio", "macros"] } lazy_static = "1.4.0" serde = { version = "1.0", features = ["derive"] } serde_json = "1" diff --git a/crates/tabby-common/src/path.rs b/crates/tabby-common/src/path.rs index 823d64f91ce4..25b0f491ca35 100644 --- a/crates/tabby-common/src/path.rs +++ b/crates/tabby-common/src/path.rs @@ -29,6 +29,10 @@ pub fn config_file() -> PathBuf { tabby_root().join("config.toml") } +pub fn repository_meta_db() -> PathBuf { + tabby_root().join("repositories.sqlite") +} + pub fn usage_id_file() -> PathBuf { tabby_root().join("usage_anonymous_id") } diff --git a/crates/tabby-repositories/.env b/crates/tabby-repositories/.env new file mode 100644 index 000000000000..5f4d57ee15eb --- /dev/null +++ b/crates/tabby-repositories/.env @@ -0,0 +1 @@ +DATABASE_URL=sqlite://crates/tabby-repositories/schema.sqlite diff --git a/crates/tabby-repositories/Cargo.toml b/crates/tabby-repositories/Cargo.toml new file mode 100644 index 000000000000..a5960dac3577 --- /dev/null +++ b/crates/tabby-repositories/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "tabby-repositories" +version.workspace = true +edition.workspace = true +authors.workspace = true +homepage.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +sqlx = { workspace = true } +anyhow = { workspace = true } +tabby-common = { path = "../tabby-common" } +serde_json = { workspace = true } diff --git a/crates/tabby-repositories/schema.sql b/crates/tabby-repositories/schema.sql new file mode 100644 index 000000000000..c98c37dd85be --- /dev/null +++ b/crates/tabby-repositories/schema.sql @@ -0,0 +1,10 @@ +DROP TABLE IF EXISTS repository_meta; +CREATE TABLE repository_meta( + git_url TEXT NOT NULL, + filepath TEXT NOT NULL, + language TEXT NOT NULL, + max_line_length INTEGER NOT NULL, + avg_line_length REAL NOT NULL, + alphanum_fraction REAL NOT NULL, + tags TEXT NOT NULL +); diff --git a/crates/tabby-repositories/schema.sqlite b/crates/tabby-repositories/schema.sqlite new file mode 100644 index 000000000000..8ee377f05eb2 Binary files /dev/null and b/crates/tabby-repositories/schema.sqlite differ diff --git a/crates/tabby-repositories/src/lib.rs b/crates/tabby-repositories/src/lib.rs new file mode 100644 index 000000000000..01ea76052559 --- /dev/null +++ b/crates/tabby-repositories/src/lib.rs @@ -0,0 +1,57 @@ +use anyhow::Result; +use sqlx::sqlite::SqlitePoolOptions; +use sqlx::{query, SqlitePool}; +use sqlx::{sqlite::SqliteConnectOptions, Pool, Sqlite}; +use std::str::FromStr; +use tabby_common::Tag; + +pub struct RepositoryCache { + pool: Pool, +} + +struct RepositoryMetaDAO { + git_url: String, + filepath: String, + language: String, + max_line_length: usize, + avg_line_length: f32, + alphanum_fraction: f32, + tags: String, +} + +impl RepositoryCache { + pub async fn new() -> Result { + let init_query = include_str!("../schema.sql"); + let options = SqliteConnectOptions::new() + .filename(tabby_common::path::repository_meta_db()) + .create_if_missing(true); + let pool = SqlitePool::connect_with(options).await?; + sqlx::query(init_query).execute(&pool).await?; + Ok(RepositoryCache { pool }) + } + + pub async fn clear(&self) -> Result<()> { + query!("DELETE FROM repository_meta") + .execute(&self.pool) + .await?; + Ok(()) + } + + pub async fn add_repository_meta( + &self, + git_url: String, + filepath: String, + language: String, + max_line_length: i64, + avg_line_length: f32, + alphanum_fraction: f32, + tags: Vec, + ) -> Result<()> { + let tags = serde_json::to_string(&tags)?; + query!("INSERT INTO repository_meta (git_url, filepath, language, max_line_length, avg_line_length, alphanum_fraction, tags) + VALUES ($1, $2, $3, $4, $5, $6, $7)", + git_url, filepath, language, max_line_length, avg_line_length, alphanum_fraction, tags + ).execute(&self.pool).await?; + Ok(()) + } +} diff --git a/ee/tabby-db/Cargo.toml b/ee/tabby-db/Cargo.toml index 9f8f288068f7..e6c584281bbe 100644 --- a/ee/tabby-db/Cargo.toml +++ b/ee/tabby-db/Cargo.toml @@ -15,8 +15,8 @@ anyhow.workspace = true chrono = { workspace = true, features = ["serde"] } hash-ids.workspace = true lazy_static.workspace = true +sqlx = { workspace = true } sql_query_builder = { version = "2.1.0", features = ["sqlite"] } -sqlx = { version = "0.7.3", features = ["sqlite", "chrono", "runtime-tokio", "macros"] } tabby-common = { path = "../../crates/tabby-common" } tokio = { workspace = true, features = ["fs"] } uuid.workspace = true