Refactored aliases
ci/woodpecker/push/ociImagePush Pipeline is running
Details
ci/woodpecker/push/ociImagePush Pipeline is running
Details
This commit is contained in:
parent
3b1eab8069
commit
a658452138
|
@ -15,11 +15,10 @@ use chrono::Utc;
|
||||||
use ext_calckey_model_migration::{Migrator, MigratorTrait};
|
use ext_calckey_model_migration::{Migrator, MigratorTrait};
|
||||||
use futures_util::StreamExt;
|
use futures_util::StreamExt;
|
||||||
use redis::IntoConnectionInfo;
|
use redis::IntoConnectionInfo;
|
||||||
use sea_orm::sea_query::IntoIden;
|
|
||||||
use sea_orm::ActiveValue::Set;
|
use sea_orm::ActiveValue::Set;
|
||||||
use sea_orm::{
|
use sea_orm::{
|
||||||
ColumnTrait, ConnectOptions, DatabaseConnection, DbErr, EntityTrait, QueryFilter, RelationDef,
|
ColumnTrait, ConnectOptions, DatabaseConnection, DbErr, EntityTrait, QueryFilter,
|
||||||
RelationTrait, TransactionTrait,
|
TransactionTrait,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
|
@ -44,18 +43,6 @@ pub enum CalckeyDbError {
|
||||||
DbError(#[from] DbErr),
|
DbError(#[from] DbErr),
|
||||||
}
|
}
|
||||||
|
|
||||||
trait AliasSourceExt {
|
|
||||||
fn with_alias<I: IntoIden>(&self, alias: I) -> RelationDef;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: RelationTrait> AliasSourceExt for T {
|
|
||||||
fn with_alias<I: IntoIden>(&self, alias: I) -> RelationDef {
|
|
||||||
let mut def = self.def();
|
|
||||||
def.from_tbl = def.from_tbl.alias(alias);
|
|
||||||
def
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CalckeyModel {
|
impl CalckeyModel {
|
||||||
pub async fn new(config: ConnectorConfig) -> Result<Self, CalckeyDbError> {
|
pub async fn new(config: ConnectorConfig) -> Result<Self, CalckeyDbError> {
|
||||||
let opt = ConnectOptions::new(config.url)
|
let opt = ConnectOptions::new(config.url)
|
||||||
|
|
|
@ -1,21 +1,70 @@
|
||||||
use ext_calckey_model_migration::{Alias, Expr, IntoIden, SelectExpr, SelectStatement, TableRef};
|
use ext_calckey_model_migration::{
|
||||||
use sea_orm::{ColumnTrait, Condition, EntityTrait, Iden, Iterable, JoinType, RelationDef};
|
Alias, Expr, IntoIden, Quote, SelectExpr, SelectStatement, TableRef,
|
||||||
|
};
|
||||||
|
use sea_orm::{
|
||||||
|
ColumnTrait, Condition, DynIden, EntityTrait, Iden, Iterable, JoinType, RelationDef,
|
||||||
|
RelationTrait,
|
||||||
|
};
|
||||||
|
use std::fmt::Write;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub enum MagIden {
|
||||||
|
DynIden(DynIden),
|
||||||
|
Alias(Alias),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MagIden {
|
||||||
|
pub fn alias(alias: &str) -> MagIden {
|
||||||
|
Self::Alias(Alias::new(alias))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<DynIden> for MagIden {
|
||||||
|
fn from(value: DynIden) -> Self {
|
||||||
|
Self::DynIden(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Iden for MagIden {
|
||||||
|
fn prepare(&self, s: &mut dyn Write, q: Quote) {
|
||||||
|
match self {
|
||||||
|
MagIden::DynIden(di) => di.prepare(s, q),
|
||||||
|
MagIden::Alias(a) => a.prepare(s, q),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn quoted(&self, q: Quote) -> String {
|
||||||
|
match self {
|
||||||
|
MagIden::DynIden(di) => di.quoted(q),
|
||||||
|
MagIden::Alias(a) => a.quoted(q),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_string(&self) -> String {
|
||||||
|
match self {
|
||||||
|
MagIden::DynIden(di) => di.to_string(),
|
||||||
|
MagIden::Alias(a) => a.to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unquoted(&self, s: &mut dyn Write) {
|
||||||
|
match self {
|
||||||
|
MagIden::DynIden(di) => di.unquoted(s),
|
||||||
|
MagIden::Alias(a) => a.unquoted(s),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) trait SelectColumnsExt {
|
pub(crate) trait SelectColumnsExt {
|
||||||
fn add_aliased_columns<T: EntityTrait>(&mut self, alias: &str) -> &mut Self;
|
fn add_aliased_columns<T: EntityTrait>(&mut self, alias: &MagIden) -> &mut Self;
|
||||||
|
|
||||||
fn join_columns<I: IntoIden>(
|
fn join_columns(&mut self, join: JoinType, rel: RelationDef, alias: &MagIden) -> &mut Self;
|
||||||
|
|
||||||
|
fn join_columns_on(
|
||||||
&mut self,
|
&mut self,
|
||||||
join: JoinType,
|
join: JoinType,
|
||||||
rel: RelationDef,
|
rel: RelationDef,
|
||||||
alias: I,
|
alias: &MagIden,
|
||||||
) -> &mut Self;
|
|
||||||
|
|
||||||
fn join_columns_on<I: IntoIden>(
|
|
||||||
&mut self,
|
|
||||||
join: JoinType,
|
|
||||||
rel: RelationDef,
|
|
||||||
alias: I,
|
|
||||||
condition: Condition,
|
condition: Condition,
|
||||||
) -> &mut Self;
|
) -> &mut Self;
|
||||||
}
|
}
|
||||||
|
@ -41,17 +90,15 @@ pub(crate) fn join_columns_default(rel: RelationDef) -> Condition {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SelectColumnsExt for SelectStatement {
|
impl SelectColumnsExt for SelectStatement {
|
||||||
fn add_aliased_columns<T: EntityTrait>(&mut self, iden: &str) -> &mut Self {
|
fn add_aliased_columns<T: EntityTrait>(&mut self, iden: &MagIden) -> &mut Self {
|
||||||
for col in T::Column::iter() {
|
for col in T::Column::iter() {
|
||||||
let column: &T::Column = &col;
|
let column: &T::Column = &col;
|
||||||
|
let alias = iden.join(&col);
|
||||||
let alias = format!("{}{}", iden, col.to_string());
|
let column_ref = iden.col(column.as_column_ref().1);
|
||||||
|
|
||||||
let column_ref = Expr::col((Alias::new(iden), column.as_column_ref().1));
|
|
||||||
|
|
||||||
self.expr(SelectExpr {
|
self.expr(SelectExpr {
|
||||||
expr: col.select_as(column_ref),
|
expr: col.select_as(column_ref),
|
||||||
alias: Some(Alias::new(&alias).into_iden()),
|
alias: Some(alias.into_iden()),
|
||||||
window: None,
|
window: None,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -59,48 +106,66 @@ impl SelectColumnsExt for SelectStatement {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn join_columns<I: IntoIden>(
|
fn join_columns(&mut self, join: JoinType, mut rel: RelationDef, alias: &MagIden) -> &mut Self {
|
||||||
&mut self,
|
rel.to_tbl = rel.to_tbl.alias(alias.clone().into_iden());
|
||||||
join: JoinType,
|
|
||||||
mut rel: RelationDef,
|
|
||||||
alias: I,
|
|
||||||
) -> &mut Self {
|
|
||||||
let alias = alias.into_iden();
|
|
||||||
rel.to_tbl = rel.to_tbl.alias(alias);
|
|
||||||
self.join(join, rel.to_tbl.clone(), join_columns_default(rel));
|
self.join(join, rel.to_tbl.clone(), join_columns_default(rel));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn join_columns_on<I: IntoIden>(
|
fn join_columns_on(
|
||||||
&mut self,
|
&mut self,
|
||||||
join: JoinType,
|
join: JoinType,
|
||||||
mut rel: RelationDef,
|
mut rel: RelationDef,
|
||||||
alias: I,
|
alias: &MagIden,
|
||||||
condition: Condition,
|
condition: Condition,
|
||||||
) -> &mut Self {
|
) -> &mut Self {
|
||||||
let alias = alias.into_iden();
|
rel.to_tbl = rel.to_tbl.alias(alias.clone().into_iden());
|
||||||
rel.to_tbl = rel.to_tbl.alias(alias);
|
|
||||||
self.join(join, rel.to_tbl.clone(), condition);
|
self.join(join, rel.to_tbl.clone(), condition);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn joined_prefix_str(prefix: &str, suffix: &str) -> String {
|
pub trait AliasColumnExt {
|
||||||
format!("{prefix}{suffix}")
|
fn col(&self, col: impl IntoIden) -> Expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn joined_prefix_alias(prefix: &str, suffix: &str) -> Alias {
|
impl<T: Iden + ?Sized> AliasColumnExt for T {
|
||||||
Alias::new(joined_prefix_str(prefix, suffix))
|
fn col(&self, col: impl IntoIden) -> Expr {
|
||||||
|
Expr::col((Alias::new(self.to_string()).into_iden(), col.into_iden()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn joined_prefix(prefix: &str, suffix: &str) -> impl IntoIden {
|
pub trait AliasSuffixExt {
|
||||||
joined_prefix_alias(prefix, suffix).into_iden()
|
fn join(&self, suffix: &dyn Iden) -> MagIden;
|
||||||
|
|
||||||
|
fn join_str(&self, suffix: &str) -> MagIden;
|
||||||
|
|
||||||
|
fn join_as_str(&self, suffix: &dyn Iden) -> String;
|
||||||
|
|
||||||
|
fn join_str_as_str(&self, suffix: &str) -> String;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Iden + ?Sized> AliasSuffixExt for T {
|
||||||
|
fn join(&self, suffix: &dyn Iden) -> MagIden {
|
||||||
|
MagIden::alias(&self.join_as_str(suffix))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn join_str(&self, suffix: &str) -> MagIden {
|
||||||
|
MagIden::alias(&self.join_str_as_str(suffix))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn join_as_str(&self, suffix: &dyn Iden) -> String {
|
||||||
|
format!("{}{}", self.to_string(), suffix.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn join_str_as_str(&self, suffix: &str) -> String {
|
||||||
|
format!("{}{}", self.to_string(), suffix)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) trait EntityPrefixExt {
|
pub(crate) trait EntityPrefixExt {
|
||||||
fn base_prefix_str(&self) -> String;
|
fn base_prefix_str(&self) -> String;
|
||||||
fn base_prefix_alias(&self) -> Alias;
|
fn base_prefix(&self) -> MagIden;
|
||||||
fn base_prefix(&self) -> impl IntoIden;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: EntityTrait> EntityPrefixExt for T {
|
impl<T: EntityTrait> EntityPrefixExt for T {
|
||||||
|
@ -108,11 +173,28 @@ impl<T: EntityTrait> EntityPrefixExt for T {
|
||||||
format!("{}.", self.table_name())
|
format!("{}.", self.table_name())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn base_prefix_alias(&self) -> Alias {
|
fn base_prefix(&self) -> MagIden {
|
||||||
Alias::new(self.base_prefix_str())
|
MagIden::alias(&self.base_prefix_str())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
fn base_prefix(&self) -> impl IntoIden {
|
|
||||||
self.base_prefix_alias().into_iden()
|
pub trait AliasSourceExt {
|
||||||
|
fn with_from_alias(&self, alias: &MagIden) -> RelationDef;
|
||||||
|
|
||||||
|
fn with_alias(&self, from: &MagIden, to: &MagIden) -> RelationDef;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: RelationTrait> AliasSourceExt for T {
|
||||||
|
fn with_from_alias(&self, alias: &MagIden) -> RelationDef {
|
||||||
|
let mut def = self.def();
|
||||||
|
def.from_tbl = def.from_tbl.alias(Alias::new(alias.clone().to_string()));
|
||||||
|
def
|
||||||
|
}
|
||||||
|
|
||||||
|
fn with_alias(&self, from: &MagIden, to: &MagIden) -> RelationDef {
|
||||||
|
let mut def = self.def();
|
||||||
|
def.from_tbl = def.from_tbl.alias(from.clone().into_iden());
|
||||||
|
def.to_tbl = def.to_tbl.alias(to.clone().into_iden());
|
||||||
|
def
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
use crate::model_ext::{AliasSuffixExt, EntityPrefixExt, MagIden};
|
||||||
|
use crate::note_model::{INTERACTION_REACTION, INTERACTION_RENOTE, RENOTE, REPLY, USER};
|
||||||
|
use crate::user_model::UserData;
|
||||||
|
use ck::note;
|
||||||
|
use ext_calckey_model_migration::IntoIden;
|
||||||
|
use sea_orm::sea_query::Alias;
|
||||||
|
use sea_orm::Iden;
|
||||||
|
use sea_orm::{DbErr, FromQueryResult, QueryResult};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
pub mod sub_interaction_renote {
|
||||||
|
use sea_orm::{DeriveColumn, EnumIter, FromQueryResult};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, FromQueryResult, Serialize, Deserialize)]
|
||||||
|
pub struct Model {
|
||||||
|
pub renotes: Option<i64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
|
||||||
|
pub enum Column {
|
||||||
|
Renotes,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod sub_interaction_reaction {
|
||||||
|
use sea_orm::{DeriveColumn, EnumIter, FromQueryResult};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, FromQueryResult, Serialize, Deserialize)]
|
||||||
|
pub struct Model {
|
||||||
|
pub reaction_name: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
|
||||||
|
pub enum Column {
|
||||||
|
ReactionName,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct NoteData {
|
||||||
|
pub note: note::Model,
|
||||||
|
pub interaction_user_renote: Option<sub_interaction_renote::Model>,
|
||||||
|
pub interaction_user_reaction: Option<sub_interaction_reaction::Model>,
|
||||||
|
pub user: UserData,
|
||||||
|
pub reply: Option<Box<NoteData>>,
|
||||||
|
pub renote: Option<Box<NoteData>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromQueryResult for NoteData {
|
||||||
|
fn from_query_result(res: &QueryResult, prefix: &str) -> Result<Self, DbErr> {
|
||||||
|
let prefix = if prefix.is_empty() {
|
||||||
|
note::Entity.base_prefix()
|
||||||
|
} else {
|
||||||
|
MagIden::alias(&prefix)
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(NoteData {
|
||||||
|
note: note::Model::from_query_result(res, &prefix.to_string())?,
|
||||||
|
interaction_user_renote: sub_interaction_renote::Model::from_query_result_optional(
|
||||||
|
res,
|
||||||
|
&prefix.join_str_as_str(INTERACTION_RENOTE),
|
||||||
|
)?,
|
||||||
|
interaction_user_reaction: sub_interaction_reaction::Model::from_query_result_optional(
|
||||||
|
res,
|
||||||
|
&prefix.join_str_as_str(INTERACTION_REACTION),
|
||||||
|
)?,
|
||||||
|
user: UserData::from_query_result(res, &prefix.join_str_as_str(USER))?,
|
||||||
|
reply: NoteData::from_query_result_optional(res, &prefix.join_str_as_str(REPLY))?
|
||||||
|
.map(Box::new),
|
||||||
|
renote: NoteData::from_query_result_optional(res, &prefix.join_str_as_str(RENOTE))?
|
||||||
|
.map(Box::new),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,61 +1,23 @@
|
||||||
|
pub mod data;
|
||||||
|
|
||||||
use ext_calckey_model_migration::SelectStatement;
|
use ext_calckey_model_migration::SelectStatement;
|
||||||
use sea_orm::sea_query::{Alias, Asterisk, Expr, IntoIden, Query, SelectExpr, SimpleExpr};
|
use sea_orm::sea_query::{Asterisk, Expr, IntoIden, Query, SelectExpr, SimpleExpr};
|
||||||
use sea_orm::{
|
use sea_orm::{
|
||||||
Condition, DbErr, EntityName, EntityTrait, FromQueryResult, Iden, JoinType, QueryFilter,
|
Condition, CursorTrait, EntityName, EntityTrait, Iden, JoinType, QueryFilter, QueryOrder,
|
||||||
QueryOrder, QueryResult, QuerySelect, QueryTrait, Select,
|
QuerySelect, QueryTrait, Select,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
use ck::{note, note_reaction, user, user_note_pining};
|
use ck::{note, note_reaction, user, user_note_pining};
|
||||||
|
use data::{sub_interaction_reaction, sub_interaction_renote, NoteData};
|
||||||
use magnetar_sdk::types::SpanFilter;
|
use magnetar_sdk::types::SpanFilter;
|
||||||
|
|
||||||
use crate::model_ext::{
|
use crate::model_ext::{
|
||||||
join_columns_default, joined_prefix, joined_prefix_alias, joined_prefix_str, EntityPrefixExt,
|
join_columns_default, AliasColumnExt, AliasSourceExt, AliasSuffixExt, EntityPrefixExt, MagIden,
|
||||||
SelectColumnsExt,
|
SelectColumnsExt,
|
||||||
};
|
};
|
||||||
use crate::paginated::PaginatedModel;
|
use crate::paginated::PaginatedModel;
|
||||||
use crate::user_model::{UserData, UserResolver};
|
use crate::user_model::{UserResolveOptions, UserResolver};
|
||||||
use crate::{AliasSourceExt, CalckeyDbError, CalckeyModel};
|
use crate::{CalckeyDbError, CalckeyModel};
|
||||||
|
|
||||||
pub mod sub_interaction_renote {
|
|
||||||
use sea_orm::{DeriveColumn, EnumIter, FromQueryResult};
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, FromQueryResult, Serialize, Deserialize)]
|
|
||||||
pub struct Model {
|
|
||||||
pub renotes: Option<i64>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
|
|
||||||
pub enum Column {
|
|
||||||
Renotes,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub mod sub_interaction_reaction {
|
|
||||||
use sea_orm::{DeriveColumn, EnumIter, FromQueryResult};
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, FromQueryResult, Serialize, Deserialize)]
|
|
||||||
pub struct Model {
|
|
||||||
pub reaction_name: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
|
|
||||||
pub enum Column {
|
|
||||||
ReactionName,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
||||||
pub struct NoteData {
|
|
||||||
pub note: note::Model,
|
|
||||||
pub interaction_user_renote: Option<sub_interaction_renote::Model>,
|
|
||||||
pub interaction_user_reaction: Option<sub_interaction_reaction::Model>,
|
|
||||||
pub user: UserData,
|
|
||||||
pub reply: Option<Box<NoteData>>,
|
|
||||||
pub renote: Option<Box<NoteData>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
const PIN: &str = "pin.";
|
const PIN: &str = "pin.";
|
||||||
const INTERACTION_REACTION: &str = "interaction.reaction.";
|
const INTERACTION_REACTION: &str = "interaction.reaction.";
|
||||||
|
@ -64,37 +26,13 @@ const USER: &str = "user.";
|
||||||
const REPLY: &str = "reply.";
|
const REPLY: &str = "reply.";
|
||||||
const RENOTE: &str = "renote.";
|
const RENOTE: &str = "renote.";
|
||||||
|
|
||||||
impl FromQueryResult for NoteData {
|
|
||||||
fn from_query_result(res: &QueryResult, prefix: &str) -> Result<Self, DbErr> {
|
|
||||||
let fallback = format!("{}.", note::Entity.table_name());
|
|
||||||
let prefix = if prefix.is_empty() { &fallback } else { prefix };
|
|
||||||
|
|
||||||
Ok(NoteData {
|
|
||||||
note: note::Model::from_query_result(res, prefix)?,
|
|
||||||
interaction_user_renote: sub_interaction_renote::Model::from_query_result_optional(
|
|
||||||
res,
|
|
||||||
&joined_prefix_str(prefix, INTERACTION_RENOTE),
|
|
||||||
)?,
|
|
||||||
interaction_user_reaction: sub_interaction_reaction::Model::from_query_result_optional(
|
|
||||||
res,
|
|
||||||
&joined_prefix_str(prefix, INTERACTION_REACTION),
|
|
||||||
)?,
|
|
||||||
user: UserData::from_query_result(res, &joined_prefix_str(prefix, USER))?,
|
|
||||||
reply: NoteData::from_query_result_optional(res, &joined_prefix_str(prefix, REPLY))?
|
|
||||||
.map(Box::new),
|
|
||||||
renote: NoteData::from_query_result_optional(res, &joined_prefix_str(prefix, RENOTE))?
|
|
||||||
.map(Box::new),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct NoteResolver {
|
pub struct NoteResolver {
|
||||||
db: CalckeyModel,
|
db: CalckeyModel,
|
||||||
user_resolver: UserResolver,
|
user_resolver: UserResolver,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait NoteVisibilityFilterFactory: Send + Sync {
|
pub trait NoteVisibilityFilterFactory: Send + Sync {
|
||||||
fn with_note_and_user_tables(&self, note: Option<Alias>) -> SimpleExpr;
|
fn with_note_and_user_tables(&self, note: &dyn Iden) -> SimpleExpr;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct NoteResolveOptions {
|
pub struct NoteResolveOptions {
|
||||||
|
@ -102,45 +40,39 @@ pub struct NoteResolveOptions {
|
||||||
pub visibility_filter: Box<dyn NoteVisibilityFilterFactory>,
|
pub visibility_filter: Box<dyn NoteVisibilityFilterFactory>,
|
||||||
pub time_range: Option<SpanFilter>,
|
pub time_range: Option<SpanFilter>,
|
||||||
pub limit: Option<u64>,
|
pub limit: Option<u64>,
|
||||||
pub with_user: bool,
|
|
||||||
pub with_reply_target: bool,
|
pub with_reply_target: bool,
|
||||||
pub with_renote_target: bool,
|
pub with_renote_target: bool,
|
||||||
pub with_interactions_from: Option<String>, // User ID
|
pub with_interactions_from: Option<String>, // User ID
|
||||||
pub only_pins_from: Option<String>, // User ID
|
pub only_pins_from: Option<String>, // User ID
|
||||||
|
pub user_options: UserResolveOptions,
|
||||||
}
|
}
|
||||||
|
|
||||||
trait SelectNoteInteractionsExt {
|
trait SelectNoteInteractionsExt {
|
||||||
fn add_sub_select_interaction_reaction(
|
fn add_sub_select_interaction_reaction(
|
||||||
&mut self,
|
&mut self,
|
||||||
source_note_alias: &str,
|
note_tbl: &MagIden,
|
||||||
alias: &str,
|
|
||||||
user_id: &str,
|
user_id: &str,
|
||||||
) -> &mut Self;
|
) -> &mut Self;
|
||||||
|
|
||||||
fn add_sub_select_interaction_renote(
|
fn add_sub_select_interaction_renote(&mut self, note_tbl: &MagIden, user_id: &str)
|
||||||
&mut self,
|
-> &mut Self;
|
||||||
source_note_alias: &str,
|
|
||||||
alias: &str,
|
|
||||||
user_id: &str,
|
|
||||||
) -> &mut Self;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SelectNoteInteractionsExt for SelectStatement {
|
impl SelectNoteInteractionsExt for SelectStatement {
|
||||||
fn add_sub_select_interaction_reaction(
|
fn add_sub_select_interaction_reaction(
|
||||||
&mut self,
|
&mut self,
|
||||||
iden: &str,
|
note_tbl: &MagIden,
|
||||||
prefix_alias: &str,
|
|
||||||
user_id: &str,
|
user_id: &str,
|
||||||
) -> &mut Self {
|
) -> &mut Self {
|
||||||
let note_id_col = Expr::col((Alias::new(iden), note::Column::Id));
|
let note_id_col = note_tbl.col(note::Column::Id);
|
||||||
|
let alias = note_tbl
|
||||||
let column = sub_interaction_reaction::Column::ReactionName;
|
.join_str(INTERACTION_REACTION)
|
||||||
let alias = format!("{}{}", prefix_alias, column.to_string());
|
.join(&sub_interaction_reaction::Column::ReactionName);
|
||||||
|
|
||||||
let sub_query = Query::select()
|
let sub_query = Query::select()
|
||||||
.expr(SelectExpr {
|
.expr(SelectExpr {
|
||||||
expr: Expr::col(note_reaction::Column::Reaction).into(),
|
expr: Expr::col(note_reaction::Column::Reaction).into(),
|
||||||
alias: Some(Alias::new(alias).into_iden()),
|
alias: Some(alias.into_iden()),
|
||||||
window: None,
|
window: None,
|
||||||
})
|
})
|
||||||
.from(note_reaction::Entity)
|
.from(note_reaction::Entity)
|
||||||
|
@ -155,28 +87,26 @@ impl SelectNoteInteractionsExt for SelectStatement {
|
||||||
|
|
||||||
fn add_sub_select_interaction_renote(
|
fn add_sub_select_interaction_renote(
|
||||||
&mut self,
|
&mut self,
|
||||||
iden: &str,
|
note_tbl: &MagIden,
|
||||||
prefix_alias: &str,
|
|
||||||
user_id: &str,
|
user_id: &str,
|
||||||
) -> &mut Self {
|
) -> &mut Self {
|
||||||
let note_id_col = Expr::col((Alias::new(iden), note::Column::Id));
|
let interaction_tbl_prefix = note_tbl.join_str(INTERACTION_RENOTE);
|
||||||
|
let renote_note_tbl = interaction_tbl_prefix.join_str("note");
|
||||||
let renote_note_tbl = joined_prefix_alias(prefix_alias, "note");
|
let alias = interaction_tbl_prefix.join(&sub_interaction_renote::Column::Renotes);
|
||||||
|
|
||||||
let column = sub_interaction_renote::Column::Renotes;
|
|
||||||
let alias = format!("{}{}", prefix_alias, column.to_string());
|
|
||||||
|
|
||||||
let sub_query = Query::select()
|
let sub_query = Query::select()
|
||||||
.expr(SelectExpr {
|
.expr(SelectExpr {
|
||||||
expr: Expr::count(Expr::col(Asterisk)),
|
expr: Expr::count(Expr::col(Asterisk)),
|
||||||
alias: Some(Alias::new(alias).into_iden()),
|
alias: Some(alias.into_iden()),
|
||||||
window: None,
|
window: None,
|
||||||
})
|
})
|
||||||
.from_as(note::Entity, renote_note_tbl.clone())
|
.from_as(note::Entity, renote_note_tbl.clone().into_iden())
|
||||||
.cond_where(
|
.cond_where(
|
||||||
Expr::col((renote_note_tbl.clone(), note::Column::RenoteId)).eq(note_id_col),
|
renote_note_tbl
|
||||||
|
.col(note::Column::RenoteId)
|
||||||
|
.eq(note_tbl.col(note::Column::Id)),
|
||||||
)
|
)
|
||||||
.and_where(Expr::col((renote_note_tbl.clone(), note::Column::UserId)).eq(user_id))
|
.and_where(renote_note_tbl.col(note::Column::UserId).eq(user_id))
|
||||||
.take()
|
.take()
|
||||||
.into_sub_query_statement();
|
.into_sub_query_statement();
|
||||||
|
|
||||||
|
@ -186,7 +116,7 @@ impl SelectNoteInteractionsExt for SelectStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ids_into_expr(ids: &Vec<String>) -> SimpleExpr {
|
fn ids_into_expr(ids: &Vec<String>) -> SimpleExpr {
|
||||||
let id_col = Expr::col((note::Entity.base_prefix(), note::Column::Id));
|
let id_col = note::Entity.base_prefix().col(note::Column::Id);
|
||||||
|
|
||||||
if ids.len() == 1 {
|
if ids.len() == 1 {
|
||||||
id_col.eq(&ids[0])
|
id_col.eq(&ids[0])
|
||||||
|
@ -207,11 +137,11 @@ impl NoteResolver {
|
||||||
let select = self.resolve(options);
|
let select = self.resolve(options);
|
||||||
let visibility_filter = options
|
let visibility_filter = options
|
||||||
.visibility_filter
|
.visibility_filter
|
||||||
.with_note_and_user_tables(Some(note::Entity.base_prefix_alias()));
|
.with_note_and_user_tables(¬e::Entity.base_prefix());
|
||||||
let time_filter = options
|
let time_filter = options
|
||||||
.time_range
|
.time_range
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(note::Model::range_into_expr);
|
.and_then(note::Entity::range_into_expr);
|
||||||
let id_filter = options.ids.as_ref().map(ids_into_expr);
|
let id_filter = options.ids.as_ref().map(ids_into_expr);
|
||||||
|
|
||||||
let notes = select
|
let notes = select
|
||||||
|
@ -232,11 +162,11 @@ impl NoteResolver {
|
||||||
let select = self.resolve(options);
|
let select = self.resolve(options);
|
||||||
let visibility_filter = options
|
let visibility_filter = options
|
||||||
.visibility_filter
|
.visibility_filter
|
||||||
.with_note_and_user_tables(Some(note::Entity.base_prefix_alias()));
|
.with_note_and_user_tables(¬e::Entity.base_prefix());
|
||||||
let time_filter = options
|
let time_filter = options
|
||||||
.time_range
|
.time_range
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(note::Model::range_into_expr);
|
.and_then(note::Entity::range_into_expr);
|
||||||
let id_filter = options.ids.as_ref().map(ids_into_expr);
|
let id_filter = options.ids.as_ref().map(ids_into_expr);
|
||||||
|
|
||||||
let notes = select
|
let notes = select
|
||||||
|
@ -245,7 +175,7 @@ impl NoteResolver {
|
||||||
.apply_if(time_filter, Select::<note::Entity>::filter)
|
.apply_if(time_filter, Select::<note::Entity>::filter)
|
||||||
.apply_if(options.only_pins_from.as_deref(), |s, _| {
|
.apply_if(options.only_pins_from.as_deref(), |s, _| {
|
||||||
s.order_by_desc(Expr::col((
|
s.order_by_desc(Expr::col((
|
||||||
joined_prefix(¬e::Entity.base_prefix_str(), PIN),
|
note::Entity.base_prefix().into_iden().join_str(PIN),
|
||||||
user_note_pining::Column::CreatedAt,
|
user_note_pining::Column::CreatedAt,
|
||||||
)))
|
)))
|
||||||
})
|
})
|
||||||
|
@ -257,59 +187,70 @@ impl NoteResolver {
|
||||||
Ok(notes)
|
Ok(notes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
pub async fn get_children(&self, options: &NoteResolveOptions) -> Select<note::Entity> {
|
||||||
|
let max_breadth: usize = 10;
|
||||||
|
|
||||||
|
let nth_child = Alias::new("nth_child");
|
||||||
|
|
||||||
|
let mut select = Query::select();
|
||||||
|
select.distinct();
|
||||||
|
select.columns([Alias::new("id")]);
|
||||||
|
select.from(cte);
|
||||||
|
select.and_where(Expr::col(nth_child).lt(max_breadth))
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
fn attach_note(
|
fn attach_note(
|
||||||
&self,
|
&self,
|
||||||
q: &mut SelectStatement,
|
q: &mut SelectStatement,
|
||||||
prefix: &str,
|
note_tbl: &MagIden,
|
||||||
reply_depth: usize,
|
reply_depth: usize,
|
||||||
renote_depth: usize,
|
renote_depth: usize,
|
||||||
options: &NoteResolveOptions,
|
options: &NoteResolveOptions,
|
||||||
user_resolver: &UserResolver,
|
user_resolver: &UserResolver,
|
||||||
) {
|
) {
|
||||||
q.add_aliased_columns::<note::Entity>(prefix);
|
q.add_aliased_columns::<note::Entity>(note_tbl);
|
||||||
|
|
||||||
// Add the note's author
|
// Add the note's author
|
||||||
q.add_aliased_columns::<user::Entity>(&joined_prefix_str(prefix, USER));
|
let user_tbl = note_tbl.join_str(USER);
|
||||||
|
q.add_aliased_columns::<user::Entity>(&user_tbl);
|
||||||
q.join_columns(
|
q.join_columns(
|
||||||
JoinType::LeftJoin,
|
JoinType::LeftJoin,
|
||||||
note::Relation::User.with_alias(Alias::new(prefix).into_iden()),
|
note::Relation::User.with_from_alias(note_tbl),
|
||||||
joined_prefix(prefix, USER),
|
&user_tbl,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// user_resolver.resolve(q, &user_tbl, &options.user_options);
|
||||||
|
|
||||||
// Interactions like renotes or reactions from the specified user
|
// Interactions like renotes or reactions from the specified user
|
||||||
if let Some(user_id) = &options.with_interactions_from {
|
if let Some(user_id) = &options.with_interactions_from {
|
||||||
q.add_sub_select_interaction_reaction(
|
q.add_sub_select_interaction_reaction(note_tbl, user_id);
|
||||||
prefix,
|
q.add_sub_select_interaction_renote(note_tbl, user_id);
|
||||||
&joined_prefix_str(prefix, INTERACTION_REACTION),
|
|
||||||
user_id,
|
|
||||||
);
|
|
||||||
q.add_sub_select_interaction_renote(
|
|
||||||
prefix,
|
|
||||||
&joined_prefix_str(prefix, INTERACTION_RENOTE),
|
|
||||||
user_id,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recursively attach reply parents
|
// Recursively attach reply parents
|
||||||
if reply_depth > 0 {
|
if reply_depth > 0 {
|
||||||
|
let reply_tbl = note_tbl.join_str(REPLY);
|
||||||
let visibility_filter = options
|
let visibility_filter = options
|
||||||
.visibility_filter
|
.visibility_filter
|
||||||
.with_note_and_user_tables(Some(joined_prefix_alias(prefix, REPLY)));
|
.with_note_and_user_tables(&reply_tbl);
|
||||||
let mut rel = note::Relation::SelfRef2.with_alias(Alias::new(prefix).into_iden());
|
|
||||||
rel.to_tbl = rel.to_tbl.alias(joined_prefix_alias(prefix, REPLY));
|
|
||||||
let condition = Condition::all()
|
let condition = Condition::all()
|
||||||
.add(join_columns_default(rel))
|
.add(join_columns_default(
|
||||||
|
note::Relation::SelfRef2.with_alias(note_tbl, &reply_tbl),
|
||||||
|
))
|
||||||
.add(visibility_filter);
|
.add(visibility_filter);
|
||||||
q.join_columns_on(
|
q.join_columns_on(
|
||||||
JoinType::LeftJoin,
|
JoinType::LeftJoin,
|
||||||
note::Relation::SelfRef2.with_alias(Alias::new(prefix).into_iden()),
|
note::Relation::SelfRef2.with_from_alias(note_tbl),
|
||||||
joined_prefix(prefix, REPLY),
|
&reply_tbl,
|
||||||
condition,
|
condition,
|
||||||
);
|
);
|
||||||
|
|
||||||
self.attach_note(
|
self.attach_note(
|
||||||
q,
|
q,
|
||||||
&joined_prefix_str(prefix, REPLY),
|
&reply_tbl,
|
||||||
reply_depth - 1,
|
reply_depth - 1,
|
||||||
renote_depth,
|
renote_depth,
|
||||||
options,
|
options,
|
||||||
|
@ -319,24 +260,25 @@ impl NoteResolver {
|
||||||
|
|
||||||
// Recursively attach renote/quote targets
|
// Recursively attach renote/quote targets
|
||||||
if renote_depth > 0 {
|
if renote_depth > 0 {
|
||||||
|
let renote_tbl = note_tbl.join_str(RENOTE);
|
||||||
let visibility_filter = options
|
let visibility_filter = options
|
||||||
.visibility_filter
|
.visibility_filter
|
||||||
.with_note_and_user_tables(Some(joined_prefix_alias(prefix, RENOTE)));
|
.with_note_and_user_tables(&renote_tbl);
|
||||||
let mut rel = note::Relation::SelfRef1.with_alias(Alias::new(prefix).into_iden());
|
|
||||||
rel.to_tbl = rel.to_tbl.alias(joined_prefix_alias(prefix, RENOTE));
|
|
||||||
let condition = Condition::all()
|
let condition = Condition::all()
|
||||||
.add(join_columns_default(rel))
|
.add(join_columns_default(
|
||||||
|
note::Relation::SelfRef1.with_alias(note_tbl, &renote_tbl),
|
||||||
|
))
|
||||||
.add(visibility_filter);
|
.add(visibility_filter);
|
||||||
q.join_columns_on(
|
q.join_columns_on(
|
||||||
JoinType::LeftJoin,
|
JoinType::LeftJoin,
|
||||||
note::Relation::SelfRef1.with_alias(Alias::new(prefix).into_iden()),
|
note::Relation::SelfRef1.with_from_alias(note_tbl),
|
||||||
joined_prefix(prefix, RENOTE),
|
&renote_tbl,
|
||||||
condition,
|
condition,
|
||||||
);
|
);
|
||||||
|
|
||||||
self.attach_note(
|
self.attach_note(
|
||||||
q,
|
q,
|
||||||
&joined_prefix_str(prefix, RENOTE),
|
&renote_tbl,
|
||||||
reply_depth,
|
reply_depth,
|
||||||
renote_depth - 1,
|
renote_depth - 1,
|
||||||
options,
|
options,
|
||||||
|
@ -346,30 +288,24 @@ impl NoteResolver {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolve(&self, options: &NoteResolveOptions) -> Select<note::Entity> {
|
pub fn resolve(&self, options: &NoteResolveOptions) -> Select<note::Entity> {
|
||||||
let prefix = note::Entity.base_prefix_str();
|
let note_tbl = note::Entity.base_prefix();
|
||||||
|
|
||||||
let mut select = Query::select();
|
let mut select = Query::select();
|
||||||
select.from_as(note::Entity, Alias::new(&prefix));
|
select.from_as(note::Entity, note_tbl.clone().into_iden());
|
||||||
|
|
||||||
if let Some(pins_user) = &options.only_pins_from {
|
if let Some(pins_user) = &options.only_pins_from {
|
||||||
select
|
select
|
||||||
.join_columns(
|
.join_columns(
|
||||||
JoinType::InnerJoin,
|
JoinType::InnerJoin,
|
||||||
note::Relation::UserNotePining.with_alias(Alias::new(&prefix)),
|
note::Relation::UserNotePining.with_from_alias(¬e_tbl),
|
||||||
joined_prefix(&prefix, PIN),
|
¬e_tbl.join_str(PIN),
|
||||||
)
|
)
|
||||||
.and_where(
|
.and_where(note_tbl.col(user_note_pining::Column::UserId).eq(pins_user));
|
||||||
Expr::col((
|
|
||||||
joined_prefix(&prefix, PIN),
|
|
||||||
user_note_pining::Column::UserId,
|
|
||||||
))
|
|
||||||
.eq(pins_user),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.attach_note(
|
self.attach_note(
|
||||||
&mut select,
|
&mut select,
|
||||||
&prefix,
|
¬e_tbl,
|
||||||
options.with_reply_target.then_some(1).unwrap_or_default(),
|
options.with_reply_target.then_some(1).unwrap_or_default(),
|
||||||
options.with_renote_target.then_some(1).unwrap_or_default(),
|
options.with_renote_target.then_some(1).unwrap_or_default(),
|
||||||
options,
|
options,
|
|
@ -54,7 +54,7 @@ pub trait PaginatedModel: 'static {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PaginatedModel for ck::note::Model {
|
impl PaginatedModel for ck::note::Entity {
|
||||||
fn time_column() -> impl Iden {
|
fn time_column() -> impl Iden {
|
||||||
ck::note::Column::CreatedAt
|
ck::note::Column::CreatedAt
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,7 @@ impl PaginatedModel for ck::note::Model {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PaginatedModel for ck::user::Model {
|
impl PaginatedModel for ck::user::Entity {
|
||||||
fn time_column() -> impl Iden {
|
fn time_column() -> impl Iden {
|
||||||
ck::user::Column::CreatedAt
|
ck::user::Column::CreatedAt
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ impl PaginatedModel for ck::user::Model {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PaginatedModel for ck::following::Model {
|
impl PaginatedModel for ck::following::Entity {
|
||||||
fn time_column() -> impl Iden {
|
fn time_column() -> impl Iden {
|
||||||
ck::following::Column::CreatedAt
|
ck::following::Column::CreatedAt
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,7 @@ impl PaginatedModel for ck::following::Model {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PaginatedModel for ck::follow_request::Model {
|
impl PaginatedModel for ck::follow_request::Entity {
|
||||||
fn time_column() -> impl Iden {
|
fn time_column() -> impl Iden {
|
||||||
ck::follow_request::Column::CreatedAt
|
ck::follow_request::Column::CreatedAt
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
use crate::model_ext::EntityPrefixExt;
|
use crate::model_ext::{AliasSourceExt, AliasSuffixExt, EntityPrefixExt, MagIden};
|
||||||
use crate::{
|
use crate::{model_ext::SelectColumnsExt, CalckeyModel};
|
||||||
model_ext::{joined_prefix, joined_prefix_str, SelectColumnsExt},
|
use ck::{drive_file, user};
|
||||||
AliasSourceExt, CalckeyModel,
|
use ext_calckey_model_migration::{IntoIden, SelectStatement};
|
||||||
};
|
use sea_orm::sea_query::Alias;
|
||||||
use ck::{drive_file, follow_request, following, user};
|
use sea_orm::{DbErr, FromQueryResult, Iden, JoinType, QueryResult};
|
||||||
use ext_calckey_model_migration::{Alias, SelectStatement};
|
|
||||||
use sea_orm::{DbErr, FromQueryResult, JoinType, QueryResult};
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
@ -24,18 +22,21 @@ const BANNER: &str = "banner.";
|
||||||
|
|
||||||
impl FromQueryResult for UserData {
|
impl FromQueryResult for UserData {
|
||||||
fn from_query_result(res: &QueryResult, prefix: &str) -> Result<Self, DbErr> {
|
fn from_query_result(res: &QueryResult, prefix: &str) -> Result<Self, DbErr> {
|
||||||
let fallback = user::Entity.base_prefix_str();
|
let prefix = if prefix.is_empty() {
|
||||||
let prefix = if prefix.is_empty() { &fallback } else { prefix };
|
user::Entity.base_prefix()
|
||||||
|
} else {
|
||||||
|
MagIden::alias(prefix)
|
||||||
|
};
|
||||||
|
|
||||||
Ok(UserData {
|
Ok(UserData {
|
||||||
user: user::Model::from_query_result(res, prefix)?,
|
user: user::Model::from_query_result(res, &prefix.to_string())?,
|
||||||
avatar: drive_file::Model::from_query_result_optional(
|
avatar: drive_file::Model::from_query_result_optional(
|
||||||
res,
|
res,
|
||||||
&joined_prefix_str(prefix, AVATAR),
|
&prefix.join_str_as_str(AVATAR),
|
||||||
)?,
|
)?,
|
||||||
banner: drive_file::Model::from_query_result_optional(
|
banner: drive_file::Model::from_query_result_optional(
|
||||||
res,
|
res,
|
||||||
&joined_prefix_str(prefix, BANNER),
|
&prefix.join_str_as_str(BANNER),
|
||||||
)?,
|
)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -53,26 +54,29 @@ impl UserResolver {
|
||||||
pub fn resolve(
|
pub fn resolve(
|
||||||
&self,
|
&self,
|
||||||
q: &mut SelectStatement,
|
q: &mut SelectStatement,
|
||||||
prefix: &str,
|
user_tbl: &MagIden,
|
||||||
UserResolveOptions {
|
UserResolveOptions {
|
||||||
with_avatar_and_banner,
|
with_avatar_and_banner,
|
||||||
}: &UserResolveOptions,
|
}: &UserResolveOptions,
|
||||||
) {
|
) {
|
||||||
q.add_aliased_columns::<user::Entity>(prefix);
|
q.add_aliased_columns::<user::Entity>(user_tbl);
|
||||||
|
|
||||||
if *with_avatar_and_banner {
|
if *with_avatar_and_banner {
|
||||||
q.add_aliased_columns::<drive_file::Entity>(&joined_prefix_str(prefix, AVATAR))
|
let avatar_tbl = user_tbl.join_str(AVATAR);
|
||||||
.add_aliased_columns::<drive_file::Entity>(&joined_prefix_str(prefix, BANNER));
|
let banner_tbl = user_tbl.join_str(BANNER);
|
||||||
|
|
||||||
|
q.add_aliased_columns::<drive_file::Entity>(&avatar_tbl)
|
||||||
|
.add_aliased_columns::<drive_file::Entity>(&banner_tbl);
|
||||||
|
|
||||||
q.join_columns(
|
q.join_columns(
|
||||||
JoinType::LeftJoin,
|
JoinType::LeftJoin,
|
||||||
user::Relation::DriveFile2.with_alias(Alias::new(prefix)),
|
user::Relation::DriveFile2.with_from_alias(user_tbl),
|
||||||
joined_prefix(prefix, AVATAR),
|
&avatar_tbl,
|
||||||
)
|
)
|
||||||
.join_columns(
|
.join_columns(
|
||||||
JoinType::LeftJoin,
|
JoinType::LeftJoin,
|
||||||
user::Relation::DriveFile1.with_alias(Alias::new(prefix)),
|
user::Relation::DriveFile1.with_from_alias(user_tbl),
|
||||||
joined_prefix(prefix, BANNER),
|
&banner_tbl,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
use magnetar_calckey_model::ck;
|
use magnetar_calckey_model::ck;
|
||||||
use magnetar_calckey_model::note_model::sub_interaction_renote;
|
use magnetar_calckey_model::note_model::data::sub_interaction_renote;
|
||||||
use magnetar_sdk::types::note::{
|
use magnetar_sdk::types::note::{
|
||||||
NoteDetailExt, NoteSelfContextExt, PackNoteMaybeAttachments, PackNoteMaybeFull, PackPollBase,
|
NoteDetailExt, NoteSelfContextExt, PackNoteMaybeFull, PackPollBase, ReactionPair,
|
||||||
ReactionPair,
|
|
||||||
};
|
};
|
||||||
use magnetar_sdk::types::user::PackUserBase;
|
use magnetar_sdk::types::user::PackUserBase;
|
||||||
use magnetar_sdk::types::{
|
use magnetar_sdk::types::{
|
||||||
|
|
|
@ -12,14 +12,15 @@ use futures_util::future::{try_join_all, BoxFuture};
|
||||||
use futures_util::{FutureExt, StreamExt, TryFutureExt, TryStreamExt};
|
use futures_util::{FutureExt, StreamExt, TryFutureExt, TryStreamExt};
|
||||||
use magnetar_calckey_model::ck::sea_orm_active_enums::NoteVisibilityEnum;
|
use magnetar_calckey_model::ck::sea_orm_active_enums::NoteVisibilityEnum;
|
||||||
use magnetar_calckey_model::emoji::EmojiTag;
|
use magnetar_calckey_model::emoji::EmojiTag;
|
||||||
use magnetar_calckey_model::note_model::{
|
use magnetar_calckey_model::model_ext::AliasColumnExt;
|
||||||
sub_interaction_reaction, sub_interaction_renote, NoteData, NoteResolveOptions,
|
use magnetar_calckey_model::note_model::data::{
|
||||||
NoteVisibilityFilterFactory,
|
sub_interaction_reaction, sub_interaction_renote, NoteData,
|
||||||
};
|
};
|
||||||
|
use magnetar_calckey_model::note_model::{NoteResolveOptions, NoteVisibilityFilterFactory};
|
||||||
use magnetar_calckey_model::poll::PollResolver;
|
use magnetar_calckey_model::poll::PollResolver;
|
||||||
use magnetar_calckey_model::sea_orm::prelude::Expr;
|
use magnetar_calckey_model::sea_orm::sea_query::{IntoIden, PgFunc, Query, SimpleExpr};
|
||||||
use magnetar_calckey_model::sea_orm::sea_query::{Alias, IntoIden, PgFunc, Query, SimpleExpr};
|
use magnetar_calckey_model::sea_orm::{ActiveEnum, ColumnTrait, Iden, IntoSimpleExpr};
|
||||||
use magnetar_calckey_model::sea_orm::{ActiveEnum, ColumnTrait, IntoSimpleExpr};
|
use magnetar_calckey_model::user_model::UserResolveOptions;
|
||||||
use magnetar_calckey_model::{ck, CalckeyDbError};
|
use magnetar_calckey_model::{ck, CalckeyDbError};
|
||||||
use magnetar_common::util::{parse_reaction, RawReaction};
|
use magnetar_common::util::{parse_reaction, RawReaction};
|
||||||
use magnetar_sdk::mmm::Token;
|
use magnetar_sdk::mmm::Token;
|
||||||
|
@ -43,22 +44,12 @@ use super::user::UserShapedData;
|
||||||
pub struct NoteVisibilityFilterSimple(Option<String>);
|
pub struct NoteVisibilityFilterSimple(Option<String>);
|
||||||
|
|
||||||
impl NoteVisibilityFilterFactory for NoteVisibilityFilterSimple {
|
impl NoteVisibilityFilterFactory for NoteVisibilityFilterSimple {
|
||||||
fn with_note_and_user_tables(&self, note_tbl: Option<Alias>) -> SimpleExpr {
|
fn with_note_and_user_tables(&self, note_tbl: &dyn Iden) -> SimpleExpr {
|
||||||
let note_tbl_name =
|
let is_public = note_tbl
|
||||||
note_tbl.map_or_else(|| ck::note::Entity.into_iden(), |a| a.into_iden());
|
.col(ck::note::Column::Visibility)
|
||||||
|
|
||||||
let note_visibility = Expr::col((note_tbl_name.clone(), ck::note::Column::Visibility));
|
|
||||||
let note_mentions = Expr::col((note_tbl_name.clone(), ck::note::Column::Mentions));
|
|
||||||
let note_reply_user_id = Expr::col((note_tbl_name.clone(), ck::note::Column::ReplyUserId));
|
|
||||||
let note_visible_user_ids =
|
|
||||||
Expr::col((note_tbl_name.clone(), ck::note::Column::VisibleUserIds));
|
|
||||||
let note_user_id = Expr::col((note_tbl_name, ck::note::Column::UserId));
|
|
||||||
|
|
||||||
let is_public = note_visibility
|
|
||||||
.clone()
|
|
||||||
.eq(NoteVisibilityEnum::Public.as_enum())
|
.eq(NoteVisibilityEnum::Public.as_enum())
|
||||||
.or(note_visibility
|
.or(note_tbl
|
||||||
.clone()
|
.col(ck::note::Column::Visibility)
|
||||||
.eq(NoteVisibilityEnum::Home.as_enum()));
|
.eq(NoteVisibilityEnum::Home.as_enum()));
|
||||||
|
|
||||||
let Some(user_id_str) = &self.0 else {
|
let Some(user_id_str) = &self.0 else {
|
||||||
|
@ -67,30 +58,34 @@ impl NoteVisibilityFilterFactory for NoteVisibilityFilterSimple {
|
||||||
|
|
||||||
let self_user_id = SimpleExpr::Constant(user_id_str.into());
|
let self_user_id = SimpleExpr::Constant(user_id_str.into());
|
||||||
|
|
||||||
let is_self = note_user_id.clone().eq(self_user_id.clone());
|
let is_self = note_tbl
|
||||||
|
.col(ck::note::Column::UserId)
|
||||||
|
.eq(self_user_id.clone());
|
||||||
|
|
||||||
let is_visible_specified = {
|
let is_visible_specified = {
|
||||||
let either_specified_or_followers = note_visibility
|
let either_specified_or_followers = note_tbl
|
||||||
.clone()
|
.col(ck::note::Column::Visibility)
|
||||||
.eq(NoteVisibilityEnum::Specified.as_enum())
|
.eq(NoteVisibilityEnum::Specified.as_enum())
|
||||||
.or(note_visibility
|
.or(note_tbl
|
||||||
.clone()
|
.col(ck::note::Column::Visibility)
|
||||||
.eq(NoteVisibilityEnum::Followers.as_enum()))
|
.eq(NoteVisibilityEnum::Followers.as_enum()));
|
||||||
.into_simple_expr();
|
|
||||||
|
|
||||||
let mentioned_or_specified = self_user_id
|
let mentioned_or_specified = self_user_id
|
||||||
.clone()
|
.clone()
|
||||||
.eq(PgFunc::any(note_mentions.into_simple_expr()))
|
.eq(PgFunc::any(
|
||||||
.or(self_user_id.eq(PgFunc::any(note_visible_user_ids)));
|
note_tbl.col(ck::note::Column::Mentions).into_simple_expr(),
|
||||||
|
))
|
||||||
|
.or(self_user_id.eq(PgFunc::any(note_tbl.col(ck::note::Column::VisibleUserIds))));
|
||||||
|
|
||||||
either_specified_or_followers.and(mentioned_or_specified)
|
either_specified_or_followers.and(mentioned_or_specified)
|
||||||
};
|
};
|
||||||
|
|
||||||
let is_visible_followers = {
|
let is_visible_followers = {
|
||||||
note_visibility
|
note_tbl
|
||||||
|
.col(ck::note::Column::Visibility)
|
||||||
.eq(NoteVisibilityEnum::Followers.as_enum())
|
.eq(NoteVisibilityEnum::Followers.as_enum())
|
||||||
.and(
|
.and(
|
||||||
note_user_id.in_subquery(
|
note_tbl.col(ck::note::Column::UserId).in_subquery(
|
||||||
Query::select()
|
Query::select()
|
||||||
.column(ck::following::Column::FolloweeId)
|
.column(ck::following::Column::FolloweeId)
|
||||||
.from(ck::following::Entity)
|
.from(ck::following::Entity)
|
||||||
|
@ -98,7 +93,7 @@ impl NoteVisibilityFilterFactory for NoteVisibilityFilterSimple {
|
||||||
.to_owned(),
|
.to_owned(),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.or(note_reply_user_id.eq(user_id_str))
|
.or(note_tbl.col(ck::note::Column::ReplyUserId).eq(user_id_str))
|
||||||
};
|
};
|
||||||
|
|
||||||
is_self
|
is_self
|
||||||
|
@ -584,7 +579,9 @@ impl NoteModel {
|
||||||
)),
|
)),
|
||||||
time_range: None,
|
time_range: None,
|
||||||
limit: None,
|
limit: None,
|
||||||
with_user: self.with_context,
|
user_options: UserResolveOptions {
|
||||||
|
with_avatar_and_banner: self.with_context,
|
||||||
|
},
|
||||||
with_reply_target: self.with_context,
|
with_reply_target: self.with_context,
|
||||||
with_renote_target: self.with_context,
|
with_renote_target: self.with_context,
|
||||||
with_interactions_from: self
|
with_interactions_from: self
|
||||||
|
@ -620,7 +617,9 @@ impl NoteModel {
|
||||||
)),
|
)),
|
||||||
time_range: None,
|
time_range: None,
|
||||||
limit: None,
|
limit: None,
|
||||||
with_user: self.with_context,
|
user_options: UserResolveOptions {
|
||||||
|
with_avatar_and_banner: self.with_context,
|
||||||
|
},
|
||||||
with_reply_target: self.with_context,
|
with_reply_target: self.with_context,
|
||||||
with_renote_target: self.with_context,
|
with_renote_target: self.with_context,
|
||||||
with_interactions_from: self
|
with_interactions_from: self
|
||||||
|
|
Loading…
Reference in New Issue