From f90c01f702f6a98b041f766b6a1d857bc1b9afef Mon Sep 17 00:00:00 2001 From: Conrad Ludgate Date: Mon, 11 Sep 2023 09:26:05 +0100 Subject: replace chrono with time (#806) * replace chrono with time * Fix test chrono usage --------- Co-authored-by: Ellie Huxtable --- atuin-server-database/src/lib.rs | 98 +++++++++++++++++-------------------- atuin-server-database/src/models.rs | 8 +-- 2 files changed, 49 insertions(+), 57 deletions(-) (limited to 'atuin-server-database/src') diff --git a/atuin-server-database/src/lib.rs b/atuin-server-database/src/lib.rs index 06ecf910..4ebd517c 100644 --- a/atuin-server-database/src/lib.rs +++ b/atuin-server-database/src/lib.rs @@ -13,13 +13,9 @@ use self::{ models::{History, NewHistory, NewSession, NewUser, Session, User}, }; use async_trait::async_trait; -use atuin_common::{ - record::{EncryptedData, HostId, Record, RecordId, RecordIndex}, - utils::get_days_from_month, -}; -use chrono::{Datelike, TimeZone}; -use chronoutil::RelativeDuration; +use atuin_common::record::{EncryptedData, HostId, Record, RecordId, RecordIndex}; use serde::{de::DeserializeOwned, Serialize}; +use time::{Date, Duration, Month, OffsetDateTime, PrimitiveDateTime, Time}; use tracing::instrument; #[derive(Debug)] @@ -34,6 +30,12 @@ impl Display for DbError { } } +impl> From for DbError { + fn from(value: T) -> Self { + DbError::Other(value.into().into()) + } +} + impl std::error::Error for DbError {} pub type DbResult = Result; @@ -75,15 +77,15 @@ pub trait Database: Sized + Clone + Send + Sync + 'static { async fn count_history_range( &self, user: &User, - start: chrono::NaiveDateTime, - end: chrono::NaiveDateTime, + start: PrimitiveDateTime, + end: PrimitiveDateTime, ) -> DbResult; async fn list_history( &self, user: &User, - created_after: chrono::NaiveDateTime, - since: chrono::NaiveDateTime, + created_after: OffsetDateTime, + since: OffsetDateTime, host: &str, page_size: i64, ) -> DbResult>; @@ -95,53 +97,51 @@ pub trait Database: Sized + Clone + Send + Sync + 'static { /// Count the history for a given year #[instrument(skip_all)] async fn count_history_year(&self, user: &User, year: i32) -> DbResult { - let start = chrono::Utc.ymd(year, 1, 1).and_hms_nano(0, 0, 0, 0); - let end = start + RelativeDuration::years(1); + let start = Date::from_calendar_date(year, time::Month::January, 1)?; + let end = Date::from_calendar_date(year + 1, time::Month::January, 1)?; let res = self - .count_history_range(user, start.naive_utc(), end.naive_utc()) + .count_history_range( + user, + start.with_time(Time::MIDNIGHT), + end.with_time(Time::MIDNIGHT), + ) .await?; Ok(res) } /// Count the history for a given month #[instrument(skip_all)] - async fn count_history_month(&self, user: &User, month: chrono::NaiveDate) -> DbResult { - let start = chrono::Utc - .ymd(month.year(), month.month(), 1) - .and_hms_nano(0, 0, 0, 0); - - // ofc... - let end = if month.month() < 12 { - chrono::Utc - .ymd(month.year(), month.month() + 1, 1) - .and_hms_nano(0, 0, 0, 0) - } else { - chrono::Utc - .ymd(month.year() + 1, 1, 1) - .and_hms_nano(0, 0, 0, 0) - }; + async fn count_history_month(&self, user: &User, year: i32, month: Month) -> DbResult { + let start = Date::from_calendar_date(year, month, 1)?; + let days = time::util::days_in_year_month(year, month); + let end = start + Duration::days(days as i64); tracing::debug!("start: {}, end: {}", start, end); let res = self - .count_history_range(user, start.naive_utc(), end.naive_utc()) + .count_history_range( + user, + start.with_time(Time::MIDNIGHT), + end.with_time(Time::MIDNIGHT), + ) .await?; Ok(res) } /// Count the history for a given day #[instrument(skip_all)] - async fn count_history_day(&self, user: &User, day: chrono::NaiveDate) -> DbResult { - let start = chrono::Utc - .ymd(day.year(), day.month(), day.day()) - .and_hms_nano(0, 0, 0, 0); - let end = chrono::Utc - .ymd(day.year(), day.month(), day.day() + 1) - .and_hms_nano(0, 0, 0, 0); + async fn count_history_day(&self, user: &User, day: Date) -> DbResult { + let end = day + .next_day() + .ok_or_else(|| DbError::Other(eyre::eyre!("no next day?")))?; let res = self - .count_history_range(user, start.naive_utc(), end.naive_utc()) + .count_history_range( + user, + day.with_time(Time::MIDNIGHT), + end.with_time(Time::MIDNIGHT), + ) .await?; Ok(res) } @@ -152,7 +152,7 @@ pub trait Database: Sized + Clone + Send + Sync + 'static { user: &User, period: TimePeriod, year: u64, - month: u64, + month: Month, ) -> DbResult> { // TODO: Support different timezones. Right now we assume UTC and // everything is stored as such. But it _should_ be possible to @@ -164,7 +164,7 @@ pub trait Database: Sized + Clone + Send + Sync + 'static { // First we need to work out how far back to calculate. Get the // oldest history item let oldest = self.oldest_history(user).await?.timestamp.year(); - let current_year = chrono::Utc::now().year(); + let current_year = OffsetDateTime::now_utc().year(); // All the years we need to get data for // The upper bound is exclusive, so include current +1 @@ -188,13 +188,10 @@ pub trait Database: Sized + Clone + Send + Sync + 'static { TimePeriod::MONTH => { let mut ret = HashMap::new(); - for month in 1..13 { - let count = self - .count_history_month( - user, - chrono::Utc.ymd(year as i32, month, 1).naive_utc(), - ) - .await?; + let months = + std::iter::successors(Some(Month::January), |m| Some(m.next())).take(12); + for month in months { + let count = self.count_history_month(user, year as i32, month).await?; ret.insert( month as u64, @@ -211,14 +208,9 @@ pub trait Database: Sized + Clone + Send + Sync + 'static { TimePeriod::DAY => { let mut ret = HashMap::new(); - for day in 1..get_days_from_month(year as i32, month as u32) { + for day in 1..time::util::days_in_year_month(year as i32, month) { let count = self - .count_history_day( - user, - chrono::Utc - .ymd(year as i32, month as u32, day as u32) - .naive_utc(), - ) + .count_history_day(user, Date::from_calendar_date(year as i32, month, day)?) .await?; ret.insert( diff --git a/atuin-server-database/src/models.rs b/atuin-server-database/src/models.rs index 7183b1ec..b71a9bc9 100644 --- a/atuin-server-database/src/models.rs +++ b/atuin-server-database/src/models.rs @@ -1,25 +1,25 @@ -use chrono::prelude::*; +use time::OffsetDateTime; pub struct History { pub id: i64, pub client_id: String, // a client generated ID pub user_id: i64, pub hostname: String, - pub timestamp: NaiveDateTime, + pub timestamp: OffsetDateTime, /// All the data we have about this command, encrypted. /// /// Currently this is an encrypted msgpack object, but this may change in the future. pub data: String, - pub created_at: NaiveDateTime, + pub created_at: OffsetDateTime, } pub struct NewHistory { pub client_id: String, pub user_id: i64, pub hostname: String, - pub timestamp: chrono::NaiveDateTime, + pub timestamp: OffsetDateTime, /// All the data we have about this command, encrypted. /// -- cgit v1.3.1