1 use super::{Cipher, User}; 2 3 db_object! { 4 #[derive(Identifiable, Queryable, Insertable, Associations)] 5 #[table_name = "favorites"] 6 #[belongs_to(User, foreign_key = "user_uuid")] 7 #[belongs_to(Cipher, foreign_key = "cipher_uuid")] 8 #[primary_key(user_uuid, cipher_uuid)] 9 pub struct Favorite { 10 pub user_uuid: String, 11 pub cipher_uuid: String, 12 } 13 } 14 15 use crate::db::DbConn; 16 17 use crate::api::EmptyResult; 18 use crate::error::MapResult; 19 20 impl Favorite { 21 // Returns whether the specified cipher is a favorite of the specified user. is_favorite(cipher_uuid: &str, user_uuid: &str, conn: &DbConn) -> bool22 pub fn is_favorite(cipher_uuid: &str, user_uuid: &str, conn: &DbConn) -> bool { 23 db_run! { conn: { 24 let query = favorites::table 25 .filter(favorites::cipher_uuid.eq(cipher_uuid)) 26 .filter(favorites::user_uuid.eq(user_uuid)) 27 .count(); 28 29 query.first::<i64>(conn).ok().unwrap_or(0) != 0 30 }} 31 } 32 33 // Sets whether the specified cipher is a favorite of the specified user. set_favorite(favorite: bool, cipher_uuid: &str, user_uuid: &str, conn: &DbConn) -> EmptyResult34 pub fn set_favorite(favorite: bool, cipher_uuid: &str, user_uuid: &str, conn: &DbConn) -> EmptyResult { 35 let (old, new) = (Self::is_favorite(cipher_uuid, user_uuid, conn), favorite); 36 match (old, new) { 37 (false, true) => { 38 User::update_uuid_revision(user_uuid, conn); 39 db_run! { conn: { 40 diesel::insert_into(favorites::table) 41 .values(( 42 favorites::user_uuid.eq(user_uuid), 43 favorites::cipher_uuid.eq(cipher_uuid), 44 )) 45 .execute(conn) 46 .map_res("Error adding favorite") 47 }} 48 } 49 (true, false) => { 50 User::update_uuid_revision(user_uuid, conn); 51 db_run! { conn: { 52 diesel::delete( 53 favorites::table 54 .filter(favorites::user_uuid.eq(user_uuid)) 55 .filter(favorites::cipher_uuid.eq(cipher_uuid)) 56 ) 57 .execute(conn) 58 .map_res("Error removing favorite") 59 }} 60 } 61 // Otherwise, the favorite status is already what it should be. 62 _ => Ok(()), 63 } 64 } 65 66 // Delete all favorite entries associated with the specified cipher. delete_all_by_cipher(cipher_uuid: &str, conn: &DbConn) -> EmptyResult67 pub fn delete_all_by_cipher(cipher_uuid: &str, conn: &DbConn) -> EmptyResult { 68 db_run! { conn: { 69 diesel::delete(favorites::table.filter(favorites::cipher_uuid.eq(cipher_uuid))) 70 .execute(conn) 71 .map_res("Error removing favorites by cipher") 72 }} 73 } 74 75 // Delete all favorite entries associated with the specified user. delete_all_by_user(user_uuid: &str, conn: &DbConn) -> EmptyResult76 pub fn delete_all_by_user(user_uuid: &str, conn: &DbConn) -> EmptyResult { 77 db_run! { conn: { 78 diesel::delete(favorites::table.filter(favorites::user_uuid.eq(user_uuid))) 79 .execute(conn) 80 .map_res("Error removing favorites by user") 81 }} 82 } 83 } 84