Add thumbnail model to model subcrate
Signed-off-by: trivernis <trivernis@protonmail.com>pull/4/head
parent
fd092e8f3e
commit
13f3b39f8b
@ -0,0 +1,7 @@
|
|||||||
|
use async_trait::async_trait;
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
pub trait AsyncTryFrom<T> {
|
||||||
|
type Error;
|
||||||
|
fn async_try_from(other: T) -> Result<Self, Self::Error>;
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
-- Add migration script here
|
||||||
|
CREATE TABLE thumbnails (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
hash_id INTEGER UNIQUE NOT NULL,
|
||||||
|
storage_id INTEGER NOT NULL,
|
||||||
|
file_id INTEGER NOT NULL,
|
||||||
|
height INTEGER NOT NULL,
|
||||||
|
width INTEGER NOT NULL,
|
||||||
|
FOREIGN KEY (hash_id) REFERENCES hashes (id),
|
||||||
|
FOREIGN KEY (storage_id) REFERENCES storage_locations (id),
|
||||||
|
FOREIGN KEY (file_id) REFERENCES files (id)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE UNIQUE INDEX thumbnail_file_resolution ON thumbnails (file_id, height, width);
|
@ -1,8 +1,9 @@
|
|||||||
pub mod tag;
|
|
||||||
pub mod namespace;
|
|
||||||
pub mod hash;
|
|
||||||
pub mod source;
|
|
||||||
pub mod file;
|
pub mod file;
|
||||||
|
pub mod hash;
|
||||||
|
pub mod hash_source;
|
||||||
pub mod hash_tag;
|
pub mod hash_tag;
|
||||||
|
pub mod namespace;
|
||||||
|
pub mod source;
|
||||||
pub mod storage;
|
pub mod storage;
|
||||||
pub mod hash_source;
|
pub mod tag;
|
||||||
|
pub mod thumbnail;
|
||||||
|
@ -0,0 +1,57 @@
|
|||||||
|
use sea_orm::prelude::*;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
|
||||||
|
#[sea_orm(table_name = "thumbnails")]
|
||||||
|
pub struct Model {
|
||||||
|
#[sea_orm(primary_key)]
|
||||||
|
pub id: i64,
|
||||||
|
pub file_id: i64,
|
||||||
|
pub storage_id: i64,
|
||||||
|
pub hash_id: i64,
|
||||||
|
pub height: i32,
|
||||||
|
pub width: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
pub enum Relation {
|
||||||
|
#[sea_orm(
|
||||||
|
belongs_to = "super::file::Entity",
|
||||||
|
from = "Column::FileId",
|
||||||
|
to = "super::file::Column::Id"
|
||||||
|
)]
|
||||||
|
File,
|
||||||
|
|
||||||
|
#[sea_orm(
|
||||||
|
belongs_to = "super::hash::Entity",
|
||||||
|
from = "Column::HashId",
|
||||||
|
to = "super::hash::Column::Id"
|
||||||
|
)]
|
||||||
|
Hash,
|
||||||
|
|
||||||
|
#[sea_orm(
|
||||||
|
belongs_to = "super::storage::Entity",
|
||||||
|
from = "Column::StorageId",
|
||||||
|
to = "super::storage::Column::Id"
|
||||||
|
)]
|
||||||
|
Storage,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::hash::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::Hash.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::file::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::File.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::storage::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::Storage.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
@ -0,0 +1,72 @@
|
|||||||
|
use crate::storage::Storage;
|
||||||
|
use mediarepo_core::error::RepoResult;
|
||||||
|
use mediarepo_database::entities::hash;
|
||||||
|
use mediarepo_database::entities::thumbnail;
|
||||||
|
use sea_orm::prelude::*;
|
||||||
|
use sea_orm::DatabaseConnection;
|
||||||
|
|
||||||
|
pub struct Thumbnail {
|
||||||
|
db: DatabaseConnection,
|
||||||
|
model: thumbnail::Model,
|
||||||
|
hash: hash::Model,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Thumbnail {
|
||||||
|
pub(crate) fn new(db: DatabaseConnection, model: thumbnail::Model, hash: hash::Model) -> Self {
|
||||||
|
Self { db, model, hash }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the thumbnail by id
|
||||||
|
pub async fn by_id(db: DatabaseConnection, id: i64) -> RepoResult<Option<Self>> {
|
||||||
|
let model: Option<(thumbnail::Model, Option<hash::Model>)> =
|
||||||
|
thumbnail::Entity::find_by_id(id)
|
||||||
|
.find_also_related(hash::Entity)
|
||||||
|
.one(&db)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
if let Some((model, Some(hash))) = model {
|
||||||
|
Ok(Some(Self::new(db, model, hash)))
|
||||||
|
} else {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns all thumbnails for a given file
|
||||||
|
pub async fn for_file_id(db: DatabaseConnection, file_id: i64) -> RepoResult<Vec<Self>> {
|
||||||
|
let thumb_models: Vec<(thumbnail::Model, Option<hash::Model>)> = thumbnail::Entity::find()
|
||||||
|
.filter(thumbnail::Column::FileId.eq(file_id))
|
||||||
|
.find_also_related(hash::Entity)
|
||||||
|
.all(&db)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(thumb_models
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|(m, h)| Some(Self::new(db.clone(), m, h?)))
|
||||||
|
.collect())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn id(&self) -> i64 {
|
||||||
|
self.model.id
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn hash(&self) -> &String {
|
||||||
|
&self.hash.value
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn height(&self) -> i32 {
|
||||||
|
self.model.height
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn width(&self) -> i32 {
|
||||||
|
self.model.width
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the storage for the thumbnail
|
||||||
|
pub async fn storage(&self) -> RepoResult<Storage> {
|
||||||
|
let storage = Storage::by_id(self.db.clone(), self.model.storage_id)
|
||||||
|
.await?
|
||||||
|
.expect("The FK storage_id doesn't exist?!");
|
||||||
|
|
||||||
|
Ok(storage)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue