changeset 6:204877b11751

Enable (in theory) postgres interoperability, manage asset path
author Lewin Bormann <lbo@spheniscida.de>
date Sat, 09 Jul 2022 18:12:38 -0700
parents 2101c91aad43
children f06a74b14e94
files Cargo.toml Rocket.toml schema_sqlite.sql src/main.rs
diffstat 4 files changed, 47 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/Cargo.toml	Sat Jul 09 16:25:07 2022 -0700
+++ b/Cargo.toml	Sat Jul 09 18:12:38 2022 -0700
@@ -11,8 +11,13 @@
 env_logger = "0.9.0"
 log = "0.4.17"
 rocket = { version = "0.5.0-rc.2", features = ["secrets"] }
-rocket_db_pools = { version = "0.1.0-rc.2", features = ["sqlx_sqlite"] }
+rocket_db_pools = { version = "0.1.0-rc.2", features = ["sqlx_sqlite", "sqlx_postgres"] }
 rocket_dyn_templates = { version = "0.1.0-rc.2", features = ["handlebars"] }
 sha256 = "1.0.3"
 time = "0.3.11"
 tokio = { version = "1.19.2", features = ["fs"] }
+
+[features]
+default = ["sqlite"]
+sqlite = []
+postgres = []
--- a/Rocket.toml	Sat Jul 09 16:25:07 2022 -0700
+++ b/Rocket.toml	Sat Jul 09 18:12:38 2022 -0700
@@ -1,9 +1,18 @@
+[pg.databases.sqlite_main]
+url = "postgresql://lbo?host=/var/run/postgresql"
+
+[pg.databases.sqlite_logs]
+url = "postgresql://lbo?host=/var/run/postgresql"
+
 [default.databases.sqlite_main]
 url = "/home/lbo/dev/rust/analyrics/dev.sqlite"
+
 [default.databases.sqlite_logs]
 url = "/home/lbo/dev/rust/analyrics/devlogs.sqlite"
+max_connections = 8
 
 [default]
 port = 8000
 secret_key = "edeaaff3f1774ad2888673770c6d64097e391bc362d7d6fb34982ddf0efd18cb"
 template_dir = "assets"
+asset_path = "assets"
--- a/schema_sqlite.sql	Sat Jul 09 16:25:07 2022 -0700
+++ b/schema_sqlite.sql	Sat Jul 09 18:12:38 2022 -0700
@@ -5,5 +5,5 @@
     username TEXT,
     name TEXT,
     salt TEXT,
-    password_hash TEXT,
+    password_hash TEXT
 );
--- a/src/main.rs	Sat Jul 09 16:25:07 2022 -0700
+++ b/src/main.rs	Sat Jul 09 18:12:38 2022 -0700
@@ -12,25 +12,35 @@
 use rocket::response::{self, Flash, Redirect, Responder, Response};
 
 use rocket_db_pools::sqlx::{
-    self, pool::PoolConnection, Executor, Row, Sqlite, SqlitePool, Statement,
+    self, pool::PoolConnection, Executor, PgPool, Postgres, Row, Sqlite, SqlitePool, Statement,
 };
 use rocket_db_pools::{Connection, Database, Pool};
 
 use rocket_dyn_templates::{context, Template};
 
-use std::io;
 use std::net::IpAddr;
 use std::path::Path;
 
 use tokio::fs::{self, File};
 
+#[cfg(feature = "sqlite")]
+type DBType = Sqlite;
+#[cfg(feature = "sqlite")]
+type PoolType = SqlitePool;
+
+// Current SQL queries don't work with postgres.
+#[cfg(feature = "postgres")]
+type DBType = Postgres;
+#[cfg(feature = "postgres")]
+type PoolType = PgPool;
+
 // TO DO: use other databases?
 #[derive(Database)]
 #[database("sqlite_main")]
-struct ConfigDB(SqlitePool);
+struct ConfigDB(PoolType);
 
 async fn check_user_password<S: AsRef<str>>(
-    conn: &mut PoolConnection<Sqlite>,
+    conn: &mut PoolConnection<DBType>,
     user: S,
     password: S,
 ) -> Result<bool, Error> {
@@ -45,7 +55,7 @@
 
 #[derive(Database)]
 #[database("sqlite_logs")]
-struct LogsDB(SqlitePool);
+struct LogsDB(PoolType);
 
 async fn log_request<
     S1: AsRef<str>,
@@ -55,18 +65,18 @@
     S5: AsRef<str>,
     S6: AsRef<str>,
 >(
-    conn: &mut PoolConnection<Sqlite>,
+    conn: &mut PoolConnection<DBType>,
     session: Option<u32>,
     ip: S1,
     domain: S2,
     path: S3,
-    status: u16,
+    status: u32,
     page: Option<S4>,
     refer: Option<S5>,
     ua: S6,
     ntags: u32,
 ) -> Result<u32, Error> {
-    let q = sqlx::query("INSERT INTO RequestLog (session, ip, atime, domain, path, status, pagename, refer, ua, ntags) VALUES (?, ?, strftime('%s', 'now'), ?, ?, ?, ?, ?, ?, ?) RETURNING id");
+    let q = sqlx::query::<DBType>("INSERT INTO RequestLog (session, ip, atime, domain, path, status, pagename, refer, ua, ntags) VALUES (?, ?, strftime('%s', 'now'), ?, ?, ?, ?, ?, ?, ?) RETURNING id");
     let q = q
         .bind(session)
         .bind(ip.as_ref())
@@ -82,7 +92,7 @@
 }
 
 async fn log_tags<S: AsRef<str>, I: Iterator<Item = S>>(
-    conn: &mut PoolConnection<Sqlite>,
+    conn: &mut PoolConnection<DBType>,
     requestid: u32,
     tags: I,
 ) -> Result<usize, Error> {
@@ -103,13 +113,13 @@
     Ok(ntags)
 }
 
-async fn start_session(conn: &mut PoolConnection<Sqlite>) -> Result<u32, Error> {
+async fn start_session(conn: &mut PoolConnection<DBType>) -> Result<u32, Error> {
     Ok(sqlx::query("INSERT INTO Sessions (start, last) VALUES (strftime('%s', 'now'), strftime('%s', 'now')) RETURNING id")
         .fetch_one(conn)
         .await?.get(0))
 }
 
-async fn update_session_time(conn: &mut PoolConnection<Sqlite>, id: u32) -> Result<(), Error> {
+async fn update_session_time(conn: &mut PoolConnection<DBType>, id: u32) -> Result<(), Error> {
     sqlx::query("UPDATE Sessions SET last = strftime('%s', 'now') WHERE id = ?")
         .bind(id)
         .execute(conn)
@@ -146,10 +156,6 @@
     }
 }
 
-async fn asset<P: AsRef<Path>>(p: P) -> io::Result<File> {
-    fs::OpenOptions::new().read(true).open(p).await
-}
-
 #[derive(Responder)]
 enum LoginResponse {
     // use templates later.
@@ -254,11 +260,12 @@
     mut conn: Connection<LogsDB>,
     cookies: &CookieJar<'_>,
     host: Option<String>,
-    status: Option<u16>,
+    status: Option<u32>,
     path: Option<String>,
     pagename: Option<String>,
     referer: Option<String>,
     tags: Vec<String>,
+    config: &rocket::State<CustomConfig>,
     ip: IpAddr,
     headers: HeadersGuard<'_>,
 ) -> (Status, Either<NamedFile, &'static str>) {
@@ -319,22 +326,28 @@
         }
     }
 
-    if let Ok(f) = NamedFile::open("assets/pixel.png").await {
+    if let Ok(f) = NamedFile::open(Path::new(config.asset_path.as_str()).join("pixel.png")).await {
         (Status::Ok, Either::Left(f))
     } else {
         (Status::Ok, Either::Right(""))
     }
 }
 
+#[derive(rocket::serde::Deserialize)]
+#[serde(crate = "rocket::serde")]
+struct CustomConfig {
+    asset_path: String,
+}
+
 #[rocket::launch]
 fn rocketmain() -> _ {
     env_logger::init();
 
-    info!("{:?}", rocket::Config::figment());
     rocket::build()
         .attach(ConfigDB::init())
         .attach(LogsDB::init())
         .attach(Template::fairing())
+        .attach(rocket::fairing::AdHoc::config::<CustomConfig>())
         .mount(
             "/",
             rocket::routes![