leetcode_api/dao/
query.rs1use miette::{IntoDiagnostic, Result};
2use sea_orm::{
3 ColumnTrait, EntityTrait, FromQueryResult, QueryFilter, QuerySelect, sea_query::Expr,
4};
5use tracing::debug;
6
7use super::{detail, glob_db, index};
8use crate::{
9 entities::{new_index, prelude::*, topic_tags},
10 leetcode::IdSlug,
11};
12
13#[derive(Clone, Copy)]
14#[derive(Debug)]
15#[derive(Default)]
16#[derive(PartialEq, Eq, PartialOrd, Ord)]
17pub struct Query;
18
19#[derive(FromQueryResult)]
20#[derive(Debug)]
21#[derive(Clone)]
22pub struct PassStat {
23 pub diff: String,
24 pub pass_count: u32,
25 pub sum: u32,
26}
27
28impl Query {
29 pub async fn get_question_index(idslug: &IdSlug) -> Result<index::Model> {
33 let res = match idslug {
34 IdSlug::Id(id) => Index::find_by_id(*id)
35 .one(glob_db().await)
36 .await
37 .into_diagnostic()?
38 .unwrap_or_default(),
39 IdSlug::Slug(slug) => Index::find()
40 .filter(index::Column::QuestionTitleSlug.eq(slug))
41 .one(glob_db().await)
42 .await
43 .into_diagnostic()?
44 .unwrap_or_default(),
45 };
46 debug!("get value {:#?}", res);
47 Ok(res)
48 }
49
50 pub async fn query_detail_by_id(id: u32) -> Result<Option<detail::Model>> {
51 Detail::find_by_id(id)
52 .one(glob_db().await)
53 .await
54 .into_diagnostic()
55 }
56
57 pub async fn query_all_index() -> Result<Vec<index::Model>> {
58 let models = Index::find()
59 .all(glob_db().await)
60 .await
61 .into_diagnostic()?;
62
63 Ok(models)
64 }
65 pub async fn query_by_topic(
66 topic_slugs: &[String],
67 difficulty: Option<String>,
68 ) -> Result<Vec<new_index::Model>> {
69 let mut cond = topic_tags::Column::TopicSlug.is_in(topic_slugs);
70
71 if let Some(v) = difficulty {
72 if !v.is_empty() {
73 cond = cond.and(new_index::Column::Difficulty.eq(v));
74 }
75 }
76
77 NewIndexDB::find()
78 .inner_join(topic_tags::Entity)
79 .filter(cond)
80 .group_by(new_index::Column::TitleSlug)
81 .having(
82 topic_tags::Column::TopicSlug
83 .count()
84 .eq(topic_slugs.len() as i32),
85 )
86 .all(glob_db().await)
87 .await
88 .into_diagnostic()
89 }
90
91 pub async fn query_status() -> Result<Vec<PassStat>> {
92 NewIndexDB::find()
93 .select_only()
94 .column_as(new_index::Column::Difficulty, "diff")
95 .column_as(
96 Expr::expr(new_index::Column::Status.eq("AC")).sum(),
97 "pass_count",
98 )
99 .column_as(new_index::Column::TitleSlug.count(), "sum")
100 .group_by(new_index::Column::Difficulty)
101 .into_model::<PassStat>()
102 .all(glob_db().await)
103 .await
104 .into_diagnostic()
105 }
106
107 pub async fn query_all_topic() -> Result<Vec<topic_tags::Model>> {
108 TopicTagsDB::find()
109 .all(glob_db().await)
110 .await
111 .into_diagnostic()
112 }
113
114 pub async fn query_all_new_index<D>(diff: D) -> Result<Vec<new_index::Model>>
115 where
116 D: Into<Option<String>> + Send,
117 {
118 if let Some(diff) = diff.into() {
119 if !diff.is_empty() {
120 return NewIndexDB::find()
121 .filter(new_index::Column::Difficulty.eq(diff))
122 .all(glob_db().await)
123 .await
124 .into_diagnostic();
125 }
126 }
127 NewIndexDB::find()
128 .all(glob_db().await)
129 .await
130 .into_diagnostic()
131 }
132}