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 hash;
|
||||
pub mod hash_source;
|
||||
pub mod hash_tag;
|
||||
pub mod namespace;
|
||||
pub mod source;
|
||||
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