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