aboutsummaryrefslogtreecommitdiffstats
path: root/atuin-server
diff options
context:
space:
mode:
authorConrad Ludgate <conradludgate@gmail.com>2023-09-11 09:26:05 +0100
committerGitHub <noreply@github.com>2023-09-11 09:26:05 +0100
commitf90c01f702f6a98b041f766b6a1d857bc1b9afef (patch)
tree04a4755bd632abdcf398d0ce903163ed60a5a212 /atuin-server
parentUse `case` for Linux distro choice in `install.sh` (#1200) (diff)
downloadatuin-f90c01f702f6a98b041f766b6a1d857bc1b9afef.zip
replace chrono with time (#806)
* replace chrono with time * Fix test chrono usage --------- Co-authored-by: Ellie Huxtable <ellie@elliehuxtable.com>
Diffstat (limited to '')
-rw-r--r--atuin-server-database/Cargo.toml3
-rw-r--r--atuin-server-database/src/lib.rs98
-rw-r--r--atuin-server-database/src/models.rs8
-rw-r--r--atuin-server-postgres/Cargo.toml2
-rw-r--r--atuin-server-postgres/src/lib.rs11
-rw-r--r--atuin-server/Cargo.toml4
-rw-r--r--atuin-server/src/handlers/history.rs27
7 files changed, 73 insertions, 80 deletions
diff --git a/atuin-server-database/Cargo.toml b/atuin-server-database/Cargo.toml
index 8f1f775e..1b416f9b 100644
--- a/atuin-server-database/Cargo.toml
+++ b/atuin-server-database/Cargo.toml
@@ -13,9 +13,8 @@ repository = { workspace = true }
atuin-common = { path = "../atuin-common", version = "16.0.0" }
tracing = "0.1"
-chrono = { workspace = true }
+time = { workspace = true }
eyre = { workspace = true }
uuid = { workspace = true }
serde = { workspace = true }
async-trait = { workspace = true }
-chronoutil = "0.2.3"
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<T: std::error::Error + Into<time::error::Error>> From<T> for DbError {
+ fn from(value: T) -> Self {
+ DbError::Other(value.into().into())
+ }
+}
+
impl std::error::Error for DbError {}
pub type DbResult<T> = Result<T, DbError>;
@@ -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<i64>;
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<Vec<History>>;
@@ -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<i64> {
- 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<i64> {
- 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<i64> {
+ 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<i64> {
- 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<i64> {
+ 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<HashMap<u64, TimePeriodInfo>> {
// 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.
///
diff --git a/atuin-server-postgres/Cargo.toml b/atuin-server-postgres/Cargo.toml
index f490a976..703e1210 100644
--- a/atuin-server-postgres/Cargo.toml
+++ b/atuin-server-postgres/Cargo.toml
@@ -14,7 +14,7 @@ atuin-common = { path = "../atuin-common", version = "16.0.0" }
atuin-server-database = { path = "../atuin-server-database", version = "16.0.0" }
tracing = "0.1"
-chrono = { workspace = true }
+time = { workspace = true }
serde = { workspace = true }
sqlx = { workspace = true }
async-trait = { workspace = true }
diff --git a/atuin-server-postgres/src/lib.rs b/atuin-server-postgres/src/lib.rs
index aa523222..8f473d52 100644
--- a/atuin-server-postgres/src/lib.rs
+++ b/atuin-server-postgres/src/lib.rs
@@ -7,6 +7,7 @@ use serde::{Deserialize, Serialize};
use sqlx::postgres::PgPoolOptions;
use sqlx::Row;
+use time::{OffsetDateTime, PrimitiveDateTime};
use tracing::instrument;
use wrappers::{DbHistory, DbRecord, DbSession, DbUser};
@@ -139,7 +140,7 @@ impl Database for Postgres {
)
.bind(user.id)
.bind(id)
- .bind(chrono::Utc::now().naive_utc())
+ .bind(OffsetDateTime::now_utc())
.fetch_all(&self.pool)
.await
.map_err(fix_error)?;
@@ -175,8 +176,8 @@ impl Database for Postgres {
async fn count_history_range(
&self,
user: &User,
- start: chrono::NaiveDateTime,
- end: chrono::NaiveDateTime,
+ start: PrimitiveDateTime,
+ end: PrimitiveDateTime,
) -> DbResult<i64> {
let res: (i64,) = sqlx::query_as(
"select count(1) from history
@@ -198,8 +199,8 @@ impl Database for Postgres {
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<Vec<History>> {
diff --git a/atuin-server/Cargo.toml b/atuin-server/Cargo.toml
index f1c44b4c..1b9ad859 100644
--- a/atuin-server/Cargo.toml
+++ b/atuin-server/Cargo.toml
@@ -3,6 +3,7 @@ name = "atuin-server"
edition = "2018"
description = "server library for atuin"
+rust-version = { workspace = true }
version = { workspace = true }
authors = { workspace = true }
license = { workspace = true }
@@ -14,7 +15,7 @@ atuin-common = { path = "../atuin-common", version = "16.0.0" }
atuin-server-database = { path = "../atuin-server-database", version = "16.0.0" }
tracing = "0.1"
-chrono = { workspace = true }
+time = { workspace = true }
eyre = { workspace = true }
uuid = { workspace = true }
config = { workspace = true }
@@ -27,7 +28,6 @@ async-trait = { workspace = true }
axum = "0.6.4"
http = "0.2"
fs-err = { workspace = true }
-chronoutil = "0.2.3"
tower = "0.4"
tower-http = { version = "0.3", features = ["trace"] }
reqwest = { workspace = true }
diff --git a/atuin-server/src/handlers/history.rs b/atuin-server/src/handlers/history.rs
index bb0aa321..263d6cba 100644
--- a/atuin-server/src/handlers/history.rs
+++ b/atuin-server/src/handlers/history.rs
@@ -1,4 +1,4 @@
-use std::collections::HashMap;
+use std::{collections::HashMap, convert::TryFrom};
use axum::{
extract::{Path, Query, State},
@@ -6,6 +6,7 @@ use axum::{
Json,
};
use http::StatusCode;
+use time::Month;
use tracing::{debug, error, instrument};
use super::{ErrorResponse, ErrorResponseStatus, RespExt};
@@ -63,16 +64,10 @@ pub async fn list<DB: Database>(
};
let history = db
- .list_history(
- &user,
- req.sync_ts.naive_utc(),
- req.history_ts.naive_utc(),
- &req.host,
- page_size,
- )
+ .list_history(&user, req.sync_ts, req.history_ts, &req.host, page_size)
.await;
- if req.sync_ts.timestamp_nanos() < 0 || req.history_ts.timestamp_nanos() < 0 {
+ if req.sync_ts.unix_timestamp_nanos() < 0 || req.history_ts.unix_timestamp_nanos() < 0 {
error!("client asked for history from < epoch 0");
return Err(
ErrorResponse::reply("asked for history from before epoch 0")
@@ -139,7 +134,7 @@ pub async fn add<DB: Database>(
client_id: h.id,
user_id: user.id,
hostname: h.hostname,
- timestamp: h.timestamp.naive_utc(),
+ timestamp: h.timestamp,
data: h.data,
})
.collect();
@@ -182,11 +177,17 @@ pub async fn calendar<DB: Database>(
let year = params.get("year").unwrap_or(&0);
let month = params.get("month").unwrap_or(&1);
+ let month = Month::try_from(*month as u8).map_err(|e| ErrorResponseStatus {
+ error: ErrorResponse {
+ reason: e.to_string().into(),
+ },
+ status: http::StatusCode::BAD_REQUEST,
+ })?;
let db = &state.0.database;
let focus = match focus {
"year" => db
- .calendar(&user, TimePeriod::YEAR, *year, *month)
+ .calendar(&user, TimePeriod::YEAR, *year, month)
.await
.map_err(|_| {
ErrorResponse::reply("failed to query calendar")
@@ -194,7 +195,7 @@ pub async fn calendar<DB: Database>(
}),
"month" => db
- .calendar(&user, TimePeriod::MONTH, *year, *month)
+ .calendar(&user, TimePeriod::MONTH, *year, month)
.await
.map_err(|_| {
ErrorResponse::reply("failed to query calendar")
@@ -202,7 +203,7 @@ pub async fn calendar<DB: Database>(
}),
"day" => db
- .calendar(&user, TimePeriod::DAY, *year, *month)
+ .calendar(&user, TimePeriod::DAY, *year, month)
.await
.map_err(|_| {
ErrorResponse::reply("failed to query calendar")