use meshtastic::protobufs::MyNodeInfo; use sqlx::{ migrate::{MigrateDatabase, Migrator}, sqlite::SqlitePool, Executor, Pool, Sqlite, }; #[derive(Debug, sqlx::FromRow)] pub(crate) struct Device { pub(crate) id: i64, pub(crate) node_num: u32, pub(crate) long_name: String, pub(crate) space: String, pub(crate) control_room: String, } #[derive(Debug, sqlx::FromRow)] pub(crate) struct RemoteUser { pub(crate) id: i64, pub(crate) device: i64, pub(crate) node_id: u64, pub(crate) node_short_name: String, pub(crate) node_name: String, pub(crate) room: String, } pub(crate) struct DB { pool: Pool, } pub(crate) async fn setup(db_url: String) -> Result> { if !Sqlite::database_exists(&db_url).await.unwrap_or(false) { log::debug!("Creating database {}", &db_url); match Sqlite::create_database(&db_url).await { Ok(_) => log::debug!("Created db successfully"), Err(error) => panic!("error: {}", error), } } log::debug!("connecting to database {}", db_url); let pool = SqlitePool::connect(&db_url).await?; log::info!("running migrations"); sqlx::migrate!("./migrations") .run(&pool) .await .expect("error running db migrations"); Ok(DB { pool: pool }) } impl DB { pub async fn get_device( self: DB, node_num: i32, ) -> Result, Box> { let query = sqlx::query_as::<_, Device>("SELECT * FROM devices WHERE node_num = ? LIMIT 1"); let device = query.bind(node_num).fetch_one(&self.pool).await?; Ok(Option::Some(device)) } pub async fn upsert_device(self: DB, device: Device) -> Result<(), Box> { let query = sqlx::query("INSERT INTO devices (node_num, space, control_room) VALUES (?, ?, ?) ON CONFLICT(node_num) DO UPDATE SET space=excluded.space, control_room=excluded.control_room) WHERE node_num=excluded.node_num;"); query .bind(device.node_num) .bind(device.space) .bind(device.control_room) .execute(&self.pool) .await?; Ok(()) } pub async fn close(self: DB) { self.pool.close().await } }