use diesel::prelude::*; use dotenvy::dotenv; use std::env; pub mod models; pub mod schema; pub fn establish_connection() -> SqliteConnection { dotenv().ok(); let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set"); SqliteConnection::establish(&database_url) .unwrap_or_else(|_| panic!("Error connecting to {}", database_url)) } pub fn create_app( conn: &mut SqliteConnection, name: &str, address: &str, description: Option<&str>, ssh_address: Option<&str>, ) -> models::App { use crate::db::schema::app; let new_app = models::App { id: uuid::Uuid::new_v4().to_string(), name: name.to_string(), description: description.map(|d| d.to_string()), address: address.to_string(), ssh_address: ssh_address.map(|s| s.to_string()), }; diesel::insert_into(app::table) .values(&new_app) .execute(conn) .expect("Error saving new app"); new_app } pub fn get_apps(conn: &mut SqliteConnection) -> Vec { use crate::db::schema::app; app::table .load::(conn) .expect("Error loading apps") } pub fn delete_app(conn: &mut SqliteConnection, app_id: &str) -> usize { use crate::db::schema::app::dsl::*; diesel::delete(app.filter(id.eq(app_id))) .execute(conn) .expect("Error deleting app") } pub fn create_blog_db( conn: &mut SqliteConnection, title: &str, content: &str, linked_app_ids: Option<&[String]>, ) -> models::Blog { use crate::db::schema::blog; // json seralize the referenced app ids, store as string if let Some(ids) = linked_app_ids { for id in ids { // Check if the app exists in the database let app_exists = crate::db::schema::app::dsl::app .filter(crate::db::schema::app::dsl::id.eq(id)) .first::(conn) .optional() .expect("Error checking if app exists"); if app_exists.is_none() { panic!("App with id {} does not exist", id); } } } // if there are linked app ids, serialize them to json, else set to None let reference: Option = if let Some(ids) = linked_app_ids { Some(serde_json::to_string(&ids).expect("Failed to convert to JSON")) } else { None }; let new_blog = models::Blog { id: uuid::Uuid::new_v4().to_string(), title: title.to_string(), content: content.to_string(), reference, }; diesel::insert_into(blog::table) .values(&new_blog) .execute(conn) .expect("Error saving new blog"); new_blog } // Will be used to update an existing blog post OR create a new one if it doesn't exist pub fn save_blog( conn: &mut SqliteConnection, blog_id: Option<&str>, title: &str, content: &str, linked_app_ids: Option<&[String]>, ) -> models::Blog { use crate::db::schema::blog; // json seralize the referenced app ids, store as string let reference: Option = if let Some(ids) = linked_app_ids { Some(serde_json::to_string(&ids).expect("Failed to convert to JSON")) } else { None }; if let Some(id) = blog_id { // Update existing blog diesel::update(blog::table.filter(blog::id.eq(id))) .set(( blog::title.eq(title), blog::content.eq(content), blog::reference.eq(reference), )) .execute(conn) .expect("Error updating blog"); blog::table .filter(blog::id.eq(id)) .first::(conn) .expect("Error loading updated blog") } else { // Create new blog create_blog_db(conn, title, content, linked_app_ids) } }