Convert to proper CLI and add SQLX prepare statements
This commit is contained in:
parent
b62d6db866
commit
d78d82f8fa
20
.sqlx/query-0b4b51420a53deb3c37cea4c85c6dc5203cf7200dee8ed8cc6326ef243f716b0.json
generated
Normal file
20
.sqlx/query-0b4b51420a53deb3c37cea4c85c6dc5203cf7200dee8ed8cc6326ef243f716b0.json
generated
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"db_name": "PostgreSQL",
|
||||||
|
"query": "\n INSERT INTO tags (id, name, workspace_id, creator_id, updated_at, deleted_at, permissions)\n SELECT * FROM UNNEST($1::bigint[], $2::text[], $3::bigint[], $4::bigint[], $5::timestamptz[], $6::timestamptz[], $7::text[])\n ON CONFLICT (id) DO UPDATE SET\n name = excluded.name,\n workspace_id = excluded.workspace_id,\n creator_id = excluded.creator_id,\n updated_at = excluded.updated_at,\n deleted_at = excluded.deleted_at,\n permissions = excluded.permissions\n ",
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"parameters": {
|
||||||
|
"Left": [
|
||||||
|
"Int8Array",
|
||||||
|
"TextArray",
|
||||||
|
"Int8Array",
|
||||||
|
"Int8Array",
|
||||||
|
"TimestamptzArray",
|
||||||
|
"TimestamptzArray",
|
||||||
|
"TextArray"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"nullable": []
|
||||||
|
},
|
||||||
|
"hash": "0b4b51420a53deb3c37cea4c85c6dc5203cf7200dee8ed8cc6326ef243f716b0"
|
||||||
|
}
|
||||||
23
.sqlx/query-107be36abd0886a0a6179c1c589ab1ceb3a43851c0b5a4e0efda0fcef7072b6e.json
generated
Normal file
23
.sqlx/query-107be36abd0886a0a6179c1c589ab1ceb3a43851c0b5a4e0efda0fcef7072b6e.json
generated
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"db_name": "PostgreSQL",
|
||||||
|
"query": "\n INSERT INTO tracking_clients\n (id, updated_at, archived, creator_id, integration_provider, notes, name, server_deleted_at, workspace_id, permissions)\n SELECT * FROM UNNEST($1::bigint[], $2::timestamptz[], $3::bool[], $4::bigint[], $5::text[], $6::text[], $7::text[], $8::timestamptz[], $9::bigint[], $10::text[])\n ON CONFLICT (id) DO UPDATE SET\n updated_at = excluded.updated_at,\n archived = excluded.archived,\n creator_id = excluded.creator_id,\n integration_provider = excluded.integration_provider,\n notes = excluded.notes,\n name = excluded.name,\n server_deleted_at = excluded.server_deleted_at,\n workspace_id = excluded.workspace_id,\n permissions = excluded.permissions\n ",
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"parameters": {
|
||||||
|
"Left": [
|
||||||
|
"Int8Array",
|
||||||
|
"TimestamptzArray",
|
||||||
|
"BoolArray",
|
||||||
|
"Int8Array",
|
||||||
|
"TextArray",
|
||||||
|
"TextArray",
|
||||||
|
"TextArray",
|
||||||
|
"TimestamptzArray",
|
||||||
|
"Int8Array",
|
||||||
|
"TextArray"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"nullable": []
|
||||||
|
},
|
||||||
|
"hash": "107be36abd0886a0a6179c1c589ab1ceb3a43851c0b5a4e0efda0fcef7072b6e"
|
||||||
|
}
|
||||||
20
.sqlx/query-1681e2e9011c799d91f79b45ab712963093766c6c8b86a0a46fa6e1b3e1dca7b.json
generated
Normal file
20
.sqlx/query-1681e2e9011c799d91f79b45ab712963093766c6c8b86a0a46fa6e1b3e1dca7b.json
generated
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"db_name": "PostgreSQL",
|
||||||
|
"query": "select max(updated_at) as last_updated_at from time_entries",
|
||||||
|
"describe": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"ordinal": 0,
|
||||||
|
"name": "last_updated_at",
|
||||||
|
"type_info": "Timestamptz"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"parameters": {
|
||||||
|
"Left": []
|
||||||
|
},
|
||||||
|
"nullable": [
|
||||||
|
null
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"hash": "1681e2e9011c799d91f79b45ab712963093766c6c8b86a0a46fa6e1b3e1dca7b"
|
||||||
|
}
|
||||||
20
.sqlx/query-19019001661f62a6c91ef13cd5903df954eb6c3316bce5146388d3066fd1d410.json
generated
Normal file
20
.sqlx/query-19019001661f62a6c91ef13cd5903df954eb6c3316bce5146388d3066fd1d410.json
generated
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"db_name": "PostgreSQL",
|
||||||
|
"query": "select id from tags",
|
||||||
|
"describe": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"ordinal": 0,
|
||||||
|
"name": "id",
|
||||||
|
"type_info": "Int8"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"parameters": {
|
||||||
|
"Left": []
|
||||||
|
},
|
||||||
|
"nullable": [
|
||||||
|
false
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"hash": "19019001661f62a6c91ef13cd5903df954eb6c3316bce5146388d3066fd1d410"
|
||||||
|
}
|
||||||
26
.sqlx/query-2699f6f1991bae9b83566276daa4ed6b0a8984e46b112fc7e4ce17e07d444367.json
generated
Normal file
26
.sqlx/query-2699f6f1991bae9b83566276daa4ed6b0a8984e46b112fc7e4ce17e07d444367.json
generated
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"db_name": "PostgreSQL",
|
||||||
|
"query": "\n INSERT INTO time_entries (id, workspace_id, user_id, project_id, task_id, start, stop, duration, updated_at, description, billable, server_deleted_at, permissions)\n SELECT * FROM UNNEST($1::bigint[], $2::bigint[], $3::bigint[], $4::bigint[], $5::bigint[], $6::timestamptz[], $7::timestamptz[], $8::int[], $9::timestamptz[], $10::text[], $11::bool[], $12::timestamptz[], $13::text[])\n ON CONFLICT (id) DO UPDATE SET\n workspace_id = excluded.workspace_id,\n user_id = excluded.user_id,\n project_id = excluded.project_id,\n task_id = excluded.task_id,\n start = excluded.start,\n stop = excluded.stop,\n duration = excluded.duration,\n updated_at = excluded.updated_at,\n description = excluded.description,\n billable = excluded.billable,\n server_deleted_at = excluded.server_deleted_at,\n permissions = excluded.permissions\n ",
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"parameters": {
|
||||||
|
"Left": [
|
||||||
|
"Int8Array",
|
||||||
|
"Int8Array",
|
||||||
|
"Int8Array",
|
||||||
|
"Int8Array",
|
||||||
|
"Int8Array",
|
||||||
|
"TimestamptzArray",
|
||||||
|
"TimestamptzArray",
|
||||||
|
"Int4Array",
|
||||||
|
"TimestamptzArray",
|
||||||
|
"TextArray",
|
||||||
|
"BoolArray",
|
||||||
|
"TimestamptzArray",
|
||||||
|
"TextArray"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"nullable": []
|
||||||
|
},
|
||||||
|
"hash": "2699f6f1991bae9b83566276daa4ed6b0a8984e46b112fc7e4ce17e07d444367"
|
||||||
|
}
|
||||||
20
.sqlx/query-3c9f3d19e00757a1b6b61b42bf34ea6099b4e4c16be2c345bbc7fe9604b89938.json
generated
Normal file
20
.sqlx/query-3c9f3d19e00757a1b6b61b42bf34ea6099b4e4c16be2c345bbc7fe9604b89938.json
generated
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"db_name": "PostgreSQL",
|
||||||
|
"query": "select id from tracking_clients",
|
||||||
|
"describe": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"ordinal": 0,
|
||||||
|
"name": "id",
|
||||||
|
"type_info": "Int8"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"parameters": {
|
||||||
|
"Left": []
|
||||||
|
},
|
||||||
|
"nullable": [
|
||||||
|
false
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"hash": "3c9f3d19e00757a1b6b61b42bf34ea6099b4e4c16be2c345bbc7fe9604b89938"
|
||||||
|
}
|
||||||
16
.sqlx/query-6fe6248362270f0c9c522b3e27436972a4b56f7ea6a4cdb0b7a3e07d969f39de.json
generated
Normal file
16
.sqlx/query-6fe6248362270f0c9c522b3e27436972a4b56f7ea6a4cdb0b7a3e07d969f39de.json
generated
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"db_name": "PostgreSQL",
|
||||||
|
"query": "\n INSERT INTO workspaces (id, organization_id, name)\n SELECT * FROM UNNEST($1::bigint[], $2::bigint[], $3::text[])\n ON CONFLICT (id) DO UPDATE SET\n organization_id = excluded.organization_id,\n name = excluded.name\n ",
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"parameters": {
|
||||||
|
"Left": [
|
||||||
|
"Int8Array",
|
||||||
|
"Int8Array",
|
||||||
|
"TextArray"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"nullable": []
|
||||||
|
},
|
||||||
|
"hash": "6fe6248362270f0c9c522b3e27436972a4b56f7ea6a4cdb0b7a3e07d969f39de"
|
||||||
|
}
|
||||||
20
.sqlx/query-a6ba6775ce708715abcbf946cb816fdba2b068f1645e7941f54a43a2b6639d31.json
generated
Normal file
20
.sqlx/query-a6ba6775ce708715abcbf946cb816fdba2b068f1645e7941f54a43a2b6639d31.json
generated
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"db_name": "PostgreSQL",
|
||||||
|
"query": "select id from projects",
|
||||||
|
"describe": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"ordinal": 0,
|
||||||
|
"name": "id",
|
||||||
|
"type_info": "Int8"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"parameters": {
|
||||||
|
"Left": []
|
||||||
|
},
|
||||||
|
"nullable": [
|
||||||
|
false
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"hash": "a6ba6775ce708715abcbf946cb816fdba2b068f1645e7941f54a43a2b6639d31"
|
||||||
|
}
|
||||||
20
.sqlx/query-e76966ebbfd08291c10ce64fb947bfcf0096ae4f16e3f91ffd3f512a9c949c45.json
generated
Normal file
20
.sqlx/query-e76966ebbfd08291c10ce64fb947bfcf0096ae4f16e3f91ffd3f512a9c949c45.json
generated
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"db_name": "PostgreSQL",
|
||||||
|
"query": "select id from workspaces",
|
||||||
|
"describe": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"ordinal": 0,
|
||||||
|
"name": "id",
|
||||||
|
"type_info": "Int8"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"parameters": {
|
||||||
|
"Left": []
|
||||||
|
},
|
||||||
|
"nullable": [
|
||||||
|
false
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"hash": "e76966ebbfd08291c10ce64fb947bfcf0096ae4f16e3f91ffd3f512a9c949c45"
|
||||||
|
}
|
||||||
28
.sqlx/query-eb4f7048dcaa8186c11bc20961e941f02c599088471b3515b39c308f551d6a7e.json
generated
Normal file
28
.sqlx/query-eb4f7048dcaa8186c11bc20961e941f02c599088471b3515b39c308f551d6a7e.json
generated
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"db_name": "PostgreSQL",
|
||||||
|
"query": "\n 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)\n 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[])\n ON CONFLICT (id) DO UPDATE SET\n workspace_id = excluded.workspace_id,\n client_id = excluded.client_id,\n name = excluded.name,\n color = excluded.color,\n status = excluded.status,\n active = excluded.active,\n updated_at = excluded.updated_at,\n start_date = excluded.start_date,\n created_at = excluded.created_at,\n server_deleted_at = excluded.server_deleted_at,\n actual_hours = excluded.actual_hours,\n actual_seconds = excluded.actual_seconds,\n can_track_time = excluded.can_track_time,\n permissions = excluded.permissions\n ",
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"parameters": {
|
||||||
|
"Left": [
|
||||||
|
"Int8Array",
|
||||||
|
"Int8Array",
|
||||||
|
"Int8Array",
|
||||||
|
"TextArray",
|
||||||
|
"TextArray",
|
||||||
|
"TextArray",
|
||||||
|
"BoolArray",
|
||||||
|
"TimestamptzArray",
|
||||||
|
"DateArray",
|
||||||
|
"TimestamptzArray",
|
||||||
|
"TimestamptzArray",
|
||||||
|
"Int4Array",
|
||||||
|
"Int4Array",
|
||||||
|
"BoolArray",
|
||||||
|
"TextArray"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"nullable": []
|
||||||
|
},
|
||||||
|
"hash": "eb4f7048dcaa8186c11bc20961e941f02c599088471b3515b39c308f551d6a7e"
|
||||||
|
}
|
||||||
124
Cargo.lock
generated
124
Cargo.lock
generated
@ -51,6 +51,55 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstream"
|
||||||
|
version = "0.6.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526"
|
||||||
|
dependencies = [
|
||||||
|
"anstyle",
|
||||||
|
"anstyle-parse",
|
||||||
|
"anstyle-query",
|
||||||
|
"anstyle-wincon",
|
||||||
|
"colorchoice",
|
||||||
|
"is_terminal_polyfill",
|
||||||
|
"utf8parse",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle"
|
||||||
|
version = "1.0.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-parse"
|
||||||
|
version = "0.2.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb"
|
||||||
|
dependencies = [
|
||||||
|
"utf8parse",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-query"
|
||||||
|
version = "1.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a"
|
||||||
|
dependencies = [
|
||||||
|
"windows-sys 0.52.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-wincon"
|
||||||
|
version = "3.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8"
|
||||||
|
dependencies = [
|
||||||
|
"anstyle",
|
||||||
|
"windows-sys 0.52.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anyhow"
|
name = "anyhow"
|
||||||
version = "1.0.86"
|
version = "1.0.86"
|
||||||
@ -246,6 +295,52 @@ dependencies = [
|
|||||||
"windows-targets 0.52.6",
|
"windows-targets 0.52.6",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap"
|
||||||
|
version = "4.5.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "35723e6a11662c2afb578bcf0b88bf6ea8e21282a953428f240574fcc3a2b5b3"
|
||||||
|
dependencies = [
|
||||||
|
"clap_builder",
|
||||||
|
"clap_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_builder"
|
||||||
|
version = "4.5.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "49eb96cbfa7cfa35017b7cd548c75b14c3118c98b423041d70562665e07fb0fa"
|
||||||
|
dependencies = [
|
||||||
|
"anstream",
|
||||||
|
"anstyle",
|
||||||
|
"clap_lex",
|
||||||
|
"strsim",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_derive"
|
||||||
|
version = "4.5.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5d029b67f89d30bbb547c89fd5161293c0aec155fc691d7924b64550662db93e"
|
||||||
|
dependencies = [
|
||||||
|
"heck 0.5.0",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.71",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_lex"
|
||||||
|
version = "0.7.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "colorchoice"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "const-oid"
|
name = "const-oid"
|
||||||
version = "0.9.6"
|
version = "0.9.6"
|
||||||
@ -398,12 +493,6 @@ dependencies = [
|
|||||||
"subtle",
|
"subtle",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "dotenv"
|
|
||||||
version = "0.15.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dotenvy"
|
name = "dotenvy"
|
||||||
version = "0.15.7"
|
version = "0.15.7"
|
||||||
@ -716,6 +805,12 @@ dependencies = [
|
|||||||
"unicode-segmentation",
|
"unicode-segmentation",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heck"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hermit-abi"
|
name = "hermit-abi"
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
@ -954,6 +1049,12 @@ version = "2.9.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
|
checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "is_terminal_polyfill"
|
||||||
|
version = "1.70.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itertools"
|
name = "itertools"
|
||||||
version = "0.13.0"
|
version = "0.13.0"
|
||||||
@ -2054,7 +2155,7 @@ checksum = "5833ef53aaa16d860e92123292f1f6a3d53c34ba8b1969f152ef1a7bb803f3c8"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"dotenvy",
|
"dotenvy",
|
||||||
"either",
|
"either",
|
||||||
"heck",
|
"heck 0.4.1",
|
||||||
"hex",
|
"hex",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
@ -2351,7 +2452,8 @@ dependencies = [
|
|||||||
"axum",
|
"axum",
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
"chrono",
|
"chrono",
|
||||||
"dotenv",
|
"clap",
|
||||||
|
"dotenvy",
|
||||||
"futures",
|
"futures",
|
||||||
"governor",
|
"governor",
|
||||||
"itertools",
|
"itertools",
|
||||||
@ -2607,6 +2709,12 @@ version = "2.1.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
|
checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "utf8parse"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "valuable"
|
name = "valuable"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|||||||
@ -20,9 +20,10 @@ serde_json_path_to_error = "0.1.4"
|
|||||||
url = "2.5.2"
|
url = "2.5.2"
|
||||||
serde_with = "3.9.0"
|
serde_with = "3.9.0"
|
||||||
sqlx = { version = "0.7.4", features = ["postgres", "runtime-tokio", "macros", "chrono"] }
|
sqlx = { version = "0.7.4", features = ["postgres", "runtime-tokio", "macros", "chrono"] }
|
||||||
dotenv = "0.15.0"
|
|
||||||
futures = "0.3.30"
|
futures = "0.3.30"
|
||||||
tracing = "0.1.40"
|
tracing = "0.1.40"
|
||||||
tracing-subscriber = "0.3.18"
|
tracing-subscriber = "0.3.18"
|
||||||
itertools = "0.13.0"
|
itertools = "0.13.0"
|
||||||
soa-rs = "0.6.1"
|
soa-rs = "0.6.1"
|
||||||
|
clap = { version = "4.5.11", features = ["derive", "env"] }
|
||||||
|
dotenvy = "0.15.7"
|
||||||
|
|||||||
62
src/main.rs
62
src/main.rs
@ -42,47 +42,69 @@ struct TableSummary {
|
|||||||
tag_ids: Vec<u64>,
|
tag_ids: Vec<u64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Environment {
|
use clap::{Parser, Subcommand};
|
||||||
|
use std::net::IpAddr;
|
||||||
|
use chrono::TimeDelta;
|
||||||
|
|
||||||
|
#[derive(Parser)]
|
||||||
|
#[command(author, version, about, long_about = None)]
|
||||||
|
struct Cli {
|
||||||
|
#[command(subcommand)]
|
||||||
|
command: Commands,
|
||||||
|
|
||||||
|
#[arg(long, env = "DATABASE_URL")]
|
||||||
database_url: String,
|
database_url: String,
|
||||||
|
|
||||||
|
#[arg(long, env = "API_TOKEN")]
|
||||||
api_token: String,
|
api_token: String,
|
||||||
|
|
||||||
|
#[arg(long, env = "DEFAULT_WORKSPACE_ID")]
|
||||||
default_workspace_id: u64,
|
default_workspace_id: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Environment {
|
#[derive(Subcommand)]
|
||||||
fn from_env() -> Self {
|
enum Commands {
|
||||||
let database_url = std::env::var("DATABASE_URL").expect("DATABASE_URL must be set");
|
Server {
|
||||||
let api_token = std::env::var("API_TOKEN").expect("API_TOKEN must be set");
|
#[arg(long, env = "IP", default_value = "127.0.0.1")]
|
||||||
let default_workspace_id = std::env::var("DEFAULT_WORKSPACE_ID")
|
ip: IpAddr,
|
||||||
.expect("DEFAULT_WORKSPACE_ID must be set")
|
|
||||||
.parse()
|
|
||||||
.expect("DEFAULT_WORKSPACE_ID must be a number");
|
|
||||||
|
|
||||||
Self {
|
#[arg(long, env = "PORT", default_value = "3000")]
|
||||||
database_url,
|
port: u16,
|
||||||
api_token,
|
},
|
||||||
default_workspace_id,
|
|
||||||
}
|
Migrate,
|
||||||
}
|
|
||||||
|
Sync,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
dotenv::dotenv().expect("Failed to load .env file");
|
dotenvy::dotenv().expect("Failed to load .env file");
|
||||||
|
|
||||||
// Init tracing
|
// Init tracing
|
||||||
tracing_subscriber::fmt::init();
|
tracing_subscriber::fmt::init();
|
||||||
let env_config = Environment::from_env();
|
let cli = Cli::parse();
|
||||||
|
|
||||||
let toggl_api = TogglApi::new(&env_config.api_token, env_config.default_workspace_id);
|
let toggl_api = TogglApi::new(&cli.api_token, cli.default_workspace_id);
|
||||||
let mut db = PgPool::connect(&env_config.database_url).await.unwrap();
|
let mut db = PgPool::connect(&cli.database_url).await.unwrap();
|
||||||
|
|
||||||
sqlx::migrate!("./migrations")
|
sqlx::migrate!("./migrations")
|
||||||
.run(&db)
|
.run(&db)
|
||||||
.await
|
.await
|
||||||
.expect("Failed to run migrations");
|
.expect("Failed to run migrations");
|
||||||
|
|
||||||
|
// Return early if we are just migrating
|
||||||
|
if let Commands::Migrate = cli.command {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let worker = Worker { db, toggl_api };
|
let worker = Worker { db, toggl_api };
|
||||||
|
|
||||||
server::serve(worker).await.expect("Failed to start server")
|
if let Commands::Server { ip, port } = cli.command {
|
||||||
|
server::serve(worker, ip, port).await.expect("Failed to start server");
|
||||||
|
} else {
|
||||||
|
worker.update(TimeDelta::days(30))
|
||||||
|
.await.expect("Failed to update worker");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
use std::net::IpAddr;
|
||||||
use axum::response::IntoResponse;
|
use axum::response::IntoResponse;
|
||||||
use axum::{
|
use axum::{
|
||||||
http::StatusCode,
|
http::StatusCode,
|
||||||
@ -15,7 +16,7 @@ async fn sync(Extension(worker): Extension<Worker>) -> Result<impl IntoResponse,
|
|||||||
Ok("Ok")
|
Ok("Ok")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn serve(worker: Worker) -> Result<(), AppError> {
|
pub async fn serve(worker: Worker, ip: IpAddr, port: u16) -> Result<(), AppError> {
|
||||||
// build our application with a route
|
// build our application with a route
|
||||||
let app = Router::new()
|
let app = Router::new()
|
||||||
.route("/health", get(|| async { "Ok" }))
|
.route("/health", get(|| async { "Ok" }))
|
||||||
@ -23,7 +24,7 @@ pub async fn serve(worker: Worker) -> Result<(), AppError> {
|
|||||||
.layer(Extension(worker));
|
.layer(Extension(worker));
|
||||||
|
|
||||||
// run our app with hyper, listening globally on port 3000
|
// run our app with hyper, listening globally on port 3000
|
||||||
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await?;
|
let listener = tokio::net::TcpListener::bind((ip, port)).await?;
|
||||||
|
|
||||||
axum::serve(listener, app)
|
axum::serve(listener, app)
|
||||||
.with_graceful_shutdown(async {
|
.with_graceful_shutdown(async {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user