From 09f564746f77ed004574c290e635cac2da7d3363 Mon Sep 17 00:00:00 2001 From: Natty Date: Thu, 5 Sep 2024 22:16:54 +0200 Subject: [PATCH] SeaORM magic to use CTEs for pins Might or might not work --- Cargo.lock | 97 +++++++++++++++++++-------------- Cargo.toml | 4 +- ext_model/src/note_model/mod.rs | 54 +++++++++++++----- 3 files changed, 97 insertions(+), 58 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9e6c92e..7e9bcc6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -808,17 +808,6 @@ dependencies = [ "serde", ] -[[package]] -name = "derivative" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "deunicode" version = "1.6.0" @@ -879,6 +868,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "educe" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4bd92664bf78c4d3dba9b7cdafce6fa15b13ed3ed16175218196942e99168a8" +dependencies = [ + "enum-ordinalize", + "proc-macro2", + "quote", + "syn 2.0.77", +] + [[package]] name = "either" version = "1.13.0" @@ -906,6 +907,26 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "enum-ordinalize" +version = "4.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea0dcfa4e54eeb516fe454635a95753ddd39acda650ce703031c6973e315dd5" +dependencies = [ + "enum-ordinalize-derive", +] + +[[package]] +name = "enum-ordinalize-derive" +version = "4.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d28318a75d4aead5c4db25382e8ef717932d0346600cacae6357eb5941bc5ff" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + [[package]] name = "equivalent" version = "1.0.1" @@ -1776,7 +1797,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", - "strum 0.26.3", + "strum", "thiserror", "tokio", "tokio-stream", @@ -1880,7 +1901,7 @@ dependencies = [ "serde", "serde_json", "sha2", - "strum 0.26.3", + "strum", "thiserror", "tokio", "tracing", @@ -1908,7 +1929,7 @@ dependencies = [ "nom_locate", "quick-xml", "serde", - "strum 0.26.3", + "strum", "tracing", "unicode-segmentation", ] @@ -1929,7 +1950,7 @@ dependencies = [ "sea-orm", "serde", "serde_json", - "strum 0.26.3", + "strum", "thiserror", "tokio", "tokio-util", @@ -1956,7 +1977,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", - "strum 0.26.3", + "strum", "ts-rs", "unicode-segmentation", ] @@ -2997,9 +3018,9 @@ dependencies = [ [[package]] name = "sea-orm" -version = "0.12.15" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8814e37dc25de54398ee62228323657520b7f29713b8e238649385dbe473ee0" +checksum = "ea1fee0cf8528dbe6eda29d5798afc522a63b75e44c5b15721e6e64af9c7cc4b" dependencies = [ "async-stream", "async-trait", @@ -3015,7 +3036,7 @@ dependencies = [ "serde", "serde_json", "sqlx", - "strum 0.25.0", + "strum", "thiserror", "time", "tracing", @@ -3025,9 +3046,9 @@ dependencies = [ [[package]] name = "sea-orm-cli" -version = "0.12.15" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "620bc560062ae251b1366bde43b3f1508445cab5c2c8cbdb397034638ab1b357" +checksum = "5f0b8869c75cf3fbb1bd860abb025033cd2e514c5f4fa43e792697cb1fe6c882" dependencies = [ "chrono", "clap", @@ -3042,9 +3063,9 @@ dependencies = [ [[package]] name = "sea-orm-macros" -version = "0.12.15" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e115c6b078e013aa963cc2d38c196c2c40b05f03d0ac872fe06b6e0d5265603" +checksum = "8737b566799ed0444f278d13c300c4c6f1a91782f60ff5825a591852d5502030" dependencies = [ "heck 0.4.1", "proc-macro2", @@ -3056,9 +3077,9 @@ dependencies = [ [[package]] name = "sea-orm-migration" -version = "0.12.15" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee8269bc6ff71afd6b78aa4333ac237a69eebd2cdb439036291e64fb4b8db23c" +checksum = "216643749e26ce27ab6c51d3475f2692981d4a902d34455bcd322f412900df5c" dependencies = [ "async-trait", "clap", @@ -3073,13 +3094,13 @@ dependencies = [ [[package]] name = "sea-query" -version = "0.30.7" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4166a1e072292d46dc91f31617c2a1cdaf55a8be4b5c9f4bf2ba248e3ac4999b" +checksum = "7e5073b2cfed767511a57d18115f3b3d8bcb5690bf8c89518caec6cb22c0cd74" dependencies = [ "bigdecimal", "chrono", - "derivative", + "educe", "inherent", "ordered-float", "rust_decimal", @@ -3091,9 +3112,9 @@ dependencies = [ [[package]] name = "sea-query-binder" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36bbb68df92e820e4d5aeb17b4acd5cc8b5d18b2c36a4dd6f4626aabfa7ab1b9" +checksum = "754965d4aee6145bec25d0898e5c931e6c22859789ce62fd85a42a15ed5a8ce3" dependencies = [ "bigdecimal", "chrono", @@ -3120,9 +3141,9 @@ dependencies = [ [[package]] name = "sea-schema" -version = "0.14.2" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d148608012d25222442d1ebbfafd1228dbc5221baf4ec35596494e27a2394e" +checksum = "ad52149fc81836ea7424c3425d8f6ed8ad448dd16d2e4f6a3907ba46f3f2fd78" dependencies = [ "futures", "sea-query", @@ -3131,14 +3152,14 @@ dependencies = [ [[package]] name = "sea-schema-derive" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6f686050f76bffc4f635cda8aea6df5548666b830b52387e8bc7de11056d11e" +checksum = "debdc8729c37fdbf88472f97fd470393089f997a909e535ff67c544d18cfccf0" dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.77", ] [[package]] @@ -3628,12 +3649,6 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" -[[package]] -name = "strum" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" - [[package]] name = "strum" version = "0.26.3" diff --git a/Cargo.toml b/Cargo.toml index a9ab893..6e0b46b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,8 +60,8 @@ redis = "0.26" regex = "1.9" rsa = "0.9" reqwest = "0.12" -sea-orm = "0.12" -sea-orm-migration = "0.12" +sea-orm = "1" +sea-orm-migration = "1" serde = "1" serde_json = "1" serde_urlencoded = "0.7" diff --git a/ext_model/src/note_model/mod.rs b/ext_model/src/note_model/mod.rs index 4166402..b566452 100644 --- a/ext_model/src/note_model/mod.rs +++ b/ext_model/src/note_model/mod.rs @@ -1,25 +1,25 @@ pub mod data; -use ck::{note, note_reaction, user_note_pining}; -use data::{sub_interaction_reaction, sub_interaction_renote, NoteData}; -use ext_model_migration::SelectStatement; -use magnetar_sdk::types::SpanFilter; -use sea_orm::sea_query::{Asterisk, Expr, IntoIden, Query, SelectExpr, SimpleExpr}; -use sea_orm::{Condition, EntityTrait, Iden, JoinType, Order, QueryFilter, QuerySelect, QueryTrait, Select}; -use std::sync::Arc; - use crate::model_ext::{ join_columns_default, AliasColumnExt, AliasSourceExt, AliasSuffixExt, CursorPaginationExt, EntityPrefixExt, MagIden, SelectColumnsExt, }; 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 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 std::sync::Arc; +const PINS: &str = "pins."; const INTERACTION_REACTION: &str = "iact.rct."; const INTERACTION_RENOTE: &str = "iact.rnt."; const USER: &str = "u."; const REPLY: &str = "reply."; -const RENOTE: &str = "renote."; +const RENOTE: &str = "rnt."; #[derive(Clone)] pub struct NoteResolver { @@ -39,14 +39,15 @@ pub enum NoteResolveMode { } impl NoteResolveMode { - fn as_expr(&self) -> SimpleExpr { + fn where_expr(&self) -> SimpleExpr { 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), + // We add a CTE for pins NoteResolveMode::PinsFromUserId(user_id) => { - let sub_query = Query::select() + let cte_query = Query::select() .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)) @@ -56,7 +57,29 @@ impl NoteResolveMode { ]) .take(); - id_col.in_subquery(sub_query) + 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(), + ) } } } @@ -156,7 +179,7 @@ impl NoteResolver { .visibility_filter .with_note_and_user_tables(¬e::Entity.base_prefix()); - let id_filter = options.mode.as_ref().map(NoteResolveMode::as_expr); + let id_filter = options.mode.as_ref().map(NoteResolveMode::where_expr); let note = select .filter(visibility_filter) @@ -173,12 +196,13 @@ impl NoteResolver { options: &NoteResolveOptions, ) -> Result, CalckeyDbError> { let select = self.resolve(options); + let visibility_filter = options .visibility_filter .with_note_and_user_tables(¬e::Entity.base_prefix()); - let id_filter = options.mode.as_ref().map(NoteResolveMode::as_expr); + let id_filter = options.mode.as_ref().map(NoteResolveMode::where_expr); - let notes_select = select + let mut notes_select = select .filter(visibility_filter) .apply_if(id_filter, Select::::filter);