From 3f9dcb3a53fdc6e7cc179e6eaa314d4df426d551 Mon Sep 17 00:00:00 2001 From: Tobias Maier Date: Sat, 16 Sep 2023 19:08:20 +0000 Subject: [PATCH] Switched over to migrations --- Cargo.toml | 4 +- migrations/1_devices.sql | 5 +++ migrations/2_telemetry.sql | 10 +++++ src/database.rs | 83 +++++++++++++++----------------------- src/main.rs | 6 ++- 5 files changed, 54 insertions(+), 54 deletions(-) create mode 100644 migrations/1_devices.sql create mode 100644 migrations/2_telemetry.sql diff --git a/Cargo.toml b/Cargo.toml index 372d914..8a7b5d1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,4 +9,6 @@ edition = "2021" actix-web = "4.4.0" env_logger = "0.10.0" log = "0.4.20" -sqlx = { version = "0.7", features = [ "runtime-tokio", "tls-rustls", "postgres" ] } +sqlx = { version = "0.7", features = [ "runtime-tokio", "tls-rustls", "postgres", "migrate"] } +sqlx-cli = "0.7.1" +thiserror = "1.0.48" diff --git a/migrations/1_devices.sql b/migrations/1_devices.sql new file mode 100644 index 0000000..1227047 --- /dev/null +++ b/migrations/1_devices.sql @@ -0,0 +1,5 @@ +-- Add migration script here +CREATE TABLE Devices ( + ID CHAR(32) PRIMARY KEY, + display_name VARCHAR(255) +); \ No newline at end of file diff --git a/migrations/2_telemetry.sql b/migrations/2_telemetry.sql new file mode 100644 index 0000000..6163d42 --- /dev/null +++ b/migrations/2_telemetry.sql @@ -0,0 +1,10 @@ +-- Add migration script here +CREATE TABLE Telemetry ( + timestamp TIMESTAMP NOT NULL, + Software_Version VARCHAR(255), + Voltage FLOAT, + Temperature FLOAT, + uptime FLOAT, + device_id CHAR(32), + FOREIGN KEY (device_id) REFERENCES Devices(ID) +); \ No newline at end of file diff --git a/src/database.rs b/src/database.rs index abb1cc8..2e2ef50 100644 --- a/src/database.rs +++ b/src/database.rs @@ -1,11 +1,19 @@ +use actix_web::cookie::time::error; use log::{error, info}; -use sqlx::{pool, postgres::PgPoolOptions, query, PgPool, Pool, Postgres}; +use sqlx::{pool, postgres::PgPoolOptions, query, PgPool, Pool, Postgres, migrate}; +use thiserror::Error; #[derive(Clone)] pub struct Database { conn_pool: Pool, } +#[derive(Error, Debug)] +pub enum DatabaseError { + #[error("Generic SQLX Error")] + SqlxError(#[from] sqlx::Error) +} + impl Database { pub async fn init(host: &str, user: &str, pass: &str, db_name: &str) -> Database { match PgPoolOptions::new() @@ -24,62 +32,31 @@ impl Database { } } - pub async fn add_telementry_table(&self) { - info!("Adding telementry table"); - let query = query!(" - CREATE TABLE Telemetry ( - timestamp TIMESTAMP NOT NULL, - Software_Version VARCHAR(255), - Voltage FLOAT, - Temperature FLOAT, - uptime FLOAT, - device_id INT, - FOREIGN KEY (device_id) REFERENCES Devices(ID) - ); - ").execute(&self.conn_pool).await; - if query.is_err(){ - error!("Error Creating telemetry table"); - std::process::exit(1); - } - info!("Successfully added telemetry table"); - } - - pub async fn add_devices_table(&self) { - info!("Adding devices table"); - let query = query!(" - CREATE TABLE Devices ( - ID INT PRIMARY KEY, - display_name VARCHAR(255) - ); - ").execute(&self.conn_pool).await; - if query.is_err(){ - error!("Error Creating telemetry table"); - std::process::exit(1); - } - info!("Successfully added devices table"); - } - // Check if the necessary tables exist. If not, create them. TODO auto-migration pub async fn init_db(&self) { info!("Checking if required tables exist"); - let devices_table = self.check_if_table_exists("Devices").await; - let telemetry_table = self.check_if_table_exists("Telementry").await; - - if !devices_table { - self.add_devices_table().await; - } - if !telemetry_table { - self.add_telementry_table().await; - } + match migrate!().run(&self.conn_pool).await{ + Ok(_) => {}, + Err(e) => { + error!("Error when running migrations {}", e); + std::process::exit(1); + } + }; } - async fn check_if_table_exists(&self, table_name: &str) -> bool { - info!("Checking if table {} exists", table_name); + pub async fn add_device(&self, device_id: &str) -> Result<(), DatabaseError> { + info!("Adding device with the ID {}", &device_id); + query!("INSERT INTO Devices (ID) VALUES ($1);", device_id).execute(&self.conn_pool).await?; + Ok(()) + } + + pub async fn create_device_if_not_exists(&self, device_id: &str) -> Result<(), DatabaseError> { + info!("Checking if device with the ID {} exists", &device_id); let exists_result = - query!("SELECT count(*) FROM information_schema.tables WHERE table_name = $1;", table_name) + query!("SELECT count(*) FROM devices WHERE ID = $1;", device_id) .fetch_one(&self.conn_pool) .await; - + let exists = match exists_result { Ok(res) => res.count > Some(0), Err(err) => { @@ -88,7 +65,11 @@ impl Database { } }; - info!("Table {} exists: {}", table_name, exists); - exists + if exists{ + Ok(()) + } else { + self.add_device(device_id).await?; + Ok(()) + } } } diff --git a/src/main.rs b/src/main.rs index 7f176a8..19f5a2f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,4 @@ -use actix_web::{post, web, App, HttpServer, Responder}; +use actix_web::{post, web, App, HttpServer, Responder, http::StatusCode, HttpResponse}; use database::Database; use log::info; @@ -13,7 +13,9 @@ async fn receive_telemetry( device_id: web::Path, data: web::Data, ) -> impl Responder { - format!("Hello {}!", &device_id) + data.db.create_device_if_not_exists(&device_id); + + HttpResponse::Ok() } #[actix_web::main]