Report update statistics

This commit is contained in:
Joshua Coles 2024-03-03 20:49:27 +00:00
parent 7759632848
commit 479389dde6
3 changed files with 48 additions and 20 deletions

View File

@ -13,7 +13,7 @@ use sea_orm::{
use std::ops::Sub;
use migration::Order;
use tracing::instrument;
use crate::sync_service::update_database;
use crate::sync_service::{update_database, UpdateStats};
#[tracing::instrument(skip(client, db))]
pub async fn poll_job(client: TogglApiClient, db: DatabaseConnection, poll_period: u64) {
@ -23,10 +23,10 @@ pub async fn poll_job(client: TogglApiClient, db: DatabaseConnection, poll_perio
loop {
tracing::info!("Polling Toggl API");
match perform_poll(&client, &db).await {
Ok(report_entries_count) => {
Ok(poll_update_data) => {
tracing::info!(
"Successfully polled Toggl API: {:?} entries retrieved",
report_entries_count
"Successfully polled Toggl API: {:?}",
poll_update_data
);
}
@ -43,7 +43,7 @@ pub async fn poll_job(client: TogglApiClient, db: DatabaseConnection, poll_perio
pub async fn perform_poll(
toggl_client: &TogglApiClient,
db: &DatabaseConnection,
) -> utils::Result<usize> {
) -> utils::Result<UpdateStats> {
let since = time_entry::Entity::find()
.select_only()
.column(time_entry::Column::ServerUpdatedAt)
@ -68,7 +68,5 @@ pub async fn perform_poll(
toggl_client,
&time_entries,
None,
).await?;
Ok(time_entries.len())
).await
}

View File

@ -12,6 +12,7 @@ use serde::Deserialize;
use serde_json::Value;
use std::collections::HashMap;
use tracing::{instrument};
use crate::sync_service::UpdateStats;
#[instrument(skip(db, toggl_client))]
pub async fn report(
@ -119,7 +120,7 @@ pub async fn refresh(
Extension(toggl_client): Extension<TogglApiClient>,
Extension(db): Extension<DatabaseConnection>,
Query(RefreshQuery { start_date, end_date }): Query<RefreshQuery>,
) -> utils::Result<&'static str> {
) -> utils::Result<Json<UpdateStats>> {
let time_entries = match (start_date, end_date) {
(Some(start_date), Some(end_date)) => {
toggl_client.fetch_time_entries_in_range(start_date, end_date).await?
@ -144,7 +145,5 @@ pub async fn refresh(
&toggl_client,
&time_entries,
None,
).await?;
Ok("Ok")
).await.map(Json)
}

View File

@ -4,29 +4,52 @@ use crate::toggl_api::types::{Client, Project, ReportRow, TimeEntry as ToggleApi
use crate::utils;
use migration::Condition;
use sea_orm::{ColumnTrait, DatabaseConnection, EntityTrait, QueryFilter, QuerySelect};
use tracing::{debug, instrument};
use serde::Serialize;
use crate::toggl_api::TogglApiClient;
#[derive(Debug, Serialize)]
pub struct UpdateStats {
retrieved: UpdateStatsInner,
written: UpdateStatsInner,
}
#[derive(Debug, Serialize)]
pub struct UpdateStatsInner {
updated: usize,
deleted: usize,
}
pub async fn update_database(
db: &DatabaseConnection,
toggl_client: &TogglApiClient,
time_entries: &[ToggleApiTimeEntry],
exclusive_on: Option<Condition>,
) -> utils::Result<()> {
) -> utils::Result<UpdateStats> {
let (deleted_entries, time_entries) = time_entries
.iter()
.partition::<Vec<_>, _>(|entry| entry.server_deleted_at.is_some());
let retrieved = UpdateStatsInner {
updated: time_entries.len(),
deleted: deleted_entries.len(),
};
let mut written = UpdateStatsInner {
updated: 0,
deleted: 0,
};
let deleted_ids = deleted_entries.iter()
.map(|entry| entry.id)
.collect::<Vec<_>>();
if !deleted_ids.is_empty() {
debug!("Deleting time entries: {:?}", deleted_ids);
TimeEntry::delete_many()
let delete_result = TimeEntry::delete_many()
.filter(time_entry::Column::TogglId.is_in(deleted_ids))
.exec(db)
.await?;
written.deleted = delete_result.rows_affected as usize;
}
let existing_project_ids = project::Entity::find()
@ -67,14 +90,19 @@ pub async fn update_database(
// TODO: Why is this needed?
if models.is_empty() {
return Ok(());
return Ok(UpdateStats {
retrieved,
written,
});
}
TimeEntry::insert_many(models)
let insert_result = TimeEntry::insert_many(models)
.on_conflict(ToggleApiTimeEntry::grafting_conflict_statement())
.exec(db)
.exec_without_returning(db)
.await?;
written.updated = insert_result as usize;
if let Some(exclusive_on) = exclusive_on {
TimeEntry::delete_many()
.filter(
@ -86,5 +114,8 @@ pub async fn update_database(
.await?;
}
Ok(())
Ok(UpdateStats {
retrieved,
written,
})
}