Move all to SOA and tag time entries to join table as this should be how it works and also UNNEST doesn't support nested arrays

This commit is contained in:
Joshua Coles 2024-07-27 20:51:14 +01:00
parent 6f7db97ab6
commit 71f9ed3312
3 changed files with 58 additions and 42 deletions

View File

@ -0,0 +1,16 @@
-- Create a new join table to associate time_entries with tags
CREATE TABLE public.time_entry_tags (
time_entry_id bigint not null references public.time_entries(id) on delete cascade,
tag_id bigint not null references public.tags(id) on delete cascade,
primary key (time_entry_id, tag_id)
);
-- Insert data into the new join table based on the existing time_entries and tags data
INSERT INTO public.time_entry_tags (time_entry_id, tag_id)
SELECT time_entries.id, UNNEST(time_entries.tag_ids) AS tag_id
FROM public.time_entries
WHERE time_entries.tag_ids IS NOT NULL;
-- Remove the tag_ids array column from the time_entries table
ALTER TABLE public.time_entries
DROP COLUMN tag_ids;

View File

@ -1,7 +1,7 @@
use chrono::{DateTime, DurationRound, NaiveDate, TimeDelta, Utc}; use chrono::{DateTime, DurationRound, NaiveDate, TimeDelta, Utc};
use sqlx::{Connection, PgConnection, Postgres, QueryBuilder}; use sqlx::{Connection, PgConnection, Postgres, QueryBuilder};
use toggl::TogglApi; use toggl::TogglApi;
use crate::toggl::types::{Tag, TimeEntry, TogglReportFilters, TrackingClient}; use crate::toggl::types::{Project, Tag, TimeEntry, TogglReportFilters, TrackingClient};
use itertools::Itertools; use itertools::Itertools;
use soa_rs::Soa; use soa_rs::Soa;
use tracing_subscriber::fmt::time; use tracing_subscriber::fmt::time;
@ -218,46 +218,46 @@ impl Worker {
self.update_clients().await?; self.update_clients().await?;
} }
for project in projects { let projects: Soa<Project> = Soa::from(projects.as_slice());
sqlx::query!(
r#" sqlx::query!(
INSERT INTO projects (id, workspace_id, client_id, name, color, status, active, updated_at, start_date, created_at, server_deleted_at, actual_hours, actual_seconds, can_track_time, permissions) r#"
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15) INSERT INTO projects (id, workspace_id, client_id, name, color, status, active, updated_at, start_date, created_at, server_deleted_at, actual_hours, actual_seconds, can_track_time, permissions)
ON CONFLICT (id) DO UPDATE SET SELECT * FROM UNNEST($1::bigint[], $2::bigint[], $3::bigint[], $4::text[], $5::text[], $6::text[], $7::bool[], $8::timestamptz[], $9::date[], $10::timestamptz[], $11::timestamptz[], $12::int[], $13::int[], $14::bool[], $15::text[])
workspace_id = excluded.workspace_id, ON CONFLICT (id) DO UPDATE SET
client_id = excluded.client_id, workspace_id = excluded.workspace_id,
name = excluded.name, client_id = excluded.client_id,
color = excluded.color, name = excluded.name,
status = excluded.status, color = excluded.color,
active = excluded.active, status = excluded.status,
updated_at = excluded.updated_at, active = excluded.active,
start_date = excluded.start_date, updated_at = excluded.updated_at,
created_at = excluded.created_at, start_date = excluded.start_date,
server_deleted_at = excluded.server_deleted_at, created_at = excluded.created_at,
actual_hours = excluded.actual_hours, server_deleted_at = excluded.server_deleted_at,
actual_seconds = excluded.actual_seconds, actual_hours = excluded.actual_hours,
can_track_time = excluded.can_track_time, actual_seconds = excluded.actual_seconds,
permissions = excluded.permissions can_track_time = excluded.can_track_time,
"#, permissions = excluded.permissions
project.id, "#,
project.workspace_id, &projects.id().iter().map(|id| *id as i64).collect_vec()[..],
project.client_id, &projects.workspace_id().iter().map(|id| *id as i64).collect_vec()[..],
project.name, projects.client_id().iter().map(|opt| opt.map(|id| id as i64)).collect_vec() as _,
project.color, projects.name(),
project.status.to_string(), projects.color(),
project.active, &projects.status().iter().map(|s| s.to_string()).collect::<Vec<_>>()[..],
project.updated_at, projects.active(),
project.start_date, projects.updated_at(),
project.created_at, projects.start_date() as _,
project.server_deleted_at, projects.created_at(),
project.actual_hours, projects.server_deleted_at() as _,
project.actual_seconds, &projects.actual_hours().iter().map(|opt| opt.map(|id| id as i64)).collect_vec() as _,
project.can_track_time, &projects.actual_seconds().iter().map(|opt| opt.map(|id| id as i64)).collect_vec() as _,
project.permissions, projects.can_track_time(),
) projects.permissions() as _,
.execute(&mut self.db) )
.await?; .execute(&mut self.db)
} .await?;
Ok(()) Ok(())
} }

View File

@ -304,7 +304,7 @@ pub mod types {
} }
} }
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone, Soars)]
pub struct Project { pub struct Project {
pub id: i64, pub id: i64,
pub workspace_id: i64, pub workspace_id: i64,