You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
102 lines
3.6 KiB
102 lines
3.6 KiB
use diesel::prelude::*;
|
|
|
|
use crate::{
|
|
api::EmptyResult,
|
|
db::{DbConn, schema::favorites},
|
|
error::MapResult,
|
|
};
|
|
|
|
use super::{CipherId, User, UserId};
|
|
|
|
#[derive(Identifiable, Queryable, Insertable)]
|
|
#[diesel(table_name = favorites)]
|
|
#[diesel(primary_key(user_uuid, cipher_uuid))]
|
|
pub struct Favorite {
|
|
pub user_uuid: UserId,
|
|
pub cipher_uuid: CipherId,
|
|
}
|
|
|
|
impl Favorite {
|
|
// Returns whether the specified cipher is a favorite of the specified user.
|
|
pub async fn is_favorite(cipher_uuid: &CipherId, user_uuid: &UserId, conn: &DbConn) -> bool {
|
|
conn.run(move |conn| {
|
|
let query = favorites::table
|
|
.filter(favorites::cipher_uuid.eq(cipher_uuid))
|
|
.filter(favorites::user_uuid.eq(user_uuid))
|
|
.count();
|
|
|
|
query.first::<i64>(conn).ok().unwrap_or(0) != 0
|
|
})
|
|
.await
|
|
}
|
|
|
|
// Sets whether the specified cipher is a favorite of the specified user.
|
|
pub async fn set_favorite(
|
|
favorite: bool,
|
|
cipher_uuid: &CipherId,
|
|
user_uuid: &UserId,
|
|
conn: &DbConn,
|
|
) -> EmptyResult {
|
|
let (old, new) = (Self::is_favorite(cipher_uuid, user_uuid, conn).await, favorite);
|
|
match (old, new) {
|
|
(false, true) => {
|
|
User::update_uuid_revision(user_uuid, conn).await;
|
|
conn.run(move |conn| {
|
|
diesel::insert_into(favorites::table)
|
|
.values((favorites::user_uuid.eq(user_uuid), favorites::cipher_uuid.eq(cipher_uuid)))
|
|
.execute(conn)
|
|
.map_res("Error adding favorite")
|
|
})
|
|
.await
|
|
}
|
|
(true, false) => {
|
|
User::update_uuid_revision(user_uuid, conn).await;
|
|
conn.run(move |conn| {
|
|
diesel::delete(
|
|
favorites::table
|
|
.filter(favorites::user_uuid.eq(user_uuid))
|
|
.filter(favorites::cipher_uuid.eq(cipher_uuid)),
|
|
)
|
|
.execute(conn)
|
|
.map_res("Error removing favorite")
|
|
})
|
|
.await
|
|
}
|
|
// Otherwise, the favorite status is already what it should be.
|
|
_ => Ok(()),
|
|
}
|
|
}
|
|
|
|
// Delete all favorite entries associated with the specified cipher.
|
|
pub async fn delete_all_by_cipher(cipher_uuid: &CipherId, conn: &DbConn) -> EmptyResult {
|
|
conn.run(move |conn| {
|
|
diesel::delete(favorites::table.filter(favorites::cipher_uuid.eq(cipher_uuid)))
|
|
.execute(conn)
|
|
.map_res("Error removing favorites by cipher")
|
|
})
|
|
.await
|
|
}
|
|
|
|
// Delete all favorite entries associated with the specified user.
|
|
pub async fn delete_all_by_user(user_uuid: &UserId, conn: &DbConn) -> EmptyResult {
|
|
conn.run(move |conn| {
|
|
diesel::delete(favorites::table.filter(favorites::user_uuid.eq(user_uuid)))
|
|
.execute(conn)
|
|
.map_res("Error removing favorites by user")
|
|
})
|
|
.await
|
|
}
|
|
|
|
/// Return a vec with (cipher_uuid) this will only contain favorite flagged ciphers
|
|
/// This is used during a full sync so we only need one query for all favorite cipher matches.
|
|
pub async fn get_all_cipher_uuid_by_user(user_uuid: &UserId, conn: &DbConn) -> Vec<CipherId> {
|
|
conn.run(move |conn| {
|
|
favorites::table
|
|
.filter(favorites::user_uuid.eq(user_uuid))
|
|
.select(favorites::cipher_uuid)
|
|
.load::<CipherId>(conn)
|
|
.unwrap_or_default()
|
|
})
|
|
.await
|
|
}
|
|
}
|
|
|