Split query into two due to SeaORM limitations
ci/woodpecker/push/ociImagePush Pipeline was successful Details

This commit is contained in:
Natty 2024-09-05 23:40:12 +02:00
parent 09f564746f
commit 611afc591c
Signed by: natty
GPG Key ID: BF6CB659ADEE60EC
2 changed files with 28 additions and 41 deletions

View File

@ -8,10 +8,10 @@ use crate::user_model::{UserResolveOptions, UserResolver};
use crate::{CalckeyDbError, CalckeyModel};
use ck::{note, note_reaction, user_note_pining};
use data::{sub_interaction_reaction, sub_interaction_renote, NoteData};
use ext_model_migration::{BinOper, CommonTableExpression, Order, QueryStatementBuilder, SelectStatement, WithClause};
use ext_model_migration::SelectStatement;
use magnetar_sdk::types::SpanFilter;
use sea_orm::sea_query::{Alias, Asterisk, Expr, IntoIden, Query, SelectExpr, SimpleExpr};
use sea_orm::{Condition, ConnectionTrait, EntityTrait, Iden, JoinType, QueryFilter, QuerySelect, QueryTrait, Select, StatementBuilder};
use sea_orm::sea_query::{Asterisk, Expr, IntoIden, Query, SelectExpr, SimpleExpr};
use sea_orm::{ColumnTrait, Condition, EntityTrait, Iden, JoinType, QueryFilter, QueryOrder, QuerySelect, QueryTrait, Select, StatementBuilder};
use std::sync::Arc;
const PINS: &str = "pins.";
@ -39,47 +39,25 @@ pub enum NoteResolveMode {
}
impl NoteResolveMode {
fn where_expr(&self) -> SimpleExpr {
async fn where_expr(&self, db: &CalckeyModel) -> Result<SimpleExpr, CalckeyDbError> {
let id_col = note::Entity.base_prefix().col(note::Column::Id);
match self {
NoteResolveMode::Single(id) => id_col.eq(id),
NoteResolveMode::Multiple(ids) => id_col.is_in(ids),
NoteResolveMode::Single(id) => Ok(id_col.eq(id)),
NoteResolveMode::Multiple(ids) => Ok(id_col.is_in(ids)),
// We add a CTE for pins
NoteResolveMode::PinsFromUserId(user_id) => {
let cte_query = Query::select()
let cte_query = user_note_pining::Entity::find()
.column(user_note_pining::Column::NoteId)
.from(user_note_pining::Entity)
.and_where(Expr::col((user_note_pining::Entity, user_note_pining::Column::UserId)).eq(user_id))
.order_by_columns([
((user_note_pining::Entity, user_note_pining::Column::CreatedAt), Order::Desc),
((user_note_pining::Entity, user_note_pining::Column::Id), Order::Desc)
])
.take();
.filter(user_note_pining::Column::UserId.eq(user_id))
.order_by_desc(user_note_pining::Column::CreatedAt)
.all(db.inner())
.await?
.into_iter()
.map(|m| m.note_id)
.collect::<Vec<_>>();
let cte = CommonTableExpression::from_select(cte_query)
.table_name(Alias::new(PINS))
.to_owned();
let with_clause = WithClause::new()
.cte(cte)
.to_owned();
SimpleExpr::Binary(
Box::new(id_col.into()),
BinOper::In,
SimpleExpr::SubQuery(
None,
Query::select()
.column(user_note_pining::Column::NoteId)
.from(Alias::new(PINS))
.take()
.with(with_clause)
.into_sub_query_statement()
.into(),
).into(),
)
Box::pin(NoteResolveMode::Multiple(cte_query).where_expr(&db)).await
}
}
}
@ -179,7 +157,11 @@ impl NoteResolver {
.visibility_filter
.with_note_and_user_tables(&note::Entity.base_prefix());
let id_filter = options.mode.as_ref().map(NoteResolveMode::where_expr);
let id_filter = if let Some(mode) = options.mode.as_ref() {
Some(mode.where_expr(&self.db).await?)
} else {
None
};
let note = select
.filter(visibility_filter)
@ -200,9 +182,14 @@ impl NoteResolver {
let visibility_filter = options
.visibility_filter
.with_note_and_user_tables(&note::Entity.base_prefix());
let id_filter = options.mode.as_ref().map(NoteResolveMode::where_expr);
let mut notes_select = select
let id_filter = if let Some(mode) = options.mode.as_ref() {
Some(mode.where_expr(&self.db).await?)
} else {
None
};
let notes_select = select
.filter(visibility_filter)
.apply_if(id_filter, Select::<note::Entity>::filter);

View File

@ -2,7 +2,7 @@ use std::collections::HashMap;
use std::sync::Arc;
use cached::{Cached, TimedCache};
use strum::{EnumVariantNames, VariantNames};
use strum::VariantNames;
use thiserror::Error;
use tokio::sync::Mutex;
use tracing::error;