use diesel::prelude::*; #[cfg(any( not(hottub_single_provider), hottub_provider = "hanime", hottub_provider = "hentaihaven", hottub_provider = "missav", hottub_provider = "perverzija", ))] pub fn get_video( conn: &mut SqliteConnection, video_id: String, ) -> Result, diesel::result::Error> { use crate::models::DBVideo; use crate::schema::videos::dsl::*; let result = videos .filter(id.eq(video_id)) .first::(conn) .optional()?; match result { Some(video) => Ok(Some(video.url)), None => Ok(None), } } #[cfg(any( not(hottub_single_provider), hottub_provider = "hanime", hottub_provider = "hentaihaven", hottub_provider = "missav", hottub_provider = "perverzija", ))] pub fn insert_video( conn: &mut SqliteConnection, new_id: &str, new_url: &str, ) -> Result { use crate::models::DBVideo; use crate::schema::videos::dsl::*; diesel::insert_into(videos) .values(DBVideo { id: new_id.to_string(), url: new_url.to_string(), }) .execute(conn) } // Replace any existing rows for `new_id` with a single fresh row. The `videos` // table is created without a UNIQUE/PRIMARY KEY constraint, so a plain insert // would append duplicates and `get_video` (which reads the first match) would // keep returning the stalest copy. Delete-then-insert in a transaction keeps a // single, up-to-date entry per id so background refreshes actually take effect. #[cfg(any( not(hottub_single_provider), hottub_provider = "hanime", hottub_provider = "hentaihaven", hottub_provider = "missav", hottub_provider = "perverzija", ))] pub fn upsert_video( conn: &mut SqliteConnection, new_id: &str, new_url: &str, ) -> Result { use crate::models::DBVideo; use crate::schema::videos::dsl::*; conn.transaction(|conn| { diesel::delete(videos.filter(id.eq(new_id))).execute(conn)?; diesel::insert_into(videos) .values(DBVideo { id: new_id.to_string(), url: new_url.to_string(), }) .execute(conn) }) } #[cfg(any( not(hottub_single_provider), hottub_provider = "hanime", hottub_provider = "hentaihaven", hottub_provider = "missav", hottub_provider = "perverzija", ))] pub fn delete_video( conn: &mut SqliteConnection, video_id: String, ) -> Result { use crate::schema::videos::dsl::*; diesel::delete(videos.filter(id.eq(video_id))).execute(conn) } pub fn has_table( conn: &mut SqliteConnection, table_name: &str, ) -> Result { use diesel::sql_query; use diesel::sql_types::Text; #[derive(QueryableByName)] struct TableName { #[diesel(sql_type = Text)] #[diesel(column_name = name)] name: String, } let query = "SELECT name FROM sqlite_master WHERE type='table' AND name = ?1"; let rows = sql_query(query) .bind::(table_name) .load::(conn)?; let exists = rows.first().map(|r| !r.name.is_empty()).unwrap_or(false); Ok(exists) } pub fn create_table( conn: &mut SqliteConnection, create_sql: &str, ) -> Result<(), diesel::result::Error> { use diesel::sql_query; sql_query(create_sql).execute(conn)?; Ok(()) }