favorite.rs (3549B)
1 use super::User; 2 use crate::api::EmptyResult; 3 use crate::db::DbConn; 4 use crate::error::MapResult; 5 db_object! { 6 #[derive(Insertable)] 7 #[diesel(table_name = favorites)] 8 pub struct Favorite { 9 user_uuid: String, 10 cipher_uuid: String, 11 } 12 } 13 14 impl Favorite { 15 // Returns whether the specified cipher is a favorite of the specified user. 16 pub async fn is_favorite(cipher_uuid: &str, user_uuid: &str, conn: &DbConn) -> bool { 17 db_run! { conn: { 18 let query = favorites::table 19 .filter(favorites::cipher_uuid.eq(cipher_uuid)) 20 .filter(favorites::user_uuid.eq(user_uuid)) 21 .count(); 22 query.first::<i64>(conn).ok().unwrap_or(0) != 0 23 }} 24 } 25 26 // Sets whether the specified cipher is a favorite of the specified user. 27 pub async fn set_favorite( 28 favorite: bool, 29 cipher_uuid: &str, 30 user_uuid: &str, 31 conn: &DbConn, 32 ) -> EmptyResult { 33 let (old, new) = ( 34 Self::is_favorite(cipher_uuid, user_uuid, conn).await, 35 favorite, 36 ); 37 match (old, new) { 38 (false, true) => { 39 User::update_uuid_revision(user_uuid, conn).await; 40 db_run! { conn: { 41 diesel::insert_into(favorites::table) 42 .values(( 43 favorites::user_uuid.eq(user_uuid), 44 favorites::cipher_uuid.eq(cipher_uuid), 45 )) 46 .execute(conn) 47 .map_res("Error adding favorite") 48 }} 49 } 50 (true, false) => { 51 User::update_uuid_revision(user_uuid, conn).await; 52 db_run! { conn: { 53 diesel::delete( 54 favorites::table 55 .filter(favorites::user_uuid.eq(user_uuid)) 56 .filter(favorites::cipher_uuid.eq(cipher_uuid)) 57 ) 58 .execute(conn) 59 .map_res("Error removing favorite") 60 }} 61 } 62 // Otherwise, the favorite status is already what it should be. 63 _ => Ok(()), 64 } 65 } 66 67 // Delete all favorite entries associated with the specified cipher. 68 pub async fn delete_all_by_cipher(cipher_uuid: &str, conn: &DbConn) -> EmptyResult { 69 db_run! { conn: { 70 diesel::delete(favorites::table.filter(favorites::cipher_uuid.eq(cipher_uuid))) 71 .execute(conn) 72 .map_res("Error removing favorites by cipher") 73 }} 74 } 75 76 // Delete all favorite entries associated with the specified user. 77 pub async fn delete_all_by_user(user_uuid: &str, conn: &DbConn) -> EmptyResult { 78 db_run! { conn: { 79 diesel::delete(favorites::table.filter(favorites::user_uuid.eq(user_uuid))) 80 .execute(conn) 81 .map_res("Error removing favorites by user") 82 }} 83 } 84 85 /// Return a vec with (cipher_uuid) this will only contain favorite flagged ciphers 86 /// This is used during a full sync so we only need one query for all favorite cipher matches. 87 pub async fn get_all_cipher_uuid_by_user(user_uuid: &str, conn: &DbConn) -> Vec<String> { 88 db_run! { conn: { 89 favorites::table 90 .filter(favorites::user_uuid.eq(user_uuid)) 91 .select(favorites::cipher_uuid) 92 .load::<String>(conn) 93 .unwrap_or_default() 94 }} 95 } 96 }