From 25fb0eed111bed93d1195c82c4404bf55e47431d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=8B=D1=80=D1=86=D0=B5=D0=B2=20=D0=92=D0=B0=D0=B4?= =?UTF-8?q?=D0=B8=D0=BC=20=D0=98=D0=B3=D0=BE=D1=80=D0=B5=D0=B2=D0=B8=D1=87?= Date: Sun, 21 Jan 2024 10:55:36 +0300 Subject: [PATCH 01/11] Add PostgresStorage --- crates/teloxide/Cargo.toml | 4 + crates/teloxide/src/dispatching/dialogue.rs | 3 + .../src/dispatching/dialogue/storage.rs | 6 + .../dialogue/storage/postgres_storage.rs | 157 ++++++++++++++++++ .../queries/create_teloxide_dialogues.sql | 4 + .../postgres_storage/queries/get_dialogue.sql | 1 + .../queries/remove_dialogue.sql | 1 + .../queries/update_dialogue.sql | 2 + 8 files changed, 178 insertions(+) create mode 100644 crates/teloxide/src/dispatching/dialogue/storage/postgres_storage.rs create mode 100644 crates/teloxide/src/dispatching/dialogue/storage/postgres_storage/queries/create_teloxide_dialogues.sql create mode 100644 crates/teloxide/src/dispatching/dialogue/storage/postgres_storage/queries/get_dialogue.sql create mode 100644 crates/teloxide/src/dispatching/dialogue/storage/postgres_storage/queries/remove_dialogue.sql create mode 100644 crates/teloxide/src/dispatching/dialogue/storage/postgres_storage/queries/update_dialogue.sql diff --git a/crates/teloxide/Cargo.toml b/crates/teloxide/Cargo.toml index 8286a3a7..f19ea988 100644 --- a/crates/teloxide/Cargo.toml +++ b/crates/teloxide/Cargo.toml @@ -25,7 +25,10 @@ webhooks-axum = ["webhooks", "axum", "tower", "tower-http"] sqlite-storage-nativetls = ["sqlx", "sqlx/runtime-tokio-native-tls", "native-tls"] sqlite-storage-rustls = ["sqlx", "sqlx/runtime-tokio-rustls", "rustls"] +postgres-storage-nativetls = ["sqlx", "sqlx/runtime-tokio-native-tls", "native-tls"] +postgres-storage-rustls = ["sqlx", "sqlx/runtime-tokio-rustls", "rustls"] redis-storage = ["redis"] + cbor-serializer = ["serde_cbor"] bincode-serializer = ["bincode"] @@ -101,6 +104,7 @@ either = "1.9.0" sqlx = { version = "0.7.3", optional = true, default-features = false, features = [ "macros", "sqlite", + "postgres" ] } redis = { version = "0.21", features = ["tokio-comp"], optional = true } serde_cbor = { version = "0.11", optional = true } diff --git a/crates/teloxide/src/dispatching/dialogue.rs b/crates/teloxide/src/dispatching/dialogue.rs index 6f668e8f..e7938654 100644 --- a/crates/teloxide/src/dispatching/dialogue.rs +++ b/crates/teloxide/src/dispatching/dialogue.rs @@ -99,6 +99,9 @@ pub use self::{RedisStorage, RedisStorageError}; #[cfg(feature = "sqlite-storage-nativetls")] pub use self::{SqliteStorage, SqliteStorageError}; +#[cfg(feature = "postgres-storage-nativetls")] +pub use self::{PostgresStorage, PostgresStorageError}; + pub use get_chat_id::GetChatId; pub use storage::*; diff --git a/crates/teloxide/src/dispatching/dialogue/storage.rs b/crates/teloxide/src/dispatching/dialogue/storage.rs index 73611c61..d071d5ed 100644 --- a/crates/teloxide/src/dispatching/dialogue/storage.rs +++ b/crates/teloxide/src/dispatching/dialogue/storage.rs @@ -9,6 +9,9 @@ mod redis_storage; #[cfg(feature = "sqlite-storage-nativetls")] mod sqlite_storage; +#[cfg(feature = "postgres-storage-nativetls")] +mod postgres_storage; + use futures::future::BoxFuture; use teloxide_core::types::ChatId; @@ -25,6 +28,9 @@ use std::sync::Arc; #[cfg(feature = "sqlite-storage-nativetls")] pub use sqlite_storage::{SqliteStorage, SqliteStorageError}; +#[cfg(feature = "postgres-storage-nativetls")] +pub use postgres_storage::{PostgresStorage, PostgresStorageError}; + /// A storage with an erased error type. pub type ErasedStorage = dyn Storage> + Send + Sync; diff --git a/crates/teloxide/src/dispatching/dialogue/storage/postgres_storage.rs b/crates/teloxide/src/dispatching/dialogue/storage/postgres_storage.rs new file mode 100644 index 00000000..ceb4f2a8 --- /dev/null +++ b/crates/teloxide/src/dispatching/dialogue/storage/postgres_storage.rs @@ -0,0 +1,157 @@ +use std::{ + convert::Infallible, + fmt::{Debug, Display}, + str, + sync::Arc, +}; + +use futures::future::BoxFuture; +use serde::{de::DeserializeOwned, Serialize}; +use sqlx::postgres::{PgPool, PgPoolOptions}; +use teloxide_core::types::ChatId; +use thiserror::Error; + +use super::{serializer::Serializer, Storage}; + +/// An error returned from [`PostgresStorage`]. +#[derive(Debug, Error)] +pub enum PostgresStorageError +where + SE: Debug + Display, +{ + #[error("dialogue serialization error: {0}")] + SerdeError(SE), + + #[error("postgres error: {0}")] + PostgresError(#[from] sqlx::Error), + + // TODO maybe add chat_id for the sake of completeness? + #[error("row not found")] + DialogueNotFound, +} + +/// A persistent dialogue storage based on [PostgreSQL](https://www.postgresql.org/) +pub struct PostgresStorage { + pool: PgPool, + serializer: S, +} + +impl PostgresStorage { + /// Opens a connection pool to the [Postgres](https://www.postgresql.org/) database and creates the table + /// for storing dialogues. + /// + /// Parameters: + /// - database_url: full url to the postgres database, for example + /// `"postgres://postgres:password@localhost/test")` + /// - max_connections: number of connections in creating connection pool. Be + /// mindful of the connection limits for your database, each + /// connection established with the Postgres creates a new process on the + /// server side + /// - serializer: what [`Serializer`] will be used to encode the dialogue + /// data. Available ones are: [`Json`], [`Bincode`], [`Cbor`] + /// + /// [`Json`]: crate::dispatching::dialogue::serializer::Json + /// [`Bincode`]: crate::dispatching::dialogue::serializer::Bincode + /// [`Cbor`]: crate::dispatching::dialogue::serializer::Cbor + pub async fn open( + database_url: &str, + max_connections: u32, + serializer: S, + ) -> Result, PostgresStorageError> { + let pool = + PgPoolOptions::new().max_connections(max_connections).connect(database_url).await?; + sqlx::query(include_str!("postgres_storage/queries/create_teloxide_dialogues.sql")) + .execute(&pool) + .await?; + + Ok(Arc::new(Self { pool, serializer })) + } + + async fn get_dialogue( + self: Arc, + ChatId(chat_id): ChatId, + ) -> Result>, sqlx::Error> { + #[derive(sqlx::FromRow)] + struct DialogueDbRow { + dialogue: Vec, + } + + let bytes = sqlx::query_as::<_, DialogueDbRow>(include_str!( + "postgres_storage/queries/get_dialogue.sql" + )) + .bind(chat_id) + .fetch_optional(&self.pool) + .await? + .map(|r| r.dialogue); + + Ok(bytes) + } +} + +// FIXME: these methods' bodies are almostly the same as SqliteStorage ones +// (except actual queries) Maybe combine them somehow? + +impl Storage for PostgresStorage +where + S: Send + Sync + Serializer + 'static, + D: Send + Serialize + DeserializeOwned + 'static, + >::Error: Debug + Display, +{ + type Error = PostgresStorageError<>::Error>; + + fn remove_dialogue( + self: Arc, + ChatId(chat_id): ChatId, + ) -> BoxFuture<'static, Result<(), Self::Error>> + where + D: Send + 'static, + { + Box::pin(async move { + let deleted_rows_count = + sqlx::query(include_str!("postgres_storage/queries/remove_dialogue.sql")) + .bind(chat_id) + .execute(&self.pool) + .await? + .rows_affected(); + + if deleted_rows_count == 0 { + return Err(PostgresStorageError::DialogueNotFound); + } + + Ok(()) + }) + } + + fn update_dialogue( + self: Arc, + ChatId(chat_id): ChatId, + dialogue: D, + ) -> BoxFuture<'static, Result<(), Self::Error>> + where + D: Send + 'static, + { + Box::pin(async move { + let d = + self.serializer.serialize(&dialogue).map_err(PostgresStorageError::SerdeError)?; + sqlx::query(include_str!("postgres_storage/queries/update_dialogue.sql")) + .bind(chat_id) + .bind(d) + .execute(&self.pool) + .await?; + Ok(()) + }) + } + + fn get_dialogue( + self: Arc, + chat_id: ChatId, + ) -> BoxFuture<'static, Result, Self::Error>> { + Box::pin(async move { + self.clone() + .get_dialogue(chat_id) + .await? + .map(|d| self.serializer.deserialize(&d).map_err(PostgresStorageError::SerdeError)) + .transpose() + }) + } +} diff --git a/crates/teloxide/src/dispatching/dialogue/storage/postgres_storage/queries/create_teloxide_dialogues.sql b/crates/teloxide/src/dispatching/dialogue/storage/postgres_storage/queries/create_teloxide_dialogues.sql new file mode 100644 index 00000000..3fc00d84 --- /dev/null +++ b/crates/teloxide/src/dispatching/dialogue/storage/postgres_storage/queries/create_teloxide_dialogues.sql @@ -0,0 +1,4 @@ +CREATE TABLE IF NOT EXISTS teloxide_dialogues ( + chat_id BIGINT PRIMARY KEY, + dialogue BYTEA NOT NULL +) \ No newline at end of file diff --git a/crates/teloxide/src/dispatching/dialogue/storage/postgres_storage/queries/get_dialogue.sql b/crates/teloxide/src/dispatching/dialogue/storage/postgres_storage/queries/get_dialogue.sql new file mode 100644 index 00000000..e5e3c834 --- /dev/null +++ b/crates/teloxide/src/dispatching/dialogue/storage/postgres_storage/queries/get_dialogue.sql @@ -0,0 +1 @@ +SELECT dialogue FROM teloxide_dialogues WHERE chat_id = $1 \ No newline at end of file diff --git a/crates/teloxide/src/dispatching/dialogue/storage/postgres_storage/queries/remove_dialogue.sql b/crates/teloxide/src/dispatching/dialogue/storage/postgres_storage/queries/remove_dialogue.sql new file mode 100644 index 00000000..2fb0b93f --- /dev/null +++ b/crates/teloxide/src/dispatching/dialogue/storage/postgres_storage/queries/remove_dialogue.sql @@ -0,0 +1 @@ +DELETE FROM teloxide_dialogues WHERE chat_id = $1 \ No newline at end of file diff --git a/crates/teloxide/src/dispatching/dialogue/storage/postgres_storage/queries/update_dialogue.sql b/crates/teloxide/src/dispatching/dialogue/storage/postgres_storage/queries/update_dialogue.sql new file mode 100644 index 00000000..d21f4086 --- /dev/null +++ b/crates/teloxide/src/dispatching/dialogue/storage/postgres_storage/queries/update_dialogue.sql @@ -0,0 +1,2 @@ +INSERT INTO teloxide_dialogues VALUES ($1, $2) +ON CONFLICT(chat_id) DO UPDATE SET dialogue=excluded.dialogue \ No newline at end of file From f0b7681cb3a3668329bfee196b5b00fdd734ff94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=8B=D1=80=D1=86=D0=B5=D0=B2=20=D0=92=D0=B0=D0=B4?= =?UTF-8?q?=D0=B8=D0=BC=20=D0=98=D0=B3=D0=BE=D1=80=D0=B5=D0=B2=D0=B8=D1=87?= Date: Sun, 21 Jan 2024 11:38:26 +0300 Subject: [PATCH 02/11] Add PostgresStorage tests --- crates/teloxide/Cargo.toml | 4 ++ crates/teloxide/tests/postgres.rs | 91 +++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 crates/teloxide/tests/postgres.rs diff --git a/crates/teloxide/Cargo.toml b/crates/teloxide/Cargo.toml index f19ea988..c17e1eb0 100644 --- a/crates/teloxide/Cargo.toml +++ b/crates/teloxide/Cargo.toml @@ -152,6 +152,10 @@ name = "sqlite" path = "tests/sqlite.rs" required-features = ["sqlite-storage-nativetls", "cbor-serializer", "bincode-serializer"] +[[test]] +name = "postgres" +path = "tests/postgres.rs" +required-features = ["postgres-storage-nativetls", "cbor-serializer", "bincode-serializer"] [[example]] name = "admin" diff --git a/crates/teloxide/tests/postgres.rs b/crates/teloxide/tests/postgres.rs new file mode 100644 index 00000000..cbcab064 --- /dev/null +++ b/crates/teloxide/tests/postgres.rs @@ -0,0 +1,91 @@ +use std::{ + fmt::{Debug, Display}, + sync::Arc, +}; +use teloxide::{ + dispatching::dialogue::{PostgresStorage, PostgresStorageError, Serializer, Storage}, + types::ChatId, +}; + +#[tokio::test] +#[cfg_attr(not(CI_POSTGRES), ignore)] +async fn test_postgres_json() { + let storage = PostgresStorage::open( + "postgres://teloxide:rewrite_it_in_rust@localhost:5432/test_postgres_json", + 4, + teloxide::dispatching::dialogue::serializer::Json, + ) + .await + .unwrap(); + + test_postgres(storage).await; +} + +#[tokio::test] +#[cfg_attr(not(CI_POSTGRES), ignore)] +async fn test_postgres_bincode() { + let storage = PostgresStorage::open( + "postgres://teloxide:rewrite_it_in_rust@localhost:5432/test_postgres_bincode", + 4, + teloxide::dispatching::dialogue::serializer::Bincode, + ) + .await + .unwrap(); + + test_postgres(storage).await; +} + +#[tokio::test] +#[cfg_attr(not(CI_POSTGRES), ignore)] +async fn test_postgres_cbor() { + let storage = PostgresStorage::open( + "postgres://teloxide:rewrite_it_in_rust@localhost:5432/test_postgres_cbor", + 4, + teloxide::dispatching::dialogue::serializer::Cbor, + ) + .await + .unwrap(); + + test_postgres(storage).await; +} + +type Dialogue = String; + +macro_rules! test_dialogues { + ($storage:expr, $_0:expr, $_1:expr, $_2:expr) => { + assert_eq!(Arc::clone(&$storage).get_dialogue(ChatId(1)).await.unwrap(), $_0); + assert_eq!(Arc::clone(&$storage).get_dialogue(ChatId(11)).await.unwrap(), $_1); + assert_eq!(Arc::clone(&$storage).get_dialogue(ChatId(256)).await.unwrap(), $_2); + }; +} + +async fn test_postgres(storage: Arc>) +where + S: Send + Sync + Serializer + 'static, + >::Error: Debug + Display, +{ + test_dialogues!(storage, None, None, None); + + Arc::clone(&storage).update_dialogue(ChatId(1), "ABC".to_owned()).await.unwrap(); + Arc::clone(&storage).update_dialogue(ChatId(11), "DEF".to_owned()).await.unwrap(); + Arc::clone(&storage).update_dialogue(ChatId(256), "GHI".to_owned()).await.unwrap(); + + test_dialogues!( + storage, + Some("ABC".to_owned()), + Some("DEF".to_owned()), + Some("GHI".to_owned()) + ); + + Arc::clone(&storage).remove_dialogue(ChatId(1)).await.unwrap(); + Arc::clone(&storage).remove_dialogue(ChatId(11)).await.unwrap(); + Arc::clone(&storage).remove_dialogue(ChatId(256)).await.unwrap(); + + test_dialogues!(storage, None, None, None); + + // Check that a try to remove a non-existing dialogue results in an error. + assert!(matches!( + Arc::clone(&storage).remove_dialogue(ChatId(1)).await.unwrap_err(), + PostgresStorageError::DialogueNotFound + )); +} From 3fb4ee226acabeb36a689bdd4583b9839efbdc34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=8B=D1=80=D1=86=D0=B5=D0=B2=20=D0=92=D0=B0=D0=B4?= =?UTF-8?q?=D0=B8=D0=BC=20=D0=98=D0=B3=D0=BE=D1=80=D0=B5=D0=B2=D0=B8=D1=87?= Date: Sun, 21 Jan 2024 12:08:28 +0300 Subject: [PATCH 03/11] Update ci.yml to allow Postgres testing --- .github/workflows/ci.yml | 17 ++++++++++++++++- .github/workflows/postgres/init.sql | 4 ++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/postgres/init.sql diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0d6d70fa..43713cc7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,7 +8,7 @@ on: name: Continuous integration env: - RUSTFLAGS: "--cfg CI_REDIS -Dwarnings" + RUSTFLAGS: "--cfg CI_REDIS CI_POSTGRES -Dwarnings" RUSTDOCFLAGS: -Dwarnings RUST_BACKTRACE: short @@ -74,6 +74,21 @@ jobs: test: name: Test runs-on: ubuntu-latest + services: + # Setup Postgres for testing PostgresStorage + postgres: + image: postgres + + volumes: + - ./postgres/init.sql:/docker-entrypoint-initdb.d/init.sql + + env: + POSTGRES_USER: teloxide + POSTGRES_PASSWORD: rewrite_it_in_rust + + ports: + - 5432:5432 + strategy: matrix: rust: diff --git a/.github/workflows/postgres/init.sql b/.github/workflows/postgres/init.sql new file mode 100644 index 00000000..f7da96c8 --- /dev/null +++ b/.github/workflows/postgres/init.sql @@ -0,0 +1,4 @@ +CREATE ROLE teloxide WITH LOGIN SUPERUSER PASSWORD 'rewrite_it_in_rust' +CREATE DATABASE test_postgres_json; +CREATE DATABASE test_postgres_bincode; +CREATE_DATABASE test_postgres_cbor; \ No newline at end of file From ec113c1bc4227e0aee5d34c1a5b83a71808c85b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=8B=D1=80=D1=86=D0=B5=D0=B2=20=D0=92=D0=B0=D0=B4?= =?UTF-8?q?=D0=B8=D0=BC=20=D0=98=D0=B3=D0=BE=D1=80=D0=B5=D0=B2=D0=B8=D1=87?= Date: Sun, 21 Jan 2024 13:28:01 +0300 Subject: [PATCH 04/11] Fix ci.yml --- .github/workflows/ci.yml | 7 ++----- .github/workflows/{postgres => }/init.sql | 0 2 files changed, 2 insertions(+), 5 deletions(-) rename .github/workflows/{postgres => }/init.sql (100%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 43713cc7..ecd282df 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,7 +8,7 @@ on: name: Continuous integration env: - RUSTFLAGS: "--cfg CI_REDIS CI_POSTGRES -Dwarnings" + RUSTFLAGS: "--cfg CI_REDIS --cfg CI_POSTGRES -Dwarnings" RUSTDOCFLAGS: -Dwarnings RUST_BACKTRACE: short @@ -80,15 +80,12 @@ jobs: image: postgres volumes: - - ./postgres/init.sql:/docker-entrypoint-initdb.d/init.sql + - init.sql:/docker-entrypoint-initdb.d/init.sql env: POSTGRES_USER: teloxide POSTGRES_PASSWORD: rewrite_it_in_rust - ports: - - 5432:5432 - strategy: matrix: rust: diff --git a/.github/workflows/postgres/init.sql b/.github/workflows/init.sql similarity index 100% rename from .github/workflows/postgres/init.sql rename to .github/workflows/init.sql From 44fd889decc7db02fafa7a6afbdc74bf794eb281 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=8B=D1=80=D1=86=D0=B5=D0=B2=20=D0=92=D0=B0=D0=B4?= =?UTF-8?q?=D0=B8=D0=BC=20=D0=98=D0=B3=D0=BE=D1=80=D0=B5=D0=B2=D0=B8=D1=87?= Date: Sun, 21 Jan 2024 16:09:07 +0300 Subject: [PATCH 05/11] bump msrv --- .github/workflows/ci.yml | 4 ++-- Cargo.toml | 2 +- README.md | 2 +- crates/teloxide-core/src/lib.rs | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ecd282df..d2d45f53 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,7 +26,7 @@ env: # - down below in a matrix # - `Cargo.toml` # - **/CHANGELOG.md - rust_msrv: 1.68.0 + rust_msrv: 1.70.0 CI: 1 @@ -105,7 +105,7 @@ jobs: toolchain: nightly-2023-09-27 features: "--features full nightly" - rust: msrv - toolchain: 1.68.0 + toolchain: 1.70.0 features: "--features full" steps: diff --git a/Cargo.toml b/Cargo.toml index 803ed545..37e4f9f1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ resolver = "2" # The settings below will be applied to all crates in the workspace [workspace.package] # MSRV (minimal supported Rust version). -rust-version = "1.68" +rust-version = "1.70" edition = "2021" license = "MIT" diff --git a/README.md b/README.md index 45153b31..7c0970ed 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ $ set TELOXIDE_TOKEN= $ $env:TELOXIDE_TOKEN= ``` - 4. Make sure that your Rust compiler is up to date (`teloxide` currently requires rustc at least version 1.68): + 4. Make sure that your Rust compiler is up to date (`teloxide` currently requires rustc at least version 1.70): ```bash # If you're using stable $ rustup update stable diff --git a/crates/teloxide-core/src/lib.rs b/crates/teloxide-core/src/lib.rs index 679a4859..125c70b6 100644 --- a/crates/teloxide-core/src/lib.rs +++ b/crates/teloxide-core/src/lib.rs @@ -7,7 +7,7 @@ //!```toml //! teloxide-core = "0.9" //! ``` -//! _Compiler support: requires rustc 1.68+_. +//! _Compiler support: requires rustc 1.70+_. //! //! ``` //! # async { From b2e652671f3cede32616459c9e86391558b831b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=8B=D1=80=D1=86=D0=B5=D0=B2=20=D0=92=D0=B0=D0=B4?= =?UTF-8?q?=D0=B8=D0=BC=20=D0=98=D0=B3=D0=BE=D1=80=D0=B5=D0=B2=D0=B8=D1=87?= Date: Sun, 21 Jan 2024 16:14:48 +0300 Subject: [PATCH 06/11] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ crates/teloxide-core/CHANGELOG.md | 2 ++ 2 files changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6cfe45b5..6bb03223 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `filter_video_chat_ended` - `filter_video_chat_participants_invited` - `filter_web_app_data` +- `PostgresStorage` a persistent dialogue storage based on [PostgreSQL](https://www.postgresql.org/)([PR 996](https://github.com/teloxide/teloxide/pull/996)) ### Fixed @@ -57,6 +58,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - MSRV (Minimal Supported Rust Version) was bumped from `1.64.0` to `1.68.0` ([PR 950][https://github.com/teloxide/teloxide/pull/950]) - Sqlx version was bumped from `0.6` to `0.7.3`([PR 995](https://github.com/teloxide/teloxide/pull/995)) - Feature `sqlite-storage` was renamed to `sqlite-storage-nativetls`([PR 995](https://github.com/teloxide/teloxide/pull/995)) +- MSRV (Minimal Supported Rust Version) was bumped from `1.68.0` to `1.70.0` ([PR 996][https://github.com/teloxide/teloxide/pull/996]) ### Removed diff --git a/crates/teloxide-core/CHANGELOG.md b/crates/teloxide-core/CHANGELOG.md index f8d06ed7..2066e45d 100644 --- a/crates/teloxide-core/CHANGELOG.md +++ b/crates/teloxide-core/CHANGELOG.md @@ -89,6 +89,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `DefaultParseMode` now also requires that the supported requests implement `Clone` (as a user you should not notice anything changing) - Methods of the Message type: `delete_chat_photo`, `group_chat_created`, `super_group_chat_created`, `channel_chat_created`, `chat_migration`, `migrate_to_chat_id`, `migrate_from_chat_id` now return shared reference instead of owned value inside `Option` ([#982][pr982]) - Methods `delete_chat_photo`, `group_chat_created`, `super_group_chat_created`, `channel_chat_created` now return appropriate structs not `Option` ([#982][pr982]) +- MSRV (Minimal Supported Rust Version) was bumped from `1.68.0` to `1.70.0` ([#996][pr996]) [pr852]: https://github.com/teloxide/teloxide/pull/853 [pr859]: https://github.com/teloxide/teloxide/pull/859 @@ -97,6 +98,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [pr892]: https://github.com/teloxide/teloxide/pull/892 [pr950]: https://github.com/teloxide/teloxide/pull/950 [pr961]: https://github.com/teloxide/teloxide/pull/961 +[pr996]: https://github.com/teloxide/teloxide/pull/996 ### Deprecated From 3565186d618fe31a8906ecc2e85839f54b4a7faf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=8B=D1=80=D1=86=D0=B5=D0=B2=20=D0=92=D0=B0=D0=B4?= =?UTF-8?q?=D0=B8=D0=BC=20=D0=98=D0=B3=D0=BE=D1=80=D0=B5=D0=B2=D0=B8=D1=87?= Date: Sun, 21 Jan 2024 16:25:14 +0300 Subject: [PATCH 07/11] Add `postgres-storage-nativetls` to the `full` feature --- crates/teloxide/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/teloxide/Cargo.toml b/crates/teloxide/Cargo.toml index c17e1eb0..9d3c8dd7 100644 --- a/crates/teloxide/Cargo.toml +++ b/crates/teloxide/Cargo.toml @@ -57,6 +57,7 @@ full = [ # "sqlite-storage-rustls" is explicitly ommited here, # since it conflicts with "sqlite-storage-nativetls" "redis-storage", + "postgres-storage-nativetls", "cbor-serializer", "bincode-serializer", "macros", From fa32ff762e13b0509bb03ae0a1a4979ba1dfed62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=8B=D1=80=D1=86=D0=B5=D0=B2=20=D0=92=D0=B0=D0=B4?= =?UTF-8?q?=D0=B8=D0=BC=20=D0=98=D0=B3=D0=BE=D1=80=D0=B5=D0=B2=D0=B8=D1=87?= Date: Fri, 26 Jan 2024 13:52:55 +0300 Subject: [PATCH 08/11] Replace PostgreSQL service with several docker containers in ci.yml --- .github/workflows/ci.yml | 18 +++++------------- .github/workflows/init.sql | 4 ---- crates/teloxide/tests/postgres.rs | 12 +++++++----- 3 files changed, 12 insertions(+), 22 deletions(-) delete mode 100644 .github/workflows/init.sql diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d2d45f53..840d88ec 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -74,18 +74,6 @@ jobs: test: name: Test runs-on: ubuntu-latest - services: - # Setup Postgres for testing PostgresStorage - postgres: - image: postgres - - volumes: - - init.sql:/docker-entrypoint-initdb.d/init.sql - - env: - POSTGRES_USER: teloxide - POSTGRES_PASSWORD: rewrite_it_in_rust - strategy: matrix: rust: @@ -131,7 +119,11 @@ jobs: redis-server --port 7777 > /dev/null & redis-server --port 7778 > /dev/null & redis-server --port 7779 > /dev/null & - + - name: Start PostgreSQL servers + run: | + docker run -d -p 5432:5432 -e POSTGRES_USER=teloxide -e POSTGRES_PASSWORD=rewrite_it_in_rust -e POSTGRES_DB=test_postgres_json postgres + docker run -d -p 5433:5432 -e POSTGRES_USER=teloxide -e POSTGRES_PASSWORD=rewrite_it_in_rust -e POSTGRES_DB=test_postgres_bincode postgres + docker run -d -p 5434:5432 -e POSTGRES_USER=teloxide -e POSTGRES_PASSWORD=rewrite_it_in_rust -e POSTGRES_DB=test_postgres_cbor postgres - name: Test unit & integration tests run: | cargo +${{ matrix.toolchain }} test --tests --verbose ${{ matrix.features }} diff --git a/.github/workflows/init.sql b/.github/workflows/init.sql deleted file mode 100644 index f7da96c8..00000000 --- a/.github/workflows/init.sql +++ /dev/null @@ -1,4 +0,0 @@ -CREATE ROLE teloxide WITH LOGIN SUPERUSER PASSWORD 'rewrite_it_in_rust' -CREATE DATABASE test_postgres_json; -CREATE DATABASE test_postgres_bincode; -CREATE_DATABASE test_postgres_cbor; \ No newline at end of file diff --git a/crates/teloxide/tests/postgres.rs b/crates/teloxide/tests/postgres.rs index cbcab064..12cc6ecc 100644 --- a/crates/teloxide/tests/postgres.rs +++ b/crates/teloxide/tests/postgres.rs @@ -7,12 +7,14 @@ use teloxide::{ types::ChatId, }; +// These examples are meant to run under the CI with the postgres service +// Were checked locally #[tokio::test] #[cfg_attr(not(CI_POSTGRES), ignore)] async fn test_postgres_json() { let storage = PostgresStorage::open( "postgres://teloxide:rewrite_it_in_rust@localhost:5432/test_postgres_json", - 4, + 1, teloxide::dispatching::dialogue::serializer::Json, ) .await @@ -25,8 +27,8 @@ async fn test_postgres_json() { #[cfg_attr(not(CI_POSTGRES), ignore)] async fn test_postgres_bincode() { let storage = PostgresStorage::open( - "postgres://teloxide:rewrite_it_in_rust@localhost:5432/test_postgres_bincode", - 4, + "postgres://teloxide:rewrite_it_in_rust@localhost:5433/test_postgres_bincode", + 1, teloxide::dispatching::dialogue::serializer::Bincode, ) .await @@ -39,8 +41,8 @@ async fn test_postgres_bincode() { #[cfg_attr(not(CI_POSTGRES), ignore)] async fn test_postgres_cbor() { let storage = PostgresStorage::open( - "postgres://teloxide:rewrite_it_in_rust@localhost:5432/test_postgres_cbor", - 4, + "postgres://teloxide:rewrite_it_in_rust@localhost:5434/test_postgres_cbor", + 1, teloxide::dispatching::dialogue::serializer::Cbor, ) .await From 5a9bbf3f0be0487963c79138e76801d0b2d55090 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=8B=D1=80=D1=86=D0=B5=D0=B2=20=D0=92=D0=B0=D0=B4?= =?UTF-8?q?=D0=B8=D0=BC=20=D0=98=D0=B3=D0=BE=D1=80=D0=B5=D0=B2=D0=B8=D1=87?= Date: Fri, 26 Jan 2024 14:36:33 +0300 Subject: [PATCH 09/11] Try again with postgres service in ci.yml --- .github/workflows/ci.yml | 27 +++++++++++++++++++++++---- crates/teloxide/tests/postgres.rs | 4 ++-- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 840d88ec..d344add2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -74,6 +74,20 @@ jobs: test: name: Test runs-on: ubuntu-latest + services: + # Setup Postgres for testing PostgresStorage + postgres: + image: postgres + env: + POSTGRES_USER: teloxide + POSTGRES_PASSWORD: rewrite_it_in_rust + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + - 5432:5432 strategy: matrix: rust: @@ -119,11 +133,16 @@ jobs: redis-server --port 7777 > /dev/null & redis-server --port 7778 > /dev/null & redis-server --port 7779 > /dev/null & - - name: Start PostgreSQL servers + - name: Install psql run: | - docker run -d -p 5432:5432 -e POSTGRES_USER=teloxide -e POSTGRES_PASSWORD=rewrite_it_in_rust -e POSTGRES_DB=test_postgres_json postgres - docker run -d -p 5433:5432 -e POSTGRES_USER=teloxide -e POSTGRES_PASSWORD=rewrite_it_in_rust -e POSTGRES_DB=test_postgres_bincode postgres - docker run -d -p 5434:5432 -e POSTGRES_USER=teloxide -e POSTGRES_PASSWORD=rewrite_it_in_rust -e POSTGRES_DB=test_postgres_cbor postgres + apt install postgresql-client -y + - name: Create PostgreSQL databases + run: | + psql -h localhost -U teloxide -c "CREATE DATABASE test_postgres_json;" + psql -h localhost -U teloxide -c "CREATE DATABASE test_postgres_bincode;" + psql -h localhost -U teloxide -c "CREATE DATABASE test_postgres_cbor;" + env: + PGPASSWORD: rewrite_it_in_rust - name: Test unit & integration tests run: | cargo +${{ matrix.toolchain }} test --tests --verbose ${{ matrix.features }} diff --git a/crates/teloxide/tests/postgres.rs b/crates/teloxide/tests/postgres.rs index 12cc6ecc..37027484 100644 --- a/crates/teloxide/tests/postgres.rs +++ b/crates/teloxide/tests/postgres.rs @@ -27,7 +27,7 @@ async fn test_postgres_json() { #[cfg_attr(not(CI_POSTGRES), ignore)] async fn test_postgres_bincode() { let storage = PostgresStorage::open( - "postgres://teloxide:rewrite_it_in_rust@localhost:5433/test_postgres_bincode", + "postgres://teloxide:rewrite_it_in_rust@localhost:5432/test_postgres_bincode", 1, teloxide::dispatching::dialogue::serializer::Bincode, ) @@ -41,7 +41,7 @@ async fn test_postgres_bincode() { #[cfg_attr(not(CI_POSTGRES), ignore)] async fn test_postgres_cbor() { let storage = PostgresStorage::open( - "postgres://teloxide:rewrite_it_in_rust@localhost:5434/test_postgres_cbor", + "postgres://teloxide:rewrite_it_in_rust@localhost:5432/test_postgres_cbor", 1, teloxide::dispatching::dialogue::serializer::Cbor, ) From 3a392aded385034523f73bcd4709c4f1c844f337 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=8B=D1=80=D1=86=D0=B5=D0=B2=20=D0=92=D0=B0=D0=B4?= =?UTF-8?q?=D0=B8=D0=BC=20=D0=98=D0=B3=D0=BE=D1=80=D0=B5=D0=B2=D0=B8=D1=87?= Date: Fri, 26 Jan 2024 14:40:06 +0300 Subject: [PATCH 10/11] Fix ci.yml with sudo --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d344add2..ed6b638d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -135,7 +135,7 @@ jobs: redis-server --port 7779 > /dev/null & - name: Install psql run: | - apt install postgresql-client -y + sudo apt install postgresql-client -y - name: Create PostgreSQL databases run: | psql -h localhost -U teloxide -c "CREATE DATABASE test_postgres_json;" From 816f01a9eacfa154aef827c0d5345ed21f348e05 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 Apr 2024 16:25:29 +0000 Subject: [PATCH 11/11] Bump h2 from 0.3.25 to 0.3.26 Bumps [h2](https://github.com/hyperium/h2) from 0.3.25 to 0.3.26. - [Release notes](https://github.com/hyperium/h2/releases) - [Changelog](https://github.com/hyperium/h2/blob/v0.3.26/CHANGELOG.md) - [Commits](https://github.com/hyperium/h2/compare/v0.3.25...v0.3.26) --- updated-dependencies: - dependency-name: h2 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- Cargo.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0a0b9791..7cabfb9e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -689,9 +689,9 @@ checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" [[package]] name = "h2" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fbd2820c5e49886948654ab546d0688ff24530286bdcf8fca3cefb16d4618eb" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" dependencies = [ "bytes", "fnv", @@ -839,7 +839,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.5.6", + "socket2 0.4.10", "tokio", "tower-service", "tracing",