Add time_entry columns

This commit is contained in:
Joshua Coles 2024-03-03 18:14:50 +00:00
parent 573d7f8635
commit ce60eaf310
8 changed files with 434 additions and 7 deletions

1
Cargo.lock generated
View File

@ -1630,6 +1630,7 @@ version = "0.1.0"
dependencies = [
"async-std",
"sea-orm-migration",
"serde_json",
]
[[package]]

350
migration/Cargo.lock generated
View File

@ -355,6 +355,12 @@ version = "0.21.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
[[package]]
name = "base64ct"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
[[package]]
name = "bitflags"
version = "1.3.2"
@ -366,6 +372,9 @@ name = "bitflags"
version = "2.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf"
dependencies = [
"serde",
]
[[package]]
name = "block-buffer"
@ -437,6 +446,7 @@ dependencies = [
"android-tzdata",
"iana-time-zone",
"num-traits",
"serde",
"windows-targets 0.52.4",
]
@ -495,6 +505,12 @@ dependencies = [
"crossbeam-utils",
]
[[package]]
name = "const-oid"
version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
[[package]]
name = "core-foundation-sys"
version = "0.8.6"
@ -550,6 +566,27 @@ dependencies = [
"typenum",
]
[[package]]
name = "der"
version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c"
dependencies = [
"const-oid",
"pem-rfc7468",
"zeroize",
]
[[package]]
name = "deranged"
version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
dependencies = [
"powerfmt",
"serde",
]
[[package]]
name = "derivative"
version = "2.2.0"
@ -568,6 +605,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"const-oid",
"crypto-common",
"subtle",
]
@ -683,6 +721,17 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6"
[[package]]
name = "flume"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181"
dependencies = [
"futures-core",
"futures-sink",
"spin 0.9.8",
]
[[package]]
name = "form_urlencoded"
version = "1.2.1"
@ -722,6 +771,17 @@ version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
[[package]]
name = "futures-executor"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d"
dependencies = [
"futures-core",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-intrusive"
version = "0.5.0"
@ -1020,6 +1080,9 @@ name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
dependencies = [
"spin 0.5.2",
]
[[package]]
name = "libc"
@ -1027,6 +1090,23 @@ version = "0.2.153"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
[[package]]
name = "libm"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
[[package]]
name = "libsqlite3-sys"
version = "0.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf4e226dcd58b4be396f7bd3c20da8fdee2911400705297ba7d2d7cc2c30f716"
dependencies = [
"cc",
"pkg-config",
"vcpkg",
]
[[package]]
name = "linux-raw-sys"
version = "0.3.8"
@ -1089,6 +1169,7 @@ version = "0.1.0"
dependencies = [
"async-std",
"sea-orm-migration",
"serde_json",
]
[[package]]
@ -1139,6 +1220,49 @@ dependencies = [
"minimal-lexical",
]
[[package]]
name = "num-bigint-dig"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151"
dependencies = [
"byteorder",
"lazy_static",
"libm",
"num-integer",
"num-iter",
"num-traits",
"rand",
"smallvec",
"zeroize",
]
[[package]]
name = "num-conv"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
[[package]]
name = "num-integer"
version = "0.1.46"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
dependencies = [
"num-traits",
]
[[package]]
name = "num-iter"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.18"
@ -1146,6 +1270,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
dependencies = [
"autocfg",
"libm",
]
[[package]]
@ -1241,6 +1366,15 @@ version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
[[package]]
name = "pem-rfc7468"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412"
dependencies = [
"base64ct",
]
[[package]]
name = "percent-encoding"
version = "2.3.1"
@ -1270,6 +1404,33 @@ dependencies = [
"futures-io",
]
[[package]]
name = "pkcs1"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f"
dependencies = [
"der",
"pkcs8",
"spki",
]
[[package]]
name = "pkcs8"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7"
dependencies = [
"der",
"spki",
]
[[package]]
name = "pkg-config"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
[[package]]
name = "polling"
version = "2.8.0"
@ -1300,6 +1461,12 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "powerfmt"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
[[package]]
name = "ppv-lite86"
version = "0.2.17"
@ -1441,11 +1608,31 @@ dependencies = [
"cfg-if",
"getrandom",
"libc",
"spin",
"spin 0.9.8",
"untrusted",
"windows-sys 0.52.0",
]
[[package]]
name = "rsa"
version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc"
dependencies = [
"const-oid",
"digest",
"num-bigint-dig",
"num-integer",
"num-traits",
"pkcs1",
"pkcs8",
"rand_core",
"signature",
"spki",
"subtle",
"zeroize",
]
[[package]]
name = "rustc-demangle"
version = "0.1.23"
@ -1552,6 +1739,7 @@ checksum = "6632f499b80cc6aaa781b302e4c9fae663e0e3dcf2640e9d80034d5b10731efe"
dependencies = [
"async-stream",
"async-trait",
"chrono",
"futures",
"log",
"ouroboros",
@ -1559,11 +1747,14 @@ dependencies = [
"sea-query",
"sea-query-binder",
"serde",
"serde_json",
"sqlx",
"strum",
"thiserror",
"time",
"tracing",
"url",
"uuid",
]
[[package]]
@ -1624,6 +1815,7 @@ dependencies = [
"inherent",
"ordered-float",
"sea-query-derive",
"serde_json",
]
[[package]]
@ -1633,6 +1825,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36bbb68df92e820e4d5aeb17b4acd5cc8b5d18b2c36a4dd6f4626aabfa7ab1b9"
dependencies = [
"sea-query",
"serde_json",
"sqlx",
]
@ -1734,6 +1927,16 @@ dependencies = [
"lazy_static",
]
[[package]]
name = "signature"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
dependencies = [
"digest",
"rand_core",
]
[[package]]
name = "slab"
version = "0.4.9"
@ -1769,11 +1972,30 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "spin"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
[[package]]
name = "spin"
version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
dependencies = [
"lock_api",
]
[[package]]
name = "spki"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d"
dependencies = [
"base64ct",
"der",
]
[[package]]
name = "sqlformat"
@ -1794,7 +2016,9 @@ checksum = "dba03c279da73694ef99763320dea58b51095dfe87d001b1d4b5fe78ba8763cf"
dependencies = [
"sqlx-core",
"sqlx-macros",
"sqlx-mysql",
"sqlx-postgres",
"sqlx-sqlite",
]
[[package]]
@ -1871,13 +2095,57 @@ dependencies = [
"serde_json",
"sha2",
"sqlx-core",
"sqlx-mysql",
"sqlx-postgres",
"sqlx-sqlite",
"syn 1.0.109",
"tempfile",
"tokio",
"url",
]
[[package]]
name = "sqlx-mysql"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e37195395df71fd068f6e2082247891bc11e3289624bbc776a0cdfa1ca7f1ea4"
dependencies = [
"atoi",
"base64",
"bitflags 2.4.2",
"byteorder",
"bytes",
"crc",
"digest",
"dotenvy",
"either",
"futures-channel",
"futures-core",
"futures-io",
"futures-util",
"generic-array",
"hex",
"hkdf",
"hmac",
"itoa",
"log",
"md-5",
"memchr",
"once_cell",
"percent-encoding",
"rand",
"rsa",
"serde",
"sha1",
"sha2",
"smallvec",
"sqlx-core",
"stringprep",
"thiserror",
"tracing",
"whoami",
]
[[package]]
name = "sqlx-postgres"
version = "0.7.3"
@ -1917,6 +2185,29 @@ dependencies = [
"whoami",
]
[[package]]
name = "sqlx-sqlite"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "210976b7d948c7ba9fced8ca835b11cbb2d677c59c79de41ac0d397e14547490"
dependencies = [
"atoi",
"flume",
"futures-channel",
"futures-core",
"futures-executor",
"futures-intrusive",
"futures-util",
"libsqlite3-sys",
"log",
"percent-encoding",
"serde",
"sqlx-core",
"tracing",
"url",
"urlencoding",
]
[[package]]
name = "static_assertions"
version = "1.1.0"
@ -2016,6 +2307,36 @@ dependencies = [
"once_cell",
]
[[package]]
name = "time"
version = "0.3.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749"
dependencies = [
"deranged",
"num-conv",
"powerfmt",
"serde",
"time-core",
"time-macros",
]
[[package]]
name = "time-core"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
[[package]]
name = "time-macros"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774"
dependencies = [
"num-conv",
"time-core",
]
[[package]]
name = "tinyvec"
version = "1.6.0"
@ -2161,18 +2482,39 @@ dependencies = [
"percent-encoding",
]
[[package]]
name = "urlencoding"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
[[package]]
name = "utf8parse"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
[[package]]
name = "uuid"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a"
dependencies = [
"serde",
]
[[package]]
name = "value-bag"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "126e423afe2dd9ac52142e7e9d5ce4135d7e13776c529d27fd6bc49f19e3280b"
[[package]]
name = "vcpkg"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "version_check"
version = "0.9.4"
@ -2461,3 +2803,9 @@ dependencies = [
"quote",
"syn 2.0.52",
]
[[package]]
name = "zeroize"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d"

View File

@ -10,10 +10,12 @@ path = "src/lib.rs"
[dependencies]
async-std = { version = "1", features = ["attributes", "tokio1"] }
serde_json = "^1.0"
[dependencies.sea-orm-migration]
version = "0.12.0"
features = [
"runtime-tokio-rustls", # `ASYNC_RUNTIME` feature
"sqlx-postgres", # `DATABASE_DRIVER` feature
'with-json'
]

View File

@ -5,6 +5,7 @@ mod m20231106_134950_create_clients;
mod m20231106_195401_create_projects;
mod m20231106_201029_add_time_entry_project_fk;
mod m20240302_102418_update_project_table;
mod m20240302_171651_update_time_entry_table;
pub struct Migrator;
@ -17,6 +18,7 @@ impl MigratorTrait for Migrator {
Box::new(m20231106_195401_create_projects::Migration),
Box::new(m20231106_201029_add_time_entry_project_fk::Migration),
Box::new(m20240302_102418_update_project_table::Migration),
Box::new(m20240302_171651_update_time_entry_table::Migration),
]
}

View File

@ -0,0 +1,56 @@
use sea_orm_migration::prelude::*;
#[derive(DeriveMigrationName)]
pub struct Migration;
#[async_trait::async_trait]
impl MigrationTrait for Migration {
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager.alter_table(TableAlterStatement::new()
.table(TimeEntry::Table)
.add_column(ColumnDef::new(TimeEntry::Tags)
.json_binary()
.default(serde_json::json!([]))
.not_null()
)
.add_column(ColumnDef::new(TimeEntry::ServerUpdatedAt)
.timestamp_with_time_zone())
.add_column(ColumnDef::new(TimeEntry::ServerDeletedAt)
.timestamp_with_time_zone())
.to_owned()
).await?;
manager.get_connection().execute_unprepared(
r#"
update "time_entry"
set "tags" = coalesce(raw_json -> 'tags', '[]' :: jsonb),
"server_updated_at" = (raw_json ->> 'at') :: timestamptz;
"#,
).await?;
manager.alter_table(
TableAlterStatement::new()
.table(TimeEntry::Table)
.modify_column(ColumnDef::new(TimeEntry::ServerUpdatedAt).not_null())
.to_owned()
).await
}
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager.alter_table(TableAlterStatement::new()
.table(TimeEntry::Table)
.drop_column(TimeEntry::Tags)
.drop_column(TimeEntry::ServerDeletedAt)
.drop_column(TimeEntry::ServerUpdatedAt)
.to_owned()
).await
}
}
#[derive(DeriveIden)]
enum TimeEntry {
Table,
ServerUpdatedAt,
ServerDeletedAt,
Tags,
}

View File

@ -1,5 +1,5 @@
use crate::entity::{client, project, time_entry};
use crate::toggl_api::types::{Project, Client, ReportRow};
use crate::toggl_api::types::{Project, Client, ReportRow, TimeEntry};
use sea_orm::sea_query::OnConflict;
use sea_orm::{NotSet, Set};
@ -32,6 +32,20 @@ impl ReportRow {
}
}
impl TimeEntry {
pub(crate) fn as_model(&self) -> time_entry::ActiveModel {
time_entry::ActiveModel {
id: NotSet,
toggl_id: Set(self.id),
description: Set(self.description.clone()),
project_id: Set(self.project_id),
start: Set(self.start.clone().fixed_offset()),
stop: Set(self.stop.unwrap().fixed_offset()),
raw_json: Set(serde_json::to_value(self).unwrap()),
}
}
}
impl Client {
pub fn as_model(&self) -> client::ActiveModel {
client::ActiveModel {
@ -70,7 +84,7 @@ impl Project {
color: Set(self.color.clone()),
server_created_at: Set(self.created_at.clone().fixed_offset()),
server_updated_at: Set(self.at.clone().fixed_offset()),
server_deleted_at: Set(self.server_deleted_at.clone().fixed_offset()),
server_deleted_at: Set(self.server_deleted_at.map(|dt| dt.fixed_offset())),
}
}

View File

@ -16,6 +16,10 @@ pub struct Model {
pub stop: DateTimeWithTimeZone,
#[sea_orm(column_type = "JsonBinary")]
pub raw_json: Json,
#[sea_orm(column_type = "JsonBinary")]
pub tags: Json,
pub server_updated_at: DateTimeWithTimeZone,
pub server_deleted_at: Option<DateTimeWithTimeZone>,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]

View File

@ -37,14 +37,14 @@ pub struct TimeEntry {
pub project_id: Option<i64>,
pub task_id: Option<Value>,
pub billable: bool,
pub start: String,
pub stop: Option<String>,
pub start: DateTime<Utc>,
pub stop: Option<DateTime<Utc>>,
pub duration: i64,
pub description: String,
pub tags: Vec<String>,
pub tag_ids: Vec<i64>,
pub at: String,
pub server_deleted_at: Option<String>,
pub at: DateTime<Utc>,
pub server_deleted_at: Option<DateTime<Utc>>,
pub user_id: i64,
// Ignored fields