adding files to database works

This commit is contained in:
Iaphetes 2025-03-16 19:04:14 +01:00
parent dcfb500a5f
commit 852ab87b0b
4 changed files with 154 additions and 52 deletions

17
src-tauri/Cargo.lock generated
View file

@ -165,6 +165,7 @@ dependencies = [
"comrak", "comrak",
"confy", "confy",
"diff-match-patch-rs", "diff-match-patch-rs",
"futures",
"fuzzy-matcher", "fuzzy-matcher",
"html_tag", "html_tag",
"rand 0.9.0", "rand 0.9.0",
@ -1429,6 +1430,21 @@ dependencies = [
"new_debug_unreachable", "new_debug_unreachable",
] ]
[[package]]
name = "futures"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876"
dependencies = [
"futures-channel",
"futures-core",
"futures-executor",
"futures-io",
"futures-sink",
"futures-task",
"futures-util",
]
[[package]] [[package]]
name = "futures-channel" name = "futures-channel"
version = "0.3.31" version = "0.3.31"
@ -1515,6 +1531,7 @@ version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
dependencies = [ dependencies = [
"futures-channel",
"futures-core", "futures-core",
"futures-io", "futures-io",
"futures-macro", "futures-macro",

View file

@ -35,5 +35,6 @@ confy = "0.6.1"
tauri-plugin-dialog = "2" tauri-plugin-dialog = "2"
diff-match-patch-rs = "0.4.1" diff-match-patch-rs = "0.4.1"
rand = "0.9" rand = "0.9"
futures = "0.3.31"
# [profile.dev] # [profile.dev]
# codegen-backend = "cranelift" # codegen-backend = "cranelift"

View file

@ -2,18 +2,31 @@ use std::{
fs::File, fs::File,
io::{Error, Read}, io::{Error, Read},
path::Path, path::Path,
str::FromStr,
}; };
use crate::get_basepath; use crate::get_basepath;
use serde::{Deserialize, Serialize};
use sqlx::{migrate::MigrateDatabase, Sqlite, SqlitePool}; use sqlx::{migrate::MigrateDatabase, Sqlite, SqlitePool};
use tauri::{ipc::RuntimeCapability, App, AssetResolver, Manager, Url}; use tauri::{ipc::RuntimeCapability, App, AssetResolver, Manager, Url};
struct DBFileEntry {
id: u64,
relative_file_path: String,
file_name: String,
}
#[derive(Debug, Serialize, Deserialize)]
pub enum DBError {
DatabaseLocationError(String),
DatabaseConnectionError(String),
DatabaseQueryError(String),
}
async fn populate_file_db(db: &SqlitePool) {} async fn populate_file_db(db: &SqlitePool) {}
fn get_database_path(app_handle: &tauri::AppHandle) -> Result<String, ()> { fn get_database_path(app_handle: &tauri::AppHandle) -> Result<String, DBError> {
if let Some(basepath) = get_basepath(app_handle.clone()) { if let Some(basepath) = get_basepath(app_handle.clone()) {
let db_path = Path::new("Documents") let db_path = Path::new(&basepath).join("db.sqlite");
.join(Path::new("Knowledgebase"))
.join("db.sqlite");
let resolved_db_path = match app_handle let resolved_db_path = match app_handle
.path() .path()
@ -21,52 +34,44 @@ fn get_database_path(app_handle: &tauri::AppHandle) -> Result<String, ()> {
{ {
Ok(resolved_knowledgebase_path) => resolved_knowledgebase_path, Ok(resolved_knowledgebase_path) => resolved_knowledgebase_path,
Err(_) => return Err(()), Err(e) => return Err(DBError::DatabaseLocationError(e.to_string())),
}; };
let unicode_db_path = &resolved_db_path.to_string_lossy().to_owned(); let unicode_db_path = resolved_db_path.to_string_lossy().as_ref().to_string();
return Ok(unicode_db_path);
} }
Err(()) Err(DBError::DatabaseLocationError(
"No knowledgebase defined".to_string(),
))
} }
#[tauri::command] #[tauri::command]
pub async fn initialize_database(app_handle: tauri::AppHandle) { pub async fn initialize_database(app_handle: tauri::AppHandle) -> Result<(), DBError> {
if let Some(basepath) = get_basepath(app_handle.clone()) { let unicode_db_path = get_database_path(&app_handle)?;
let db_path = Path::new("Documents") if !Sqlite::database_exists(&unicode_db_path)
.join(Path::new("Knowledgebase")) .await
.join("db.sqlite"); .unwrap_or(false)
{
let resolved_db_path = match app_handle match Sqlite::create_database(&unicode_db_path).await {
.path() Ok(_) => println!("Create db success"),
.resolve(db_path, tauri::path::BaseDirectory::Home) Err(error) => panic!("error: {}", error),
{
Ok(resolved_knowledgebase_path) => resolved_knowledgebase_path,
Err(_) => return,
};
let unicode_db_path = &resolved_db_path.to_string_lossy().to_owned();
if !Sqlite::database_exists(&unicode_db_path)
.await
.unwrap_or(false)
{
match Sqlite::create_database(&unicode_db_path).await {
Ok(_) => println!("Create db success"),
Err(error) => panic!("error: {}", error),
}
} }
let db = SqlitePool::connect(unicode_db_path).await.unwrap(); }
let result = sqlx::query( let db = SqlitePool::connect(&unicode_db_path)
"CREATE TABLE IF NOT EXISTS files .await
.map_err(|e| DBError::DatabaseConnectionError(e.to_string()))?;
let _ = sqlx::query(
"CREATE TABLE IF NOT EXISTS files
( (
id INTEGER PRIMARY KEY NOT NULL, id INTEGER PRIMARY KEY NOT NULL,
relative_path TEXT NOT NULL, relative_path TEXT NOT NULL,
file_name TEXT NOT NULL file_name TEXT NOT NULL
);", );",
) )
.execute(&db) .execute(&db)
.await .await
.unwrap(); .map_err(|e| DBError::DatabaseQueryError(e.to_string()))?;
let result = sqlx::query( let _ = sqlx::query(
"CREATE TABLE IF NOT EXISTS file_diffs "CREATE TABLE IF NOT EXISTS file_diffs
( (
id INTEGER NOT NULL, id INTEGER NOT NULL,
client_id INTEGER NOT NULL, client_id INTEGER NOT NULL,
@ -77,14 +82,79 @@ pub async fn initialize_database(app_handle: tauri::AppHandle) {
PRIMARY KEY (id, client_id) PRIMARY KEY (id, client_id)
) )
;", ;",
) )
.execute(&db) .execute(&db)
.await .await
.unwrap(); .map_err(|e| DBError::DatabaseQueryError(e.to_string()))?;
} db.close().await;
Ok(())
} }
#[tauri::command] #[tauri::command]
async fn store_diff(file_path: String, file_name: String, diff: String) {} async fn store_diff(
app_handle: &tauri::AppHandle,
file_path: String,
file_name: String,
diff: String,
) -> Result<(), DBError> {
Ok(())
}
async fn add_file(file_path: String, file_name: String) {} async fn get_file_id(
app_handle: &tauri::AppHandle,
relative_file_path: &str,
file_name: &str,
) -> Result<i32, DBError> {
let unicode_db_path = get_database_path(&app_handle)?;
let db = SqlitePool::connect(&unicode_db_path)
.await
.map_err(|e| DBError::DatabaseConnectionError(e.to_string()))?;
let (id, _, _): (i32, String, String) = sqlx::query_as(&format!(
"
SELECT *
FROM files
WHERE relative_path IS '{relative_file_path}'
AND file_name IS '{file_name}'
"
))
.fetch_one(&db)
.await
.map_err(|e| DBError::DatabaseQueryError(e.to_string()))?;
db.close().await;
Ok(id)
}
pub async fn add_file(
app_handle: &tauri::AppHandle,
relative_file_path: &str,
file_name: &str,
) -> Result<(), DBError> {
if get_file_id(app_handle, relative_file_path, file_name)
.await
.is_ok()
{
return Ok(());
} else {
println!(
"{:?}",
get_file_id(app_handle, relative_file_path, file_name).await
);
}
let unicode_db_path = get_database_path(&app_handle)?;
let db = SqlitePool::connect(&unicode_db_path)
.await
.map_err(|e| DBError::DatabaseConnectionError(e.to_string()))?;
let _ = sqlx::query(&format!(
"
INSERT INTO
files (relative_path, file_name)
VALUES
('{relative_file_path}', '{file_name}');"
))
.execute(&db)
.await
.map_err(|e| DBError::DatabaseQueryError(e.to_string()))?;
db.close().await;
Ok(())
}

View file

@ -1,4 +1,5 @@
use crate::get_basepath; use crate::{database::add_file, get_basepath};
use futures::future::{BoxFuture, FutureExt};
use html_tag::HtmlTag; use html_tag::HtmlTag;
use shellexpand; use shellexpand;
use std::{ use std::{
@ -6,14 +7,20 @@ use std::{
path::Path, path::Path,
}; };
#[tauri::command] #[tauri::command]
pub fn dir_tree_html(app_handle: tauri::AppHandle, filter: Vec<String>) -> String { pub async fn dir_tree_html(app_handle: tauri::AppHandle, filter: Vec<String>) -> String {
if let Some(basepath) = get_basepath(app_handle) { if let Some(basepath) = get_basepath(app_handle.clone()) {
add_dir_tree_node(&Path::new(&basepath), &filter).to_html() add_dir_tree_node(&app_handle, &Path::new(&basepath), &filter)
.await
.to_html()
} else { } else {
String::new() String::new()
} }
} }
fn add_dir_tree_node(path: &Path, filter: &Vec<String>) -> HtmlTag { async fn add_dir_tree_node(
app_handle: &tauri::AppHandle,
path: &Path,
filter: &Vec<String>,
) -> HtmlTag {
let mut html = HtmlTag::new("div") let mut html = HtmlTag::new("div")
.with_class("filetree-node") .with_class("filetree-node")
.with_id(&format!( .with_id(&format!(
@ -46,10 +53,17 @@ fn add_dir_tree_node(path: &Path, filter: &Vec<String>) -> HtmlTag {
if let Ok(dir_entry) = dir_entry_res { if let Ok(dir_entry) = dir_entry_res {
if let Ok(metadata) = fs::metadata(dir_entry.path()) { if let Ok(metadata) = fs::metadata(dir_entry.path()) {
if metadata.is_file() { if metadata.is_file() {
add_file(
app_handle,
path.to_string_lossy().as_ref(),
dir_entry.file_name().to_string_lossy().as_ref(),
)
.await;
html.add_child(div_from_dir_entry(&dir_entry)) html.add_child(div_from_dir_entry(&dir_entry))
} else if metadata.is_dir() { } else if metadata.is_dir() {
html.add_child( html.add_child(
add_dir_tree_node(&dir_entry.path(), &filter) Box::pin(add_dir_tree_node(app_handle, &dir_entry.path(), &filter))
.await
.with_attribute("style", "visibility: hidden; height: 0px;"), // .with_style("visibility", "hidden") .with_attribute("style", "visibility: hidden; height: 0px;"), // .with_style("visibility", "hidden")
// .with_style("height", "0px"), // .with_style("height", "0px"),
); );