mirror of
https://github.com/spacedriveapp/spacedrive
synced 2024-07-02 10:03:28 +00:00
checkpoint before potentially removing seaorm
This commit is contained in:
parent
0c19a92f11
commit
338b1eb0d3
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "sd-client",
|
||||
"name": "drive",
|
||||
"version": "1.0.0",
|
||||
"main": "index.js",
|
||||
"license": "MIT",
|
||||
|
|
74
src-tauri/Cargo.lock
generated
74
src-tauri/Cargo.lock
generated
|
@ -1201,6 +1201,18 @@ version = "2.5.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7531096570974c3a9dcf9e4b8e1cede1ec26cf5046219fb3b9d897503b9be59"
|
||||
|
||||
[[package]]
|
||||
name = "fallible-iterator"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7"
|
||||
|
||||
[[package]]
|
||||
name = "fallible-streaming-iterator"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a"
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "1.5.0"
|
||||
|
@ -3060,6 +3072,50 @@ dependencies = [
|
|||
"redox_syscall 0.2.10",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "refinery"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f3a3d4976479c5e9a50352cf9117896b581c939e81f4169295cb9b353d30bc8"
|
||||
dependencies = [
|
||||
"refinery-core",
|
||||
"refinery-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "refinery-core"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1eb7989daaee90c44763f644bfa2c3ce46b0a241b9966c1c2be9e65b4918815b"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"cfg-if 1.0.0",
|
||||
"chrono",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"regex",
|
||||
"rusqlite",
|
||||
"serde",
|
||||
"siphasher",
|
||||
"thiserror",
|
||||
"toml",
|
||||
"url",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "refinery-macros"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e2d142a0c173f7e096ae1297d677cb4bb056fc80f25f31d6b0d2a82da07beee"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote 1.0.9",
|
||||
"refinery-core",
|
||||
"regex",
|
||||
"syn 1.0.74",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.5.4"
|
||||
|
@ -3139,6 +3195,21 @@ dependencies = [
|
|||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rusqlite"
|
||||
version = "0.25.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57adcf67c8faaf96f3248c2a7b419a0dbc52ebe36ba83dd57fe83827c1ea4eb3"
|
||||
dependencies = [
|
||||
"bitflags 1.3.1",
|
||||
"fallible-iterator",
|
||||
"fallible-streaming-iterator",
|
||||
"hashlink",
|
||||
"libsqlite3-sys",
|
||||
"memchr",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rust-argon2"
|
||||
version = "0.8.3"
|
||||
|
@ -3260,11 +3331,14 @@ dependencies = [
|
|||
"futures",
|
||||
"int-enum",
|
||||
"rebind",
|
||||
"refinery",
|
||||
"ring 0.17.0-alpha.10",
|
||||
"rusqlite",
|
||||
"sea-orm",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha256",
|
||||
"sqlx",
|
||||
"tauri",
|
||||
"tauri-build",
|
||||
]
|
||||
|
|
|
@ -25,6 +25,9 @@ crossbeam = "0.8.1"
|
|||
cargo-edit = "0.8.0"
|
||||
sha256 = "1.0.2"
|
||||
int-enum = "0.4.0"
|
||||
rusqlite = "0.25.3"
|
||||
refinery = { version = "0.6.0", features = ["rusqlite"] }
|
||||
sqlx = { version = "0.5.7", features = ["sqlite"] }
|
||||
sea-orm = { version = "^0", features = [ "sqlx-sqlite", "runtime-async-std-rustls", "macros" ], default-features = false }
|
||||
|
||||
[features]
|
||||
|
|
|
@ -5,21 +5,21 @@ use crate::filesystem::file::File;
|
|||
use tauri::InvokeError;
|
||||
|
||||
#[tauri::command(async)]
|
||||
pub async fn read_file_command(path: &str) -> Result<File, InvokeError> {
|
||||
pub async fn read_file_command(path: &str) -> Result<String, InvokeError> {
|
||||
let file = file::read_file(path)
|
||||
.await
|
||||
.map_err(|error| InvokeError::from(format!("Failed to read file: {}", error)))?;
|
||||
|
||||
// file::commit_file(&file).await;
|
||||
println!("file: {:?}", file);
|
||||
|
||||
Ok(file)
|
||||
Ok("lol".to_owned())
|
||||
}
|
||||
#[tauri::command(async)]
|
||||
pub async fn generate_buffer_checksum(path: &str) -> Result<File, InvokeError> {
|
||||
let mut file = file::read_file(path)
|
||||
.await
|
||||
.map_err(|error| InvokeError::from(format!("Failed to read file: {}", error)))?;
|
||||
// #[tauri::command(async)]
|
||||
// pub async fn generate_buffer_checksum(path: &str) -> Result<File, InvokeError> {
|
||||
// let mut file = file::read_file(path)
|
||||
// .await
|
||||
// .map_err(|error| InvokeError::from(format!("Failed to read file: {}", error)))?;
|
||||
|
||||
// file.buffer_checksum = Some(checksum::create_hash(&file.uri).await.unwrap());
|
||||
Ok(file)
|
||||
}
|
||||
// // file.buffer_checksum = Some(checksum::create_hash(&file.uri).await.unwrap());
|
||||
// Ok(file)
|
||||
// }
|
||||
|
|
|
@ -1,21 +1,41 @@
|
|||
use crate::app::config;
|
||||
use crate::filesystem::file;
|
||||
use sea_orm::{Database, DatabaseConnection, DbErr, Schema};
|
||||
use rusqlite::Connection;
|
||||
use sea_orm::{Database, DatabaseConnection, DbErr};
|
||||
// use sqlx::sqlite::{SqliteConnectOptions, SqliteJournalMode};
|
||||
// use sqlx::{ConnectOptions, Connection};
|
||||
// use std::str::FromStr;
|
||||
|
||||
pub async fn get_connection() -> Result<DatabaseConnection, DbErr> {
|
||||
let config = config::get_config();
|
||||
|
||||
// Database::connect(config.primary_db.to_str().unwrap_or("sqlite::memory:")).await?;
|
||||
// Connecting SQLite
|
||||
let db_url = format!("{}{}", "sqlite://", config.primary_db.to_str().unwrap());
|
||||
|
||||
let db = Database::connect(&db_url).await?;
|
||||
|
||||
// Derive schema from Entity
|
||||
let stmt = Schema::create_table_from_entity(file::Model);
|
||||
|
||||
// Execute create table statement
|
||||
let result = db.execute(db.get_database_backend().build(&stmt)).await;
|
||||
|
||||
Ok(db)
|
||||
}
|
||||
|
||||
pub async fn create_primary_db() -> Result<(), sqlx::Error> {
|
||||
let config = config::get_config();
|
||||
|
||||
let db_url = config.primary_db.to_str().unwrap();
|
||||
// establish connection, this is only used to create the db if missing
|
||||
// replace in future
|
||||
let mut connection = Connection::open(db_url).unwrap();
|
||||
|
||||
println!("Primary database initialized: {}", &db_url);
|
||||
|
||||
// migrate db
|
||||
mod embedded_primary {
|
||||
use refinery::embed_migrations;
|
||||
embed_migrations!("src/db/migrations/primary");
|
||||
}
|
||||
|
||||
embedded_primary::migrations::runner()
|
||||
.run(&mut connection)
|
||||
.unwrap();
|
||||
|
||||
// close and exit cause we don't need this connection anymore
|
||||
connection.close().unwrap();
|
||||
Ok(())
|
||||
}
|
||||
|
|
19
src-tauri/src/db/migrate.rs
Normal file
19
src-tauri/src/db/migrate.rs
Normal file
|
@ -0,0 +1,19 @@
|
|||
use crate::db::connection;
|
||||
use rusqlite::Connection;
|
||||
use std::io;
|
||||
|
||||
pub async fn migrate_primary() -> io::Result<()> {
|
||||
let mut conn = Connection::open(connection::get_primary_db_url()).unwrap();
|
||||
|
||||
println!("Running migrations");
|
||||
mod embedded_primary {
|
||||
use refinery::embed_migrations;
|
||||
embed_migrations!("src/db/migrations/primary");
|
||||
}
|
||||
|
||||
embedded_primary::migrations::runner()
|
||||
.run(&mut conn)
|
||||
.unwrap();
|
||||
|
||||
Ok(())
|
||||
}
|
17
src-tauri/src/db/migrations/primary/V1__initial.sql
Normal file
17
src-tauri/src/db/migrations/primary/V1__initial.sql
Normal file
|
@ -0,0 +1,17 @@
|
|||
CREATE TABLE IF NOT EXISTS files (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
uri STRING NOT NULL,
|
||||
meta_checksum STRING NOT NULL,
|
||||
buffer_checksum STRING,
|
||||
name STRING,
|
||||
extension STRING,
|
||||
size_in_bytes STRING NOT NULL,
|
||||
encryption INTEGER DEFAULT 0,
|
||||
ipfs_id STRING,
|
||||
date_created TEXT NOT NULL,
|
||||
date_modified TEXT NOT NULL,
|
||||
date_indexed TEXT NOT NULL,
|
||||
storage_device_id STRING,
|
||||
capture_device_id STRING,
|
||||
parent_file_id STRING
|
||||
);
|
|
@ -1 +1,2 @@
|
|||
pub mod connection;
|
||||
// pub mod migrate;
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
use crate::crypto;
|
||||
use crate::db;
|
||||
use crate::filesystem::checksum;
|
||||
use crate::util::time;
|
||||
use chrono::prelude::*;
|
||||
use chrono::NaiveDateTime;
|
||||
use chrono::{NaiveDateTime, Utc};
|
||||
use sea_orm::entity::prelude::*;
|
||||
use sea_orm::entity::*;
|
||||
use sea_orm::InsertResult;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::ffi::OsStr;
|
||||
use std::fs;
|
||||
|
@ -13,38 +15,37 @@ use std::path;
|
|||
// -------------------------------------
|
||||
// Entity: File
|
||||
// Represents an item discovered on the filesystem
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Serialize, Deserialize)]
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, DeriveEntityModel)]
|
||||
#[sea_orm(table_name = "files")]
|
||||
// -------------------------------------
|
||||
pub struct Model {
|
||||
// identity
|
||||
#[sea_orm(primary_key)]
|
||||
pub id: u64,
|
||||
pub id: u32,
|
||||
pub buffer_checksum: String,
|
||||
pub meta_checksum: String,
|
||||
pub uri: String,
|
||||
// metadata
|
||||
pub name: String,
|
||||
pub extension: String,
|
||||
pub size_in_bytes: u64,
|
||||
pub size_in_bytes: String,
|
||||
// pub encryption: crypto::Encryption,
|
||||
#[sea_orm(nullable)]
|
||||
pub ipfs_id: Option<String>,
|
||||
// ownership
|
||||
#[sea_orm(nullable)]
|
||||
pub user_id: Option<u64>,
|
||||
pub storage_device_id: Option<u32>,
|
||||
#[sea_orm(nullable)]
|
||||
pub storage_device_id: Option<u64>,
|
||||
pub capture_device_id: Option<u32>,
|
||||
#[sea_orm(nullable)]
|
||||
pub capture_device_id: Option<u64>,
|
||||
#[sea_orm(nullable)]
|
||||
pub parent_file_id: Option<u64>,
|
||||
pub parent_file_id: Option<u32>,
|
||||
// date
|
||||
pub date_created: NaiveDateTime,
|
||||
pub date_modified: NaiveDateTime,
|
||||
pub date_indexed: NaiveDateTime,
|
||||
}
|
||||
pub type File = Model;
|
||||
|
||||
pub type File = ActiveModel;
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||
pub enum Relation {}
|
||||
|
@ -53,39 +54,35 @@ impl ActiveModelBehavior for ActiveModel {}
|
|||
|
||||
// Read a file from path returning the File struct
|
||||
// Generates meta checksum and extracts metadata
|
||||
// pub async fn read_file(path: &str) -> io::Result<File> {
|
||||
// let path_buff = path::PathBuf::from(path);
|
||||
// let metadata = fs::metadata(&path)?;
|
||||
pub async fn read_file(path: &str) -> io::Result<File> {
|
||||
let db = db::connection::get_connection().await.unwrap();
|
||||
|
||||
// if metadata.is_dir() {
|
||||
// // return Err();
|
||||
// }
|
||||
let path_buff = path::PathBuf::from(path);
|
||||
let metadata = fs::metadata(&path)?;
|
||||
|
||||
// let size = metadata.len();
|
||||
// let meta_checksum = checksum::create_meta_hash(path.to_owned(), size)?;
|
||||
if metadata.is_dir() {
|
||||
// return Err();
|
||||
}
|
||||
|
||||
// // assemble File struct with initial values
|
||||
// let file = File {
|
||||
// name: extract_name(path_buff.file_name()),
|
||||
// extension: extract_name(path_buff.extension()),
|
||||
// uri: path.to_owned(),
|
||||
// size_in_bytes: size,
|
||||
// date_created: time::system_time_to_date_time(metadata.created()).unwrap_or(Utc::now()),
|
||||
// date_modified: time::system_time_to_date_time(metadata.created()).unwrap_or(Utc::now()),
|
||||
// date_indexed: Utc::now(),
|
||||
// encryption: crypto::Encryption::NONE,
|
||||
// // this will be populated later, either by the database or other functions
|
||||
// id: None,
|
||||
// meta_checksum,
|
||||
// buffer_checksum: None,
|
||||
// ipfs_id: None,
|
||||
// user_id: None,
|
||||
// storage_device_id: None,
|
||||
// capture_device_id: None,
|
||||
// parent_file_id: None,
|
||||
// };
|
||||
// Ok(file)
|
||||
// }
|
||||
let size = metadata.len();
|
||||
let meta_checksum = checksum::create_meta_hash(path.to_owned(), size)?;
|
||||
|
||||
let file = File {
|
||||
meta_checksum: Set(meta_checksum),
|
||||
name: Set(extract_name(path_buff.file_name())),
|
||||
extension: Set(extract_name(path_buff.extension())),
|
||||
uri: Set(path.to_owned()),
|
||||
size_in_bytes: Set(format!("{}", size)),
|
||||
date_created: Set(time::system_time_to_date_time(metadata.created()).unwrap()),
|
||||
date_modified: Set(time::system_time_to_date_time(metadata.modified()).unwrap()),
|
||||
date_indexed: Set(time::system_time_to_date_time(metadata.modified()).unwrap()),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let res = file.insert(&db).await.unwrap();
|
||||
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
// extract name from OsStr returned by PathBuff
|
||||
fn extract_name(os_string: Option<&OsStr>) -> String {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
)]
|
||||
|
||||
mod app;
|
||||
// mod commands;
|
||||
mod commands;
|
||||
mod crypto;
|
||||
mod db;
|
||||
mod filesystem;
|
||||
|
@ -13,15 +13,12 @@ use crate::app::menu;
|
|||
use futures::executor::block_on;
|
||||
|
||||
fn main() {
|
||||
let connection = db::connection::get_connection();
|
||||
let connection = db::connection::create_primary_db();
|
||||
let primary_db = block_on(connection).unwrap();
|
||||
// db::migrate::run_migrations(connection);
|
||||
|
||||
println!("primary database connected {:?}", primary_db);
|
||||
|
||||
tauri::Builder::default()
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
// commands::read_file_command,
|
||||
commands::read_file_command,
|
||||
// commands::generate_buffer_checksum
|
||||
])
|
||||
.menu(menu::get_menu())
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
use chrono::{offset::TimeZone, DateTime, NaiveDateTime, Utc};
|
||||
use chrono::NaiveDateTime;
|
||||
use std::io;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
pub fn system_time_to_date_time(
|
||||
system_time: io::Result<SystemTime>,
|
||||
) -> Result<DateTime<Utc>, Box<dyn std::error::Error>> {
|
||||
) -> Result<NaiveDateTime, Box<dyn std::error::Error>> {
|
||||
// extract system time or resort to current time if failure
|
||||
let system_time = system_time.unwrap_or(SystemTime::now());
|
||||
let std_duration = system_time.duration_since(UNIX_EPOCH)?;
|
||||
let chrono_duration = chrono::Duration::from_std(std_duration)?;
|
||||
let unix = NaiveDateTime::from_timestamp(0, 0);
|
||||
let naive = unix + chrono_duration;
|
||||
let date_time: DateTime<Utc> = Utc.from_local_datetime(&naive).unwrap();
|
||||
Ok(date_time)
|
||||
// let date_time: DateTime<Utc> = Utc.from_local_datetime(&naive).unwrap();
|
||||
Ok(naive)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue