From 90379aa21829ac1bee14330725851c42a31236d0 Mon Sep 17 00:00:00 2001 From: Akulij Date: Mon, 7 Apr 2025 22:07:00 +0900 Subject: [PATCH 1/7] extend users table --- src/db/schema.rs | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/src/db/schema.rs b/src/db/schema.rs index 78542e1..ea1d174 100644 --- a/src/db/schema.rs +++ b/src/db/schema.rs @@ -20,10 +20,30 @@ diesel::table! { } diesel::table! { - users (id) { - id -> Int8, - is_admin -> Bool, + teloxide_dialogues (chat_id) { + chat_id -> Int8, + dialogue -> Bytea, } } -diesel::allow_tables_to_appear_in_same_query!(literals, messages, users,); +diesel::table! { + users (id) { + id -> Int8, + is_admin -> Bool, + #[max_length = 255] + first_name -> Varchar, + #[max_length = 255] + last_name -> Nullable, + #[max_length = 255] + username -> Nullable, + #[max_length = 10] + language_code -> Nullable, + } +} + +diesel::allow_tables_to_appear_in_same_query!( + literals, + messages, + teloxide_dialogues, + users, +); From 18d7ae9ce71d4219fe4c604f49d241a6e3039356 Mon Sep 17 00:00:00 2001 From: Akulij Date: Mon, 7 Apr 2025 22:35:57 +0900 Subject: [PATCH 2/7] extend user table --- migrations/2025-04-07-124248_extend_user_table/down.sql | 5 +++++ migrations/2025-04-07-124248_extend_user_table/up.sql | 5 +++++ .../2025-04-07-125633_non_optional_firstname/down.sql | 6 ++++++ migrations/2025-04-07-125633_non_optional_firstname/up.sql | 6 ++++++ 4 files changed, 22 insertions(+) create mode 100644 migrations/2025-04-07-124248_extend_user_table/down.sql create mode 100644 migrations/2025-04-07-124248_extend_user_table/up.sql create mode 100644 migrations/2025-04-07-125633_non_optional_firstname/down.sql create mode 100644 migrations/2025-04-07-125633_non_optional_firstname/up.sql diff --git a/migrations/2025-04-07-124248_extend_user_table/down.sql b/migrations/2025-04-07-124248_extend_user_table/down.sql new file mode 100644 index 0000000..10636f0 --- /dev/null +++ b/migrations/2025-04-07-124248_extend_user_table/down.sql @@ -0,0 +1,5 @@ +ALTER TABLE users +DROP COLUMN first_name, +DROP COLUMN last_name, +DROP COLUMN username, +DROP COLUMN language_code; diff --git a/migrations/2025-04-07-124248_extend_user_table/up.sql b/migrations/2025-04-07-124248_extend_user_table/up.sql new file mode 100644 index 0000000..b2d3353 --- /dev/null +++ b/migrations/2025-04-07-124248_extend_user_table/up.sql @@ -0,0 +1,5 @@ +ALTER TABLE users +ADD COLUMN first_name VARCHAR(255), +ADD COLUMN last_name VARCHAR(255), +ADD COLUMN username VARCHAR(255), +ADD COLUMN language_code VARCHAR(10); diff --git a/migrations/2025-04-07-125633_non_optional_firstname/down.sql b/migrations/2025-04-07-125633_non_optional_firstname/down.sql new file mode 100644 index 0000000..38e94eb --- /dev/null +++ b/migrations/2025-04-07-125633_non_optional_firstname/down.sql @@ -0,0 +1,6 @@ +-- This file should undo anything in `up.sql` + + + +ALTER TABLE "users" ALTER COLUMN "first_name" DROP NOT NULL; + diff --git a/migrations/2025-04-07-125633_non_optional_firstname/up.sql b/migrations/2025-04-07-125633_non_optional_firstname/up.sql new file mode 100644 index 0000000..76ebd78 --- /dev/null +++ b/migrations/2025-04-07-125633_non_optional_firstname/up.sql @@ -0,0 +1,6 @@ +-- Your SQL goes here + + + +ALTER TABLE "users" ALTER COLUMN "first_name" SET NOT NULL; + From 6e0a21f569e2e51d8eb8c6a884cbc0947153fd08 Mon Sep 17 00:00:00 2001 From: Akulij Date: Mon, 7 Apr 2025 22:36:12 +0900 Subject: [PATCH 3/7] create event and reservation table --- .../2025-04-07-130716_event_table/down.sql | 2 ++ .../2025-04-07-130716_event_table/up.sql | 4 +++ .../down.sql | 2 ++ .../up.sql | 10 ++++++ src/db/schema.rs | 33 +++++++++++++++++++ 5 files changed, 51 insertions(+) create mode 100644 migrations/2025-04-07-130716_event_table/down.sql create mode 100644 migrations/2025-04-07-130716_event_table/up.sql create mode 100644 migrations/2025-04-07-130908_reservation_table/down.sql create mode 100644 migrations/2025-04-07-130908_reservation_table/up.sql diff --git a/migrations/2025-04-07-130716_event_table/down.sql b/migrations/2025-04-07-130716_event_table/down.sql new file mode 100644 index 0000000..92c3065 --- /dev/null +++ b/migrations/2025-04-07-130716_event_table/down.sql @@ -0,0 +1,2 @@ +DROP TABLE events; + diff --git a/migrations/2025-04-07-130716_event_table/up.sql b/migrations/2025-04-07-130716_event_table/up.sql new file mode 100644 index 0000000..58a105b --- /dev/null +++ b/migrations/2025-04-07-130716_event_table/up.sql @@ -0,0 +1,4 @@ +CREATE TABLE events ( + id SERIAL PRIMARY KEY, + time TIMESTAMP UNIQUE NOT NULL +); diff --git a/migrations/2025-04-07-130908_reservation_table/down.sql b/migrations/2025-04-07-130908_reservation_table/down.sql new file mode 100644 index 0000000..aa2a4be --- /dev/null +++ b/migrations/2025-04-07-130908_reservation_table/down.sql @@ -0,0 +1,2 @@ +DROP TABLE reservations; +DROP TYPE reservation_status; diff --git a/migrations/2025-04-07-130908_reservation_table/up.sql b/migrations/2025-04-07-130908_reservation_table/up.sql new file mode 100644 index 0000000..2850d65 --- /dev/null +++ b/migrations/2025-04-07-130908_reservation_table/up.sql @@ -0,0 +1,10 @@ +CREATE TYPE reservation_status AS ENUM ('booked', 'paid'); + +CREATE TABLE reservations ( + id SERIAL PRIMARY KEY, + user_id INTEGER REFERENCES users(id), + entered_name VARCHAR(255), + booked_time TIMESTAMP NOT NULL, + event_id INTEGER REFERENCES events(id), + status reservation_status NOT NULL +); diff --git a/src/db/schema.rs b/src/db/schema.rs index ea1d174..9324907 100644 --- a/src/db/schema.rs +++ b/src/db/schema.rs @@ -1,5 +1,18 @@ // @generated automatically by Diesel CLI. +pub mod sql_types { + #[derive(diesel::query_builder::QueryId, Clone, diesel::sql_types::SqlType)] + #[diesel(postgres_type(name = "reservation_status"))] + pub struct ReservationStatus; +} + +diesel::table! { + events (id) { + id -> Int4, + time -> Timestamp, + } +} + diesel::table! { literals (id) { id -> Int4, @@ -19,6 +32,21 @@ diesel::table! { } } +diesel::table! { + use diesel::sql_types::*; + use super::sql_types::ReservationStatus; + + reservations (id) { + id -> Int4, + user_id -> Nullable, + #[max_length = 255] + entered_name -> Nullable, + booked_time -> Timestamp, + event_id -> Nullable, + status -> ReservationStatus, + } +} + diesel::table! { teloxide_dialogues (chat_id) { chat_id -> Int8, @@ -41,9 +69,14 @@ diesel::table! { } } +diesel::joinable!(reservations -> events (event_id)); +diesel::joinable!(reservations -> users (user_id)); + diesel::allow_tables_to_appear_in_same_query!( + events, literals, messages, + reservations, teloxide_dialogues, users, ); From 87d1f8ac1af108ede9e1f58e505b0dac462af9f4 Mon Sep 17 00:00:00 2001 From: Akulij Date: Mon, 7 Apr 2025 22:45:59 +0900 Subject: [PATCH 4/7] add diesel_derive_enum --- Cargo.lock | 25 ++++++++++++++++++++++--- Cargo.toml | 1 + diesel.toml | 2 +- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 005a77e..c1bd5ed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -346,6 +346,18 @@ dependencies = [ "tokio-postgres", ] +[[package]] +name = "diesel-derive-enum" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81c5131a2895ef64741dad1d483f358c2a229a3a2d1b256778cdc5e146db64d4" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "diesel_derives" version = "2.2.4" @@ -413,7 +425,7 @@ checksum = "139ae9aca7527f85f26dd76483eb38533fd84bd571065da1739656ef71c5ff5b" dependencies = [ "darling", "either", - "heck", + "heck 0.5.0", "proc-macro2", "quote", "syn", @@ -700,6 +712,7 @@ version = "0.1.0" dependencies = [ "diesel", "diesel-async", + "diesel-derive-enum", "dotenvy", "envconfig", "serde", @@ -733,6 +746,12 @@ dependencies = [ "hashbrown 0.15.2", ] +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + [[package]] name = "heck" version = "0.5.0" @@ -1918,7 +1937,7 @@ checksum = "4e9f90acc5ab146a99bf5061a7eb4976b573f560bc898ef3bf8435448dd5e7ad" dependencies = [ "dotenvy", "either", - "heck", + "heck 0.5.0", "hex", "once_cell", "proc-macro2", @@ -2131,7 +2150,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3118a980ed2ec11f73d9495a6606905bd74726e3ffe95a42fbeb187ded8fdbf4" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote", "syn", diff --git a/Cargo.toml b/Cargo.toml index 3543e31..5ee90ef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ edition = "2021" [dependencies] diesel = { version = "2.2.8", features = ["postgres"] } diesel-async = { version = "0.5.2", features = ["bb8", "postgres"] } +diesel-derive-enum = "2.1.0" dotenvy = "0.15.7" envconfig = "0.11.0" serde = { version = "1.0.219", features = ["derive", "serde_derive"] } diff --git a/diesel.toml b/diesel.toml index a3fc278..9f7b7dd 100644 --- a/diesel.toml +++ b/diesel.toml @@ -3,7 +3,7 @@ [print_schema] file = "src/db/schema.rs" -custom_type_derives = ["diesel::query_builder::QueryId", "Clone"] +custom_type_derives = ["diesel_derive_enum::DbEnum", "diesel::query_builder::QueryId", "Clone"] [migrations_directory] dir = "/Users/akulij/gits/gongbotrs/migrations" From e4051479d43746395e9e665f59b81ee7387733e7 Mon Sep 17 00:00:00 2001 From: Akulij Date: Mon, 7 Apr 2025 23:13:52 +0900 Subject: [PATCH 5/7] stringify reservation table status field reason: no easy to setup enums support in diesel --- .../down.sql | 2 ++ .../up.sql | 2 ++ src/db/schema.rs | 11 +---------- 3 files changed, 5 insertions(+), 10 deletions(-) create mode 100644 migrations/2025-04-07-135609_stringify_reservation_status/down.sql create mode 100644 migrations/2025-04-07-135609_stringify_reservation_status/up.sql diff --git a/migrations/2025-04-07-135609_stringify_reservation_status/down.sql b/migrations/2025-04-07-135609_stringify_reservation_status/down.sql new file mode 100644 index 0000000..305d59a --- /dev/null +++ b/migrations/2025-04-07-135609_stringify_reservation_status/down.sql @@ -0,0 +1,2 @@ +CREATE TYPE reservation_status AS ENUM ('booked', 'paid'); +ALTER TABLE reservations ALTER COLUMN status TYPE reservation_status USING status::reservation_status; diff --git a/migrations/2025-04-07-135609_stringify_reservation_status/up.sql b/migrations/2025-04-07-135609_stringify_reservation_status/up.sql new file mode 100644 index 0000000..ce0762b --- /dev/null +++ b/migrations/2025-04-07-135609_stringify_reservation_status/up.sql @@ -0,0 +1,2 @@ +ALTER TABLE reservations ALTER COLUMN status TYPE VARCHAR; +DROP TYPE reservation_status; diff --git a/src/db/schema.rs b/src/db/schema.rs index 9324907..62c1f97 100644 --- a/src/db/schema.rs +++ b/src/db/schema.rs @@ -1,11 +1,5 @@ // @generated automatically by Diesel CLI. -pub mod sql_types { - #[derive(diesel::query_builder::QueryId, Clone, diesel::sql_types::SqlType)] - #[diesel(postgres_type(name = "reservation_status"))] - pub struct ReservationStatus; -} - diesel::table! { events (id) { id -> Int4, @@ -33,9 +27,6 @@ diesel::table! { } diesel::table! { - use diesel::sql_types::*; - use super::sql_types::ReservationStatus; - reservations (id) { id -> Int4, user_id -> Nullable, @@ -43,7 +34,7 @@ diesel::table! { entered_name -> Nullable, booked_time -> Timestamp, event_id -> Nullable, - status -> ReservationStatus, + status -> Varchar, } } From 21081c3206e1e164ef29ba5a278b4c88ed453157 Mon Sep 17 00:00:00 2001 From: Akulij Date: Mon, 7 Apr 2025 23:16:44 +0900 Subject: [PATCH 6/7] regenerate models.rs --- src/db/models.rs | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/src/db/models.rs b/src/db/models.rs index 6a0ba1b..af1f7a2 100644 --- a/src/db/models.rs +++ b/src/db/models.rs @@ -3,8 +3,17 @@ #![allow(unused)] #![allow(clippy::all)] + +use chrono::NaiveDateTime; use diesel::prelude::*; -#[derive(Queryable, Debug)] +#[derive(Queryable, Debug, Identifiable)] +#[diesel(table_name = events)] +pub struct Event { + pub id: i32, + pub time: NaiveDateTime, +} + +#[derive(Queryable, Debug, Identifiable)] #[diesel(table_name = literals)] pub struct Literal { pub id: i32, @@ -12,7 +21,7 @@ pub struct Literal { pub value: String, } -#[derive(Queryable, Debug)] +#[derive(Queryable, Debug, Identifiable)] #[diesel(table_name = messages)] pub struct Message { pub id: i32, @@ -21,9 +30,33 @@ pub struct Message { pub token: String, } +#[derive(Queryable, Debug, Identifiable)] +#[diesel(table_name = reservations)] +pub struct Reservation { + pub id: i32, + pub user_id: Option, + pub entered_name: Option, + pub booked_time: NaiveDateTime, + pub event_id: Option, + pub status: String, +} + +#[derive(Queryable, Debug, Identifiable)] +#[diesel(primary_key(chat_id))] +#[diesel(table_name = teloxide_dialogues)] +pub struct TeloxideDialogue { + pub chat_id: i64, + pub dialogue: Vec, +} + #[derive(Queryable, Debug)] #[diesel(table_name = users)] pub struct User { pub id: i64, pub is_admin: bool, + pub first_name: String, + pub last_name: Option, + pub username: Option, + pub language_code: Option, } + From 07a10fae0e6bdf8db65b8562573914012d84dcb4 Mon Sep 17 00:00:00 2001 From: Akulij Date: Mon, 7 Apr 2025 23:24:18 +0900 Subject: [PATCH 7/7] create reservatoin status getter that returns enum --- Cargo.lock | 28 ++++++++++++++++++++++++++++ Cargo.toml | 1 + src/db.rs | 18 ++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index c1bd5ed..9a658cf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -187,6 +187,15 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "core-foundation" version = "0.9.4" @@ -440,6 +449,18 @@ dependencies = [ "serde", ] +[[package]] +name = "enum_stringify" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9ff9e4dbfa8fb0fd68ff9e4da874ad10774af372f0e2b8d1649c63026434d37" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "envconfig" version = "0.11.0" @@ -714,6 +735,7 @@ dependencies = [ "diesel-async", "diesel-derive-enum", "dotenvy", + "enum_stringify", "envconfig", "serde", "teloxide", @@ -2438,6 +2460,12 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0" +[[package]] +name = "unicode-segmentation" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" + [[package]] name = "unicode-xid" version = "0.2.6" diff --git a/Cargo.toml b/Cargo.toml index 5ee90ef..23a9fa1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ diesel = { version = "2.2.8", features = ["postgres"] } diesel-async = { version = "0.5.2", features = ["bb8", "postgres"] } diesel-derive-enum = "2.1.0" dotenvy = "0.15.7" +enum_stringify = "0.6.3" envconfig = "0.11.0" serde = { version = "1.0.219", features = ["derive", "serde_derive"] } teloxide = { version = "0.14.0", features = ["macros", "postgres-storage-nativetls"] } diff --git a/src/db.rs b/src/db.rs index c908ca0..85917c8 100644 --- a/src/db.rs +++ b/src/db.rs @@ -9,6 +9,24 @@ use diesel_async::pooled_connection::bb8::Pool; use diesel_async::pooled_connection::AsyncDieselConnectionManager; use diesel_async::AsyncPgConnection; use diesel_async::RunQueryDsl; +use enum_stringify::EnumStringify; + +#[derive(EnumStringify)] +#[enum_stringify(case = "flat")] +pub enum ReservationStatus { + Booked, + Paid, +} + +pub trait GetReservationStatus { + fn get_status(&self) -> Option; +} + +impl GetReservationStatus for models::Reservation { + fn get_status(&self) -> Option { + ReservationStatus::try_from(self.status.clone()).ok() + } +} #[derive(Clone)] pub struct DB {