From 863db0d616f952ceac10b92dde703bef5093469a Mon Sep 17 00:00:00 2001 From: Greg Burri Date: Fri, 11 Sep 2020 00:30:14 +0200 Subject: [PATCH] Add a DB module (not used for the moment) --- backend/src/consts.rs | 4 ++ backend/src/db.rs | 93 +++++++++++++++++++++++++++++++++++++++++++ backend/src/main.rs | 29 ++++++++------ backend/src/types.rs | 0 4 files changed, 113 insertions(+), 13 deletions(-) create mode 100644 backend/src/db.rs create mode 100644 backend/src/types.rs diff --git a/backend/src/consts.rs b/backend/src/consts.rs index 376dee8..87d4211 100644 --- a/backend/src/consts.rs +++ b/backend/src/consts.rs @@ -1,3 +1,7 @@ pub const FILE_CONF: &str = "conf.ron"; pub const FILE_KEY: &str = "key.secret"; + +pub const DB_DIRECTORY: &str = "data"; +pub const DB_FILENAME: &str = "db.sqlite"; + pub const DEFAULT_MESSAGE: &str = "Marc, roule un pet'!"; \ No newline at end of file diff --git a/backend/src/db.rs b/backend/src/db.rs new file mode 100644 index 0000000..2bae4fd --- /dev/null +++ b/backend/src/db.rs @@ -0,0 +1,93 @@ +use std::path::Path; +use std::fs; + +use r2d2_sqlite::SqliteConnectionManager; +use r2d2::Pool; + +use super::consts; + +const CURRENT_DB_VERSION: u32 = 1; + +pub struct Connection { + //con: rusqlite::Connection + pool: Pool +} + +pub struct Recipe { + pub title: String, + pub id: i32, +} + +impl Connection { + pub fn new() -> Connection { + + let data_dir = Path::new(consts::DB_DIRECTORY); + + if !data_dir.exists() { + fs::DirBuilder::new().create(data_dir).unwrap(); + } + + let manager = SqliteConnectionManager::file(consts::DB_FILENAME); + let pool = r2d2::Pool::new(manager).unwrap(); + + let connection = Connection { pool }; + connection.create_or_update(); + connection + } + + fn create_or_update(self: &Self) { + // let connection = Connection::new(); + // let mut stmt = connection.sqlite_con.prepare("SELECT * FROM versions ORDER BY date").unwrap(); + // let mut stmt = connection.sqlite_con..prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='versions'").unwrap(); + + // Check the Database version. + let con = self.pool.get().unwrap(); + + let version = { + match + con.query_row( + "SELECT [name] FROM [sqlite_master] WHERE [type] = 'table' AND [name] = 'Version'", + rusqlite::NO_PARAMS, + |row| row.get::(0) + ) { + Ok(_) => con.query_row("SELECT [version] FROM [Version]", rusqlite::NO_PARAMS, |row| row.get(0)).unwrap_or_default(), + Err(_) => 0 + } + }; + + match version { + 0 => { + println!("Update to version 1..."); + con.execute( + " + CREATE TABLE [Version] ( + [id] INTEGER PRIMARY KEY, + [version] INTEGER NOT NULL, + [datetime] INTEGER DATETIME + ) + ", + rusqlite::NO_PARAMS + ); + con.execute( + " + CREATE TABLE [SetLetterCommand] ( + [id] INTEGER PRIMARY KEY, + [pos_i] INTEGER NOT NULL, + [pos_j] INTEGER NOT NULL, + [color] INTEGER NULL, + [letter] INTEGER NOT NULL, + ) + ", + rusqlite::NO_PARAMS + ); + () + } + v => + panic!("Unsupported database version: {}", v) + }; + } + + pub fn insert_set_letter_command() { + + } +} \ No newline at end of file diff --git a/backend/src/main.rs b/backend/src/main.rs index ddd9b91..726fcf8 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -5,10 +5,10 @@ extern crate percent_encoding; use listenfd::ListenFd; use actix_files as fs; -use actix_web::{ web, middleware, App, HttpServer, HttpResponse, web::Query }; +use actix_web::{ get, web, Responder, middleware, App, HttpServer, HttpRequest, HttpResponse, web::Query }; use askama::Template; -use std::{ fs::File, path::Path, env::args, io::prelude::* }; +use std::{ sync::Mutex, fs::File, path::Path, env::args, io::prelude::* }; use ron::{ de::from_reader, ser::{ to_string_pretty, PrettyConfig } }; use serde::{ Deserialize, Serialize }; @@ -16,11 +16,13 @@ use itertools::Itertools; mod consts; mod crypto; +mod db; +mod types; #[derive(Template)] #[template(path = "main.html")] -struct MainTemplate<'a> { - sentence: &'a str, +struct MainTemplate { + sentence: String, } #[derive(Deserialize)] @@ -28,21 +30,21 @@ pub struct Request { m: Option } -fn main_page(query: Query, key: &str) -> HttpResponse { +#[get("/")] +async fn main_page(key_shared: web::Data>, query: Query) -> impl Responder { + let key = key_shared.lock().unwrap(); + let m = match &query.m { Some(b) => - match crypto::decrypt(key, b) { + match crypto::decrypt(&*key, b) { Ok(m) => m, Err(_e) => String::from(consts::DEFAULT_MESSAGE) // TODO: log error. }, None => String::from(consts::DEFAULT_MESSAGE) }; - let hello = MainTemplate { sentence: &m }; - - let s = hello.render().unwrap(); - HttpResponse::Ok().content_type("text/html").body(s) + MainTemplate { sentence: m } } #[derive(Debug, Deserialize, Serialize)] @@ -112,16 +114,17 @@ async fn main() -> std::io::Result<()> { println!("Configuration: {:?}", config); + let key_shared = web::Data::new(Mutex::new(key)); + let mut listenfd = ListenFd::from_env(); let mut server = HttpServer::new( move || { - let key = key.clone(); // Is this neccessary?? - App::new() + .app_data(key_shared.clone()) .wrap(middleware::Compress::default()) .wrap(middleware::Logger::default()) - .service(web::resource("/").to(move |query| main_page(query, &key))) + .service(main_page) .service(fs::Files::new("/static", "static").show_files_listing()) } ); diff --git a/backend/src/types.rs b/backend/src/types.rs new file mode 100644 index 0000000..e69de29 -- 2.43.0