From 8f450196e0e9a8d1bb171cc805452a84d91cc0ce Mon Sep 17 00:00:00 2001 From: mpyw Date: Mon, 12 Aug 2024 14:59:50 +0900 Subject: [PATCH] Refactor: `TransactionManager` delegation without BC SQLite implementation is currently WIP --- sqlx-core/src/any/connection/backend.rs | 5 ++- sqlx-core/src/any/connection/mod.rs | 12 +++---- sqlx-core/src/any/transaction.rs | 5 +++ sqlx-core/src/connection.rs | 43 +++++++++++++------------ sqlx-core/src/transaction.rs | 8 +++++ sqlx-mysql/src/any.rs | 7 ++-- sqlx-mysql/src/connection/mod.rs | 10 +++--- sqlx-mysql/src/transaction.rs | 4 +++ sqlx-postgres/src/any.rs | 7 ++-- sqlx-postgres/src/connection/mod.rs | 10 +++--- sqlx-postgres/src/transaction.rs | 5 +++ sqlx-sqlite/src/any.rs | 7 ++-- sqlx-sqlite/src/connection/mod.rs | 10 +++--- sqlx-sqlite/src/transaction.rs | 9 ++++-- src/lib.rs | 4 +-- tests/postgres/postgres.rs | 1 - 16 files changed, 80 insertions(+), 67 deletions(-) diff --git a/sqlx-core/src/any/connection/backend.rs b/sqlx-core/src/any/connection/backend.rs index a2393832dc..e4e752c07b 100644 --- a/sqlx-core/src/any/connection/backend.rs +++ b/sqlx-core/src/any/connection/backend.rs @@ -1,6 +1,5 @@ use crate::any::{Any, AnyArguments, AnyQueryResult, AnyRow, AnyStatement, AnyTypeInfo}; use crate::describe::Describe; -use crate::Error; use either::Either; use futures_core::future::BoxFuture; use futures_core::stream::BoxStream; @@ -35,13 +34,13 @@ pub trait AnyConnectionBackend: std::any::Any + Debug + Send + 'static { fn start_rollback(&mut self); - /// Returns the current transaction depth asynchronously. + /// Returns the current transaction depth. /// /// Transaction depth indicates the level of nested transactions: /// - Level 0: No active transaction. /// - Level 1: A transaction is active. /// - Level 2 or higher: A transaction is active and one or more SAVEPOINTs have been created within it. - fn get_transaction_depth(&mut self) -> BoxFuture<'_, Result>; + fn get_transaction_depth(&self) -> usize; /// The number of statements currently cached in the connection. fn cached_statements_size(&self) -> usize { diff --git a/sqlx-core/src/any/connection/mod.rs b/sqlx-core/src/any/connection/mod.rs index c2274d9885..ba06d865f1 100644 --- a/sqlx-core/src/any/connection/mod.rs +++ b/sqlx-core/src/any/connection/mod.rs @@ -1,7 +1,7 @@ use futures_core::future::BoxFuture; use crate::any::{Any, AnyConnectOptions}; -use crate::connection::{AsyncTransactionDepth, ConnectOptions, Connection}; +use crate::connection::{ConnectOptions, Connection}; use crate::error::Error; use crate::database::Database; @@ -90,6 +90,10 @@ impl Connection for AnyConnection { Transaction::begin(self) } + fn get_transaction_depth(&self) -> usize { + self.backend.get_transaction_depth() + } + fn cached_statements_size(&self) -> usize { self.backend.cached_statements_size() } @@ -112,9 +116,3 @@ impl Connection for AnyConnection { self.backend.should_flush() } } - -impl AsyncTransactionDepth for AnyConnection { - fn get_transaction_depth(&mut self) -> BoxFuture<'_, Result> { - self.backend.get_transaction_depth() - } -} diff --git a/sqlx-core/src/any/transaction.rs b/sqlx-core/src/any/transaction.rs index fce4175626..22937a0bd1 100644 --- a/sqlx-core/src/any/transaction.rs +++ b/sqlx-core/src/any/transaction.rs @@ -1,6 +1,7 @@ use futures_util::future::BoxFuture; use crate::any::{Any, AnyConnection}; +use crate::database::Database; use crate::error::Error; use crate::transaction::TransactionManager; @@ -24,4 +25,8 @@ impl TransactionManager for AnyTransactionManager { fn start_rollback(conn: &mut AnyConnection) { conn.backend.start_rollback() } + + fn get_transaction_depth(conn: &::Connection) -> usize { + conn.backend.get_transaction_depth() + } } diff --git a/sqlx-core/src/connection.rs b/sqlx-core/src/connection.rs index 155f29d268..9faa71effe 100644 --- a/sqlx-core/src/connection.rs +++ b/sqlx-core/src/connection.rs @@ -1,7 +1,7 @@ use crate::database::{Database, HasStatementCache}; use crate::error::Error; -use crate::transaction::Transaction; +use crate::transaction::{Transaction, TransactionManager}; use futures_core::future::BoxFuture; use log::LevelFilter; use std::fmt::Debug; @@ -49,6 +49,27 @@ pub trait Connection: Send { where Self: Sized; + /// Returns the current transaction depth synchronously. + /// + /// Transaction depth indicates the level of nested transactions: + /// - Level 0: No active transaction. + /// - Level 1: A transaction is active. + /// - Level 2 or higher: A transaction is active and one or more SAVEPOINTs have been created within it. + fn get_transaction_depth(&self) -> usize { + // Fallback implementation to avoid breaking changes + ::TransactionManager::get_transaction_depth(self) + } + + /// Checks if the connection is currently in a transaction. + /// + /// This method returns `true` if the current transaction depth is greater than 0, + /// indicating that a transaction is active. It returns `false` if the transaction depth is 0, + /// meaning no transaction is active. + #[inline] + fn is_in_transaction(&self) -> bool { + self.get_transaction_depth() != 0 + } + /// Execute the function inside a transaction. /// /// If the function returns an error, the transaction will be rolled back. If it does not @@ -236,23 +257,3 @@ pub trait ConnectOptions: 'static + Send + Sync + FromStr + Debug + .log_slow_statements(LevelFilter::Off, Duration::default()) } } - -pub trait TransactionDepth { - /// Returns the current transaction depth synchronously. - /// - /// Transaction depth indicates the level of nested transactions: - /// - Level 0: No active transaction. - /// - Level 1: A transaction is active. - /// - Level 2 or higher: A transaction is active and one or more SAVEPOINTs have been created within it. - fn get_transaction_depth(&self) -> usize; -} - -pub trait AsyncTransactionDepth { - /// Returns the current transaction depth asynchronously. - /// - /// Transaction depth indicates the level of nested transactions: - /// - Level 0: No active transaction. - /// - Level 1: A transaction is active. - /// - Level 2 or higher: A transaction is active and one or more SAVEPOINTs have been created within it. - fn get_transaction_depth(&mut self) -> BoxFuture<'_, Result>; -} diff --git a/sqlx-core/src/transaction.rs b/sqlx-core/src/transaction.rs index 9cd38aab3a..48b1463f2a 100644 --- a/sqlx-core/src/transaction.rs +++ b/sqlx-core/src/transaction.rs @@ -32,6 +32,14 @@ pub trait TransactionManager { /// Starts to abort the active transaction or restore from the most recent snapshot. fn start_rollback(conn: &mut ::Connection); + + /// Returns the current transaction depth. + /// + /// Transaction depth indicates the level of nested transactions: + /// - Level 0: No active transaction. + /// - Level 1: A transaction is active. + /// - Level 2 or higher: A transaction is active and one or more SAVEPOINTs have been created within it. + fn get_transaction_depth(conn: &::Connection) -> usize; } /// An in-progress database transaction or savepoint. diff --git a/sqlx-mysql/src/any.rs b/sqlx-mysql/src/any.rs index c688ad0d48..709fdafcea 100644 --- a/sqlx-mysql/src/any.rs +++ b/sqlx-mysql/src/any.rs @@ -11,12 +11,11 @@ use sqlx_core::any::{ Any, AnyArguments, AnyColumn, AnyConnectOptions, AnyConnectionBackend, AnyQueryResult, AnyRow, AnyStatement, AnyTypeInfo, AnyTypeInfoKind, }; -use sqlx_core::connection::{Connection, TransactionDepth}; +use sqlx_core::connection::Connection; use sqlx_core::database::Database; use sqlx_core::describe::Describe; use sqlx_core::executor::Executor; use sqlx_core::transaction::TransactionManager; -use sqlx_core::Error; use std::future; sqlx_core::declare_driver_with_optional_migrate!(DRIVER = MySql); @@ -54,8 +53,8 @@ impl AnyConnectionBackend for MySqlConnection { MySqlTransactionManager::start_rollback(self) } - fn get_transaction_depth(&mut self) -> BoxFuture<'_, Result> { - Box::pin(async { Ok(TransactionDepth::get_transaction_depth(self)) }) + fn get_transaction_depth(&self) -> usize { + MySqlTransactionManager::get_transaction_depth(self) } fn shrink_buffers(&mut self) { diff --git a/sqlx-mysql/src/connection/mod.rs b/sqlx-mysql/src/connection/mod.rs index b2a9a94b42..af50188ff6 100644 --- a/sqlx-mysql/src/connection/mod.rs +++ b/sqlx-mysql/src/connection/mod.rs @@ -114,13 +114,11 @@ impl Connection for MySqlConnection { Transaction::begin(self) } - fn shrink_buffers(&mut self) { - self.inner.stream.shrink_buffers(); - } -} - -impl TransactionDepth for MySqlConnection { fn get_transaction_depth(&self) -> usize { self.inner.transaction_depth } + + fn shrink_buffers(&mut self) { + self.inner.stream.shrink_buffers(); + } } diff --git a/sqlx-mysql/src/transaction.rs b/sqlx-mysql/src/transaction.rs index 99d6526392..5a4c751b2c 100644 --- a/sqlx-mysql/src/transaction.rs +++ b/sqlx-mysql/src/transaction.rs @@ -64,4 +64,8 @@ impl TransactionManager for MySqlTransactionManager { conn.inner.transaction_depth = depth - 1; } } + + fn get_transaction_depth(conn: &MySqlConnection) -> usize { + conn.inner.transaction_depth + } } diff --git a/sqlx-postgres/src/any.rs b/sqlx-postgres/src/any.rs index d0e0459721..bcfef8dce1 100644 --- a/sqlx-postgres/src/any.rs +++ b/sqlx-postgres/src/any.rs @@ -10,13 +10,12 @@ use std::future; pub use sqlx_core::any::*; use crate::type_info::PgType; -use sqlx_core::connection::{Connection, TransactionDepth}; +use sqlx_core::connection::Connection; use sqlx_core::database::Database; use sqlx_core::describe::Describe; use sqlx_core::executor::Executor; use sqlx_core::ext::ustr::UStr; use sqlx_core::transaction::TransactionManager; -use sqlx_core::Error; sqlx_core::declare_driver_with_optional_migrate!(DRIVER = Postgres); @@ -53,8 +52,8 @@ impl AnyConnectionBackend for PgConnection { PgTransactionManager::start_rollback(self) } - fn get_transaction_depth(&mut self) -> BoxFuture<'_, Result> { - Box::pin(async { Ok(TransactionDepth::get_transaction_depth(self)) }) + fn get_transaction_depth(&mut self) -> usize { + PgTransactionManager::get_transaction_depth(self) } fn shrink_buffers(&mut self) { diff --git a/sqlx-postgres/src/connection/mod.rs b/sqlx-postgres/src/connection/mod.rs index 8e3143fec7..dcfc6206a5 100644 --- a/sqlx-postgres/src/connection/mod.rs +++ b/sqlx-postgres/src/connection/mod.rs @@ -171,6 +171,10 @@ impl Connection for PgConnection { Transaction::begin(self) } + fn get_transaction_depth(&self) -> usize { + self.transaction_depth + } + fn cached_statements_size(&self) -> usize { self.cache_statement.len() } @@ -224,9 +228,3 @@ impl AsMut for PgConnection { self } } - -impl TransactionDepth for PgConnection { - fn get_transaction_depth(&self) -> usize { - self.transaction_depth - } -} diff --git a/sqlx-postgres/src/transaction.rs b/sqlx-postgres/src/transaction.rs index 02028624e1..40a2de2e6f 100644 --- a/sqlx-postgres/src/transaction.rs +++ b/sqlx-postgres/src/transaction.rs @@ -1,4 +1,5 @@ use futures_core::future::BoxFuture; +use sqlx_core::database::Database; use crate::error::Error; use crate::executor::Executor; @@ -59,6 +60,10 @@ impl TransactionManager for PgTransactionManager { conn.transaction_depth -= 1; } } + + fn get_transaction_depth(conn: &::Connection) -> usize { + conn.transaction_depth + } } struct Rollback<'c> { diff --git a/sqlx-sqlite/src/any.rs b/sqlx-sqlite/src/any.rs index c14a4eaa29..29fb6bd7a6 100644 --- a/sqlx-sqlite/src/any.rs +++ b/sqlx-sqlite/src/any.rs @@ -12,12 +12,11 @@ use sqlx_core::any::{ }; use crate::type_info::DataType; -use sqlx_core::connection::{AsyncTransactionDepth, ConnectOptions, Connection}; +use sqlx_core::connection::{ConnectOptions, Connection}; use sqlx_core::database::Database; use sqlx_core::describe::Describe; use sqlx_core::executor::Executor; use sqlx_core::transaction::TransactionManager; -use sqlx_core::Error; sqlx_core::declare_driver_with_optional_migrate!(DRIVER = Sqlite); @@ -54,8 +53,8 @@ impl AnyConnectionBackend for SqliteConnection { SqliteTransactionManager::start_rollback(self) } - fn get_transaction_depth(&mut self) -> BoxFuture<'_, Result> { - AsyncTransactionDepth::get_transaction_depth(self) + fn get_transaction_depth(&self) -> usize { + SqliteTransactionManager::get_transaction_depth(self) } fn shrink_buffers(&mut self) { diff --git a/sqlx-sqlite/src/connection/mod.rs b/sqlx-sqlite/src/connection/mod.rs index a58428e14a..f12f49edbd 100644 --- a/sqlx-sqlite/src/connection/mod.rs +++ b/sqlx-sqlite/src/connection/mod.rs @@ -210,6 +210,10 @@ impl Connection for SqliteConnection { Transaction::begin(self) } + fn get_transaction_depth(&self) -> usize { + todo!() + } + fn cached_statements_size(&self) -> usize { self.worker .shared @@ -426,9 +430,3 @@ impl Statements { self.temp = None; } } - -impl AsyncTransactionDepth for SqliteConnection { - fn get_transaction_depth(&mut self) -> BoxFuture<'_, Result> { - Box::pin(async { Ok(self.lock_handle().await?.guard.transaction_depth) }) - } -} diff --git a/sqlx-sqlite/src/transaction.rs b/sqlx-sqlite/src/transaction.rs index 24eaca51b1..dafc33359d 100644 --- a/sqlx-sqlite/src/transaction.rs +++ b/sqlx-sqlite/src/transaction.rs @@ -1,9 +1,10 @@ use futures_core::future::BoxFuture; - -use crate::{Sqlite, SqliteConnection}; +use sqlx_core::database::Database; use sqlx_core::error::Error; use sqlx_core::transaction::TransactionManager; +use crate::{Sqlite, SqliteConnection}; + /// Implementation of [`TransactionManager`] for SQLite. pub struct SqliteTransactionManager; @@ -25,4 +26,8 @@ impl TransactionManager for SqliteTransactionManager { fn start_rollback(conn: &mut SqliteConnection) { conn.worker.start_rollback().ok(); } + + fn get_transaction_depth(_conn: &::Connection) -> usize { + todo!() + } } diff --git a/src/lib.rs b/src/lib.rs index 7a0a7c5fa0..d675fa11c3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,9 +5,7 @@ pub use sqlx_core::acquire::Acquire; pub use sqlx_core::arguments::{Arguments, IntoArguments}; pub use sqlx_core::column::Column; pub use sqlx_core::column::ColumnIndex; -pub use sqlx_core::connection::{ - AsyncTransactionDepth, ConnectOptions, Connection, TransactionDepth, -}; +pub use sqlx_core::connection::{ConnectOptions, Connection}; pub use sqlx_core::database::{self, Database}; pub use sqlx_core::describe::Describe; pub use sqlx_core::executor::{Execute, Executor}; diff --git a/tests/postgres/postgres.rs b/tests/postgres/postgres.rs index cdc518c666..8e5d0d227e 100644 --- a/tests/postgres/postgres.rs +++ b/tests/postgres/postgres.rs @@ -6,7 +6,6 @@ use sqlx::postgres::{ PgPoolOptions, PgRow, PgSeverity, Postgres, }; use sqlx::{Column, Connection, Executor, Row, Statement, TypeInfo}; -use sqlx_core::connection::TransactionDepth; use sqlx_core::{bytes::Bytes, error::BoxDynError}; use sqlx_test::{new, pool, setup_if_needed}; use std::env;