diff --git a/.sqlx/query-61bcc32d29fb7b162f3a51b5b463bc917ddce4a5fc292fb19036a88f697f9056.json b/.sqlx/query-a42862017ade20eb742a9761c1b581d4c902dfe12e36a504cc111a9d38407196.json similarity index 67% rename from .sqlx/query-61bcc32d29fb7b162f3a51b5b463bc917ddce4a5fc292fb19036a88f697f9056.json rename to .sqlx/query-a42862017ade20eb742a9761c1b581d4c902dfe12e36a504cc111a9d38407196.json index d491eb0..90529ac 100644 --- a/.sqlx/query-61bcc32d29fb7b162f3a51b5b463bc917ddce4a5fc292fb19036a88f697f9056.json +++ b/.sqlx/query-a42862017ade20eb742a9761c1b581d4c902dfe12e36a504cc111a9d38407196.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "SELECT * FROM commits WHERE hash = ?", + "query": "SELECT hash, author, author_date AS \"author_date: time::OffsetDateTime\", committer, committer_date AS \"committer_date: time::OffsetDateTime\", message, reachable FROM commits WHERE hash = ? ", "describe": { "columns": [ { @@ -14,7 +14,7 @@ "type_info": "Text" }, { - "name": "author_date", + "name": "author_date: time::OffsetDateTime", "ordinal": 2, "type_info": "Text" }, @@ -24,7 +24,7 @@ "type_info": "Text" }, { - "name": "committer_date", + "name": "committer_date: time::OffsetDateTime", "ordinal": 4, "type_info": "Text" }, @@ -37,11 +37,6 @@ "name": "reachable", "ordinal": 6, "type_info": "Int64" - }, - { - "name": "new", - "ordinal": 7, - "type_info": "Int64" } ], "parameters": { @@ -54,9 +49,8 @@ false, false, false, - false, false ] }, - "hash": "61bcc32d29fb7b162f3a51b5b463bc917ddce4a5fc292fb19036a88f697f9056" + "hash": "a42862017ade20eb742a9761c1b581d4c902dfe12e36a504cc111a9d38407196" } diff --git a/Cargo.lock b/Cargo.lock index 0d21fa1..702bc56 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2546,6 +2546,7 @@ dependencies = [ "smallvec", "sqlformat", "thiserror", + "time", "tokio", "tokio-stream", "tracing", @@ -2583,6 +2584,7 @@ dependencies = [ "sha2", "sqlx-core", "sqlx-mysql", + "sqlx-postgres", "sqlx-sqlite", "syn 1.0.109", "tempfile", @@ -2628,6 +2630,7 @@ dependencies = [ "sqlx-core", "stringprep", "thiserror", + "time", "tracing", "whoami", ] @@ -2667,6 +2670,7 @@ dependencies = [ "sqlx-core", "stringprep", "thiserror", + "time", "tracing", "whoami", ] @@ -2689,6 +2693,7 @@ dependencies = [ "percent-encoding", "serde", "sqlx-core", + "time", "tracing", "url", ] diff --git a/Cargo.toml b/Cargo.toml index 68ee155..b1bfece 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ humantime-serde = "1.1.1" mime_guess = "2.0.4" rust-embed = "6.8.1" serde = { version = "1.0.181", features = ["derive"] } -sqlx = { version = "0.7.1", features = ["runtime-tokio", "sqlite"] } +sqlx = { version = "0.7.1", features = ["runtime-tokio", "sqlite", "time"] } time = { version = "0.3.25", features = ["formatting", "macros", "parsing"] } tokio = { version = "1.29.1", features = ["full"] } toml = "0.7.6" diff --git a/src/main.rs b/src/main.rs index 726a0ee..29c0467 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,8 @@ mod config; -mod db; mod recurring; mod somehow; mod state; +mod util; mod web; use std::{io, path::PathBuf, process}; @@ -130,7 +130,7 @@ async fn run() -> somehow::Result<()> { // running. Maybe this is due to the thread pool not deferring blocking // work to a separate thread? In any case, replacing it with a sleep // doesn't block the signals. - // + // // In order to fix this, I could maybe register a bare signal handler // (instead of using tokio streams) that just calls process::exit(1) and // nothing else? diff --git a/src/db.rs b/src/util.rs similarity index 68% rename from src/db.rs rename to src/util.rs index 8e4fb8f..dafcaf7 100644 --- a/src/db.rs +++ b/src/util.rs @@ -1,12 +1,17 @@ use std::time::Duration; -use time::{format_description::well_known::Rfc3339, macros::format_description, OffsetDateTime}; +use gix::date::Time; +use time::{macros::format_description, OffsetDateTime, UtcOffset}; use crate::somehow; -pub fn format_time(time: &str) -> somehow::Result { +pub fn time_to_offset_datetime(time: Time) -> somehow::Result { + Ok(OffsetDateTime::from_unix_timestamp(time.seconds)? + .to_offset(UtcOffset::from_whole_seconds(time.offset)?)) +} + +pub fn format_time(time: OffsetDateTime) -> somehow::Result { let now = OffsetDateTime::now_utc(); - let time = OffsetDateTime::parse(time, &Rfc3339)?; let delta = time - now; let formatted_time = time.format(format_description!( @@ -21,7 +26,7 @@ pub fn format_time(time: &str) -> somehow::Result { }) } -pub fn summary(message: &str) -> String { +pub fn format_commit_summary(message: &str) -> String { // Take everything up to the first double newline let title = message .split_once("\n\n") @@ -34,6 +39,6 @@ pub fn summary(message: &str) -> String { pub fn format_commit_short(hash: &str, message: &str) -> String { let short_hash = hash.chars().take(8).collect::(); - let summary = summary(message); + let summary = format_commit_summary(message); format!("{short_hash} ({summary})") } diff --git a/src/web/commit_hash.rs b/src/web/commit_hash.rs index 944ac4b..03b4e1c 100644 --- a/src/web/commit_hash.rs +++ b/src/web/commit_hash.rs @@ -7,7 +7,7 @@ use axum::{ use futures::TryStreamExt; use sqlx::SqlitePool; -use crate::{config::Config, db, somehow}; +use crate::{config::Config, somehow, util}; struct Commit { hash: String, @@ -18,7 +18,7 @@ struct Commit { impl Commit { fn new(hash: String, message: &str, reachable: i64) -> Self { Self { - short: db::format_commit_short(&hash, message), + short: util::format_commit_short(&hash, message), hash, reachable, } @@ -48,9 +48,23 @@ pub async fn get( State(config): State<&'static Config>, State(db): State, ) -> somehow::Result { - let Some(commit) = sqlx::query!("SELECT * FROM commits WHERE hash = ?", hash) - .fetch_optional(&db) - .await? + let Some(commit) = sqlx::query!( + "\ + SELECT \ + hash, \ + author, \ + author_date AS \"author_date: time::OffsetDateTime\", \ + committer, \ + committer_date AS \"committer_date: time::OffsetDateTime\", \ + message, \ + reachable \ + FROM commits \ + WHERE hash = ? \ + ", + hash + ) + .fetch_optional(&db) + .await? else { return Ok(StatusCode::NOT_FOUND.into_response()); }; @@ -89,12 +103,12 @@ pub async fn get( current: "commit".to_string(), hash: commit.hash, author: commit.author, - author_date: db::format_time(&commit.author_date)?, + author_date: util::format_time(commit.author_date)?, commit: commit.committer, - commit_date: db::format_time(&commit.committer_date)?, + commit_date: util::format_time(commit.committer_date)?, parents, children, - summary: db::summary(&commit.message), + summary: util::format_commit_summary(&commit.message), message: commit.message.trim_end().to_string(), reachable: commit.reachable, } diff --git a/src/web/index.rs b/src/web/index.rs index fd8a861..daf359f 100644 --- a/src/web/index.rs +++ b/src/web/index.rs @@ -3,7 +3,7 @@ use axum::{extract::State, response::IntoResponse}; use futures::TryStreamExt; use sqlx::SqlitePool; -use crate::{config::Config, db, somehow}; +use crate::{config::Config, somehow, util}; struct Ref { name: String, @@ -36,7 +36,7 @@ pub async fn get( .fetch(&db) .map_ok(|r| Ref { name: r.name, - short: db::format_commit_short(&r.hash, &r.message), + short: util::format_commit_short(&r.hash, &r.message), hash: r.hash, tracked: r.tracked != 0, })