163 lines
5.0 KiB
Rust
163 lines
5.0 KiB
Rust
use crate::model_ext::{
|
|
AliasColumnExt, AliasSourceExt, AliasSuffixExt, CursorPaginationExt, EntityPrefixExt, MagIden,
|
|
ModelPagination, SelectColumnsExt,
|
|
};
|
|
use crate::note_model::data::NoteData;
|
|
use crate::note_model::{NoteResolveOptions, NoteResolver};
|
|
use crate::user_model::{UserData, UserResolveOptions, UserResolver};
|
|
use crate::{CalckeyDbError, CalckeyModel};
|
|
use chrono::{DateTime, Utc};
|
|
use ck::{access_token, notification, user};
|
|
use ext_calckey_model_migration::{JoinType, SelectStatement};
|
|
use magnetar_sdk::types::SpanFilter;
|
|
use sea_orm::Iden;
|
|
use sea_orm::{DbErr, EntityTrait, FromQueryResult, QueryFilter, QueryResult, QuerySelect};
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct NotificationData {
|
|
pub notification: notification::Model,
|
|
pub access_token: Option<access_token::Model>,
|
|
pub notifier: Option<UserData>,
|
|
pub notification_note: Option<NoteData>,
|
|
}
|
|
|
|
impl FromQueryResult for NotificationData {
|
|
fn from_query_result(res: &QueryResult, prefix: &str) -> Result<Self, DbErr> {
|
|
let prefix = if prefix.is_empty() {
|
|
notification::Entity.base_prefix()
|
|
} else {
|
|
MagIden::alias(prefix)
|
|
};
|
|
|
|
Ok(NotificationData {
|
|
notification: notification::Model::from_query_result(res, &prefix.to_string())?,
|
|
access_token: access_token::Model::from_query_result_optional(
|
|
res,
|
|
&prefix.join_str_as_str(ACCESS_TOKEN),
|
|
)?,
|
|
notification_note: NoteData::from_query_result_optional(
|
|
res,
|
|
&prefix.join_str_as_str(NOTIFICATION_NOTE),
|
|
)?,
|
|
notifier: UserData::from_query_result_optional(res, &prefix.join_str_as_str(NOTIFIER))?,
|
|
})
|
|
}
|
|
}
|
|
|
|
impl ModelPagination for NotificationData {
|
|
fn id(&self) -> &str {
|
|
&self.notification.id
|
|
}
|
|
|
|
fn time(&self) -> DateTime<Utc> {
|
|
self.notification.created_at.into()
|
|
}
|
|
}
|
|
|
|
const NOTIFICATION: &str = "notification.";
|
|
const NOTIFIER: &str = "notifier.";
|
|
const NOTIFICATION_NOTE: &str = "note.";
|
|
const ACCESS_TOKEN: &str = "access_token.";
|
|
|
|
pub struct NotificationResolveOptions {}
|
|
|
|
#[derive(Clone)]
|
|
pub struct NotificationResolver {
|
|
db: CalckeyModel,
|
|
note_resolver: NoteResolver,
|
|
user_resolver: UserResolver,
|
|
}
|
|
|
|
impl NotificationResolver {
|
|
pub(crate) fn new(
|
|
db: CalckeyModel,
|
|
user_resolver: UserResolver,
|
|
note_resolver: NoteResolver,
|
|
) -> Self {
|
|
Self {
|
|
db,
|
|
note_resolver,
|
|
user_resolver,
|
|
}
|
|
}
|
|
|
|
pub fn resolve(
|
|
&self,
|
|
q: &mut SelectStatement,
|
|
notification_tbl: &MagIden,
|
|
note_options: &NoteResolveOptions,
|
|
user_options: &UserResolveOptions,
|
|
note_resolver: &NoteResolver,
|
|
user_resolver: &UserResolver,
|
|
) {
|
|
let notifier_tbl = notification_tbl.join_str(NOTIFIER);
|
|
q.add_aliased_columns::<user::Entity>(¬ifier_tbl);
|
|
q.join_columns(
|
|
JoinType::LeftJoin,
|
|
notification::Relation::User2.with_from_alias(notification_tbl),
|
|
¬ifier_tbl,
|
|
);
|
|
user_resolver.resolve(q, ¬ifier_tbl, &user_options);
|
|
|
|
let token_tbl = notification_tbl.join_str(ACCESS_TOKEN);
|
|
q.add_aliased_columns::<access_token::Entity>(&token_tbl);
|
|
q.join_columns(
|
|
JoinType::LeftJoin,
|
|
notification::Relation::AccessToken.with_from_alias(notification_tbl),
|
|
&token_tbl,
|
|
);
|
|
|
|
let note_tbl = notification_tbl.join_str(NOTIFICATION_NOTE);
|
|
q.join_columns(
|
|
JoinType::LeftJoin,
|
|
notification::Relation::Note.with_from_alias(notification_tbl),
|
|
¬e_tbl,
|
|
);
|
|
note_resolver.attach_note(q, ¬e_tbl, 1, 1, note_options, &self.user_resolver);
|
|
}
|
|
|
|
pub async fn get(
|
|
&self,
|
|
note_options: &NoteResolveOptions,
|
|
user_options: &UserResolveOptions,
|
|
user_id: &str,
|
|
pagination: &SpanFilter,
|
|
prev: &mut Option<SpanFilter>,
|
|
next: &mut Option<SpanFilter>,
|
|
limit: u64,
|
|
) -> Result<Vec<NotificationData>, CalckeyDbError> {
|
|
let notification_tbl = notification::Entity.base_prefix();
|
|
|
|
let mut select = notification::Entity::find();
|
|
|
|
let query = QuerySelect::query(&mut select);
|
|
self.resolve(
|
|
query,
|
|
¬ification_tbl,
|
|
note_options,
|
|
user_options,
|
|
&self.note_resolver,
|
|
&self.user_resolver,
|
|
);
|
|
|
|
let notifications = select
|
|
.filter(
|
|
notification_tbl
|
|
.col(notification::Column::NotifieeId)
|
|
.eq(user_id),
|
|
)
|
|
.get_paginated_model::<NotificationData, _, _>(
|
|
&self.db.0,
|
|
(notification::Column::CreatedAt, notification::Column::Id),
|
|
pagination,
|
|
prev,
|
|
next,
|
|
limit,
|
|
)
|
|
.await?;
|
|
|
|
Ok(notifications)
|
|
}
|
|
}
|