1use super::*;
2use sqlx::{query, query_as, PgPool};
3
4#[derive(Debug, Clone, sqlx::Type)]
5#[sqlx(type_name = "hunttype")]
6pub enum Hunttype {
7 OldOdds,
8 NewOdds,
9 SOS,
10 DexNav,
11 MasudaGenIV,
12 MasudaGenV,
13 MasudaGenVI,
14}
15
16impl From<String> for Hunttype {
17 fn from(value: String) -> Self {
18 match value.as_str() {
19 "OldOdds" => Self::OldOdds,
20 "NewOdds" => Self::NewOdds,
21 "SOS" => Self::SOS,
22 "DexNav" => Self::DexNav,
23 "MasudaGenIV" => Self::MasudaGenIV,
24 "MasudaGenV" => Self::MasudaGenV,
25 "MasudaGenVI" => Self::MasudaGenVI,
26 _ => Self::NewOdds,
27 }
28 }
29}
30
31#[derive(Debug, sqlx::FromRow)]
32pub struct DbCounter {
33 pub uuid: uuid::Uuid,
34 pub owner_uuid: uuid::Uuid,
35 pub name: String,
36 pub created_at: chrono::NaiveDateTime,
37 pub last_edit: chrono::NaiveDateTime,
38 pub is_deleted: bool,
39}
40
41#[derive(Debug, sqlx::FromRow)]
42pub struct DbPhase {
43 pub uuid: uuid::Uuid,
44 pub owner_uuid: uuid::Uuid,
45 pub parent_uuid: uuid::Uuid,
46 pub name: String,
47 pub count: i32,
48 pub time: i64,
49 pub hunt_type: Hunttype,
50 pub has_charm: bool,
51 pub dexnav_encounters: Option<i32>,
52 pub success: bool,
53 pub created_at: chrono::NaiveDateTime,
54 pub last_edit: chrono::NaiveDateTime,
55 pub is_deleted: bool,
56}
57
58#[derive(Debug)]
59pub struct DbUser {
60 pub uuid: uuid::Uuid,
61 pub username: String,
62 pub token: Option<uuid::Uuid>,
63 pub token_expire: chrono::NaiveDateTime,
64 pub email: Option<String>,
65}
66
67impl DbUser {
68 pub async fn get_token(&self, pool: &PgPool) -> Result<DbAuthToken, sqlx::error::Error> {
69 let token = query_as!(
70 DbAuthToken,
71 r#"
72 select * from auth_tokens
73 where uuid = $1 AND user_uuid = $2
74 "#,
75 self.token,
76 self.uuid,
77 )
78 .fetch_one(pool)
79 .await?;
80 Ok(token)
81 }
82
83 pub async fn token_status(&self, pool: &PgPool) -> TokenStatus {
84 if let Ok(token) = self.get_token(pool).await {
85 if token.expire_on.and_utc() > chrono::Utc::now() {
86 TokenStatus::Valid
87 } else {
88 TokenStatus::Expired
89 }
90 } else {
91 TokenStatus::Invalid
92 }
93 }
94
95 pub async fn get_counters(&self, pool: &PgPool) -> Result<Vec<DbCounter>, AuthorizationError> {
96 let data = query_as!(
97 DbCounter,
98 r#"
99 select * from counters
100 where owner_uuid = $1
101 "#,
102 self.uuid
103 )
104 .fetch_all(pool)
105 .await
106 .map_err(|err| AuthorizationError::Internal(err.to_string()))?;
107
108 Ok(data)
109 }
110}
111
112pub struct DbAuthToken {
113 pub uuid: uuid::Uuid,
114 pub user_uuid: uuid::Uuid,
115 pub expire_on: chrono::NaiveDateTime,
116}
117
118#[derive(Debug, Clone, PartialEq, Eq)]
119pub enum TokenStatus {
120 Valid,
121 Invalid,
122 Expired,
123}
124
125pub struct DbPreferences {
126 pub user_uuid: uuid::Uuid,
127 pub use_default_accent_color: bool,
128 pub accent_color: Option<String>,
129 pub show_separator: bool,
130 pub multi_select: bool,
131 pub save_on_pause: bool,
132}
133
134impl DbPreferences {
135 pub async fn db_get(pool: &PgPool, user_uuid: uuid::Uuid) -> Result<Self, BackendError> {
136 let data = match query_as!(
137 DbPreferences,
138 r#"
139 select * from preferences
140 where user_uuid = $1
141 "#,
142 user_uuid,
143 )
144 .fetch_one(pool)
145 .await
146 {
147 Ok(data) => data,
148 Err(sqlx::Error::RowNotFound) => {
149 Err(BackendError::DataNotFound(String::from("preferences")))?
150 }
151 Err(err) => Err(err)?,
152 };
153
154 Ok(data)
155 }
156
157 pub async fn db_set(
158 self,
159 pool: &PgPool,
160 username: &str,
161 token: uuid::Uuid,
162 ) -> Result<(), BackendError> {
163 let user = auth::get_user(pool, username, token).await?;
164 query!(
165 r#"
166 INSERT INTO preferences (
167 user_uuid,
168 use_default_accent_color,
169 accent_color,
170 show_separator,
171 multi_select,
172 save_on_pause
173 )
174 VALUES ($1, $2, $3, $4, $5, $6)
175 ON CONFLICT (user_uuid) DO UPDATE
176 SET use_default_accent_color = $2,
177 accent_color = $3,
178 show_separator = $4,
179 multi_select = $5,
180 save_on_pause = $6
181 "#,
182 user.uuid,
183 self.use_default_accent_color,
184 self.accent_color,
185 self.show_separator,
186 self.multi_select,
187 self.save_on_pause,
188 )
189 .execute(pool)
190 .await?;
191
192 Ok(())
193 }
194}