create_rust_app/auth/
user_session.rs

1use super::schema::user_sessions;
2use crate::diesel::{
3    insert_into, AsChangeset, Associations, ExpressionMethods, Identifiable, Insertable, QueryDsl,
4    Queryable, RunQueryDsl,
5};
6
7use super::user::User;
8use super::{PaginationParams, Utc, ID};
9use crate::database::Connection;
10use diesel::QueryResult;
11use serde::{Deserialize, Serialize};
12
13#[allow(clippy::module_name_repetitions)]
14#[tsync::tsync]
15#[derive(
16    Debug,
17    Serialize,
18    Deserialize,
19    Clone,
20    Queryable,
21    Insertable,
22    Identifiable,
23    Associations,
24    AsChangeset,
25)]
26#[diesel(table_name=user_sessions, belongs_to(User))]
27pub struct UserSession {
28    /* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
29    Add columns here in the same order as the schema
30    -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
31    pub id: ID,
32
33    pub user_id: ID,
34    pub refresh_token: String,
35    pub device: Option<String>,
36
37    pub created_at: Utc,
38    #[cfg(not(feature = "database_sqlite"))]
39    pub updated_at: Utc,
40}
41
42#[allow(clippy::module_name_repetitions)]
43#[tsync::tsync]
44#[derive(Debug, Serialize, Deserialize, Clone, Insertable, AsChangeset)]
45#[diesel(table_name=user_sessions)]
46pub struct UserSessionChangeset {
47    /* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
48    Add columns here in the same order as the schema
49    Don't include non-mutable columns
50    (ex: id, created_at/updated_at)
51    -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
52    pub user_id: ID,
53    pub refresh_token: String,
54    pub device: Option<String>,
55}
56
57impl UserSession {
58    /// Create an entry in [`db`](`Connection`)'s `user_sessions` table using the data in [`item`](`UserSessionChangeset`)
59    ///
60    /// # Errors
61    /// * [`diesel::result::Error`](`diesel::result::Error`) if the query fails
62    pub fn create(db: &mut Connection, item: &UserSessionChangeset) -> QueryResult<Self> {
63        use super::schema::user_sessions::dsl::user_sessions;
64
65        insert_into(user_sessions)
66            .values(item)
67            .get_result::<Self>(db)
68    }
69
70    /// Read from [`db`](`Connection`), querying for an entry in the `user_sessions`
71    /// who's primary key matches [`item_id`](`ID`)
72    ///
73    /// # Errors
74    /// * [`diesel::result::Error`](`diesel::result::Error`) if the query fails
75    pub fn read(db: &mut Connection, item_id: ID) -> QueryResult<Self> {
76        use super::schema::user_sessions::dsl::{id, user_sessions};
77
78        user_sessions.filter(id.eq(item_id)).first::<Self>(db)
79    }
80
81    /// Query [`db`](`Connection`)'s `user_sessions` table for an entry
82    /// who's `refresh_token` matches the given `item_refresh_token`
83    ///
84    /// # Errors
85    /// * [`diesel::result::Error`](`diesel::result::Error`) if the query fails
86    pub fn find_by_refresh_token(
87        db: &mut Connection,
88        item_refresh_token: &str,
89    ) -> QueryResult<Self> {
90        use super::schema::user_sessions::dsl::{refresh_token, user_sessions};
91
92        user_sessions
93            .filter(refresh_token.eq(item_refresh_token))
94            .first::<Self>(db)
95    }
96
97    /// Read from [`db`](`Connection`), return entries of the `user_sessions` table,
98    /// paginated according to [`pagination`](`PaginationParams`)
99    ///
100    /// # Errors
101    /// * [`diesel::result::Error`](`diesel::result::Error`) if the query fails
102    pub fn read_all(
103        db: &mut Connection,
104        pagination: &PaginationParams,
105        item_user_id: ID,
106    ) -> QueryResult<Vec<Self>> {
107        use super::schema::user_sessions::dsl::{created_at, user_id, user_sessions};
108
109        user_sessions
110            .filter(user_id.eq(item_user_id))
111            .order(created_at)
112            .limit(pagination.page_size)
113            .offset(
114                pagination.page
115                    * std::cmp::min(
116                        pagination.page_size,
117                        i64::from(PaginationParams::MAX_PAGE_SIZE),
118                    ),
119            )
120            .load::<Self>(db)
121    }
122
123    /// Query [`db`](`Connection`) for all entries in the `user_sessions` table
124    /// who's `user_id` matches the given [`item_user_id`]
125    ///
126    /// # Errors
127    /// * [`diesel::result::Error`](`diesel::result::Error`) if the query fails
128    pub fn count_all(db: &mut Connection, item_user_id: ID) -> QueryResult<i64> {
129        use super::schema::user_sessions::dsl::{user_id, user_sessions};
130
131        user_sessions
132            .filter(user_id.eq(item_user_id))
133            .count()
134            .get_result(db)
135    }
136
137    /// Update the entry in [`db`](`Connection`)'s `user_sessions` table who's primary key matches
138    /// [`item_id`](`ID`), with the data in [`item`](`UserSessionChangeset`)
139    ///
140    /// # Errors
141    /// * [`diesel::result::Error`](`diesel::result::Error`) if the query fails
142    pub fn update(
143        db: &mut Connection,
144        item_id: ID,
145        item: &UserSessionChangeset,
146    ) -> QueryResult<Self> {
147        use super::schema::user_sessions::dsl::{id, user_sessions};
148
149        diesel::update(user_sessions.filter(id.eq(item_id)))
150            .set(item)
151            .get_result(db)
152    }
153
154    /// Delete the entry in [`db`](`Connection`)'s `user_sessions` table who's
155    /// primary key matches [`item_id`](`ID`)
156    ///
157    /// # Errors
158    /// * [`diesel::result::Error`](`diesel::result::Error`) if the query fails
159    pub fn delete(db: &mut Connection, item_id: ID) -> QueryResult<usize> {
160        use super::schema::user_sessions::dsl::{id, user_sessions};
161
162        diesel::delete(user_sessions.filter(id.eq(item_id))).execute(db)
163    }
164
165    /// Delete all entries in [`db`](`Connection`)'s `user_sessions` table who's
166    /// '`user_id`' matches [`item_user_id`](`ID`)
167    ///
168    /// # Errors
169    /// * [`diesel::result::Error`](`diesel::result::Error`) if the query fails
170    pub fn delete_all_for_user(db: &mut Connection, item_user_id: ID) -> QueryResult<usize> {
171        use super::schema::user_sessions::dsl::{user_id, user_sessions};
172
173        diesel::delete(user_sessions.filter(user_id.eq(item_user_id))).execute(db)
174    }
175}