Add functions to write and retrieve file contents

Signed-off-by: trivernis <trivernis@protonmail.com>
pull/4/head
trivernis 3 years ago
parent 0f90ad8984
commit a2c6e4cdf1

@ -5,11 +5,16 @@ use sea_orm::prelude::*;
pub struct Model {
#[sea_orm(primary_key)]
pub id: u64,
pub value: String
pub value: String,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
pub enum Relation {}
impl Related<super::file::Entity> for Entity {
fn to() -> RelationDef {
super::file::Relation::Hash.def().rev()
}
}
impl Related<super::tag::Entity> for Entity {
@ -32,4 +37,4 @@ impl Related<super::source::Entity> for Entity {
}
}
impl ActiveModelBehavior for ActiveModel {}
impl ActiveModelBehavior for ActiveModel {}

@ -9,6 +9,7 @@ use mediarepo_database::entities::hash;
use mediarepo_database::entities::hash::Model as HashModel;
use sea_orm::prelude::*;
use sea_orm::{DatabaseConnection, Set};
use tokio::io::BufReader;
pub struct File {
db: DatabaseConnection,
@ -35,6 +36,24 @@ impl File {
}
}
/// Finds the file by hash
pub async fn by_hash<S: AsRef<str>>(
db: DatabaseConnection,
hash: S,
) -> RepoResult<Option<Self>> {
if let Some((hash, Some(model))) = hash::Entity::find()
.filter(hash::Column::Value.eq(hash.as_ref()))
.find_also_related(file::Entity)
.one(&db)
.await?
{
let file = File::new(db, model, hash);
Ok(Some(file))
} else {
Ok(None)
}
}
/// Returns the unique identifier of the file
pub fn id(&self) -> u64 {
self.model.id
@ -119,6 +138,13 @@ impl File {
Ok(())
}
/// Returns the reader for the file
pub async fn get_reader(&self) -> RepoResult<BufReader<tokio::fs::File>> {
let storage = self.storage().await?;
storage.get_file_reader(&self.hash.value).await
}
/// Returns the active model of the file with only the id set
fn get_active_model(&self) -> ActiveFile {
ActiveFile {

@ -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 {

Loading…
Cancel
Save