|
|
|
@ -1,4 +1,5 @@
|
|
|
|
|
use mediarepo_core::error::RepoResult;
|
|
|
|
|
use mediarepo_core::file_hash_store::FileHashStore;
|
|
|
|
|
use mediarepo_database::entities::storage;
|
|
|
|
|
use mediarepo_database::entities::storage::ActiveModel as ActiveStorage;
|
|
|
|
|
use mediarepo_database::entities::storage::Model as StorageModel;
|
|
|
|
@ -6,15 +7,22 @@ use sea_orm::prelude::*;
|
|
|
|
|
use sea_orm::{DatabaseConnection, Set, Unset};
|
|
|
|
|
use std::path::PathBuf;
|
|
|
|
|
use tokio::fs;
|
|
|
|
|
use tokio::io::{AsyncRead, BufReader};
|
|
|
|
|
|
|
|
|
|
pub struct Storage {
|
|
|
|
|
db: DatabaseConnection,
|
|
|
|
|
model: StorageModel,
|
|
|
|
|
store: FileHashStore,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Storage {
|
|
|
|
|
fn new(db: DatabaseConnection, model: StorageModel) -> Self {
|
|
|
|
|
Self { db, model }
|
|
|
|
|
let path = PathBuf::from(&model.path);
|
|
|
|
|
Self {
|
|
|
|
|
store: FileHashStore::new(path),
|
|
|
|
|
db,
|
|
|
|
|
model,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Returns the storage by id
|
|
|
|
@ -27,6 +35,7 @@ impl Storage {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Returns the storage by path
|
|
|
|
|
pub async fn by_path<S: ToString>(db: DatabaseConnection, path: S) -> RepoResult<Option<Self>> {
|
|
|
|
|
if let Some(model) = storage::Entity::find()
|
|
|
|
|
.filter(storage::Column::Path.eq(path.to_string()))
|
|
|
|
@ -110,6 +119,21 @@ impl Storage {
|
|
|
|
|
path.exists()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Adds a file to the store
|
|
|
|
|
pub async fn add_file<R: AsyncRead + Unpin>(&self, reader: R) -> RepoResult<String> {
|
|
|
|
|
self.store.add_file(reader, None).await
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Returns the buf reader to the given hash
|
|
|
|
|
pub async fn get_file_reader<S: ToString>(
|
|
|
|
|
&self,
|
|
|
|
|
hash: S,
|
|
|
|
|
) -> RepoResult<BufReader<tokio::fs::File>> {
|
|
|
|
|
let (_ext, reader) = self.store.get_file(hash.to_string()).await?;
|
|
|
|
|
|
|
|
|
|
Ok(reader)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Returns the active model with only the ID filled so saves always perform an update
|
|
|
|
|
fn get_active_model(&self) -> ActiveStorage {
|
|
|
|
|
ActiveStorage {
|
|
|
|
|