mirror of
https://github.com/aljazceru/turso.git
synced 2026-02-11 03:04:22 +01:00
bind/rust: Add more tests for Transaction
This commit is contained in:
@@ -36,6 +36,7 @@ pub mod params;
|
||||
pub mod transaction;
|
||||
pub mod value;
|
||||
|
||||
use transaction::TransactionBehavior;
|
||||
pub use value::Value;
|
||||
|
||||
pub use params::params_from_iter;
|
||||
@@ -132,6 +133,7 @@ impl Database {
|
||||
#[allow(clippy::arc_with_non_send_sync)]
|
||||
let connection = Connection {
|
||||
inner: Arc::new(Mutex::new(conn)),
|
||||
transaction_behavior: TransactionBehavior::Deferred,
|
||||
};
|
||||
Ok(connection)
|
||||
}
|
||||
@@ -140,12 +142,14 @@ impl Database {
|
||||
/// A database connection.
|
||||
pub struct Connection {
|
||||
inner: Arc<Mutex<Arc<turso_core::Connection>>>,
|
||||
transaction_behavior: TransactionBehavior,
|
||||
}
|
||||
|
||||
impl Clone for Connection {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
inner: Arc::clone(&self.inner),
|
||||
transaction_behavior: self.transaction_behavior,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -288,7 +288,7 @@ impl Connection {
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::{Builder, Connection, Result};
|
||||
use crate::{Builder, Connection, Error, Result};
|
||||
|
||||
use super::DropBehavior;
|
||||
|
||||
@@ -299,18 +299,30 @@ mod test {
|
||||
Ok(conn)
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[should_panic(expected = "Transaction dropped without finish()")]
|
||||
async fn test_drop_panic() {
|
||||
let mut conn = checked_memory_handle().await.unwrap();
|
||||
{
|
||||
let tx = conn.transaction().await.unwrap();
|
||||
tx.execute("INSERT INTO foo VALUES(?)", &[1]).await.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_drop() -> Result<()> {
|
||||
let mut conn = checked_memory_handle().await?;
|
||||
{
|
||||
let tx = conn.transaction().await?;
|
||||
tx.execute("INSERT INTO foo VALUES(?)", &[1]).await?;
|
||||
tx.finish().await?;
|
||||
// default: rollback
|
||||
}
|
||||
{
|
||||
let mut tx = conn.transaction().await?;
|
||||
tx.execute("INSERT INTO foo VALUES(?)", &[2]).await?;
|
||||
tx.set_drop_behavior(DropBehavior::Commit)
|
||||
tx.set_drop_behavior(DropBehavior::Commit);
|
||||
tx.finish().await?;
|
||||
}
|
||||
{
|
||||
let tx = conn.transaction().await?;
|
||||
@@ -325,6 +337,87 @@ mod test {
|
||||
.as_integer()
|
||||
.unwrap()
|
||||
);
|
||||
tx.finish().await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn assert_nested_tx_error(e: Error) {
|
||||
if let Error::SqlExecutionFailure(e) = &e {
|
||||
assert!(e.contains("transaction"));
|
||||
} else {
|
||||
panic!("Unexpected error type: {e:?}");
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_unchecked_nesting() -> Result<()> {
|
||||
let conn = checked_memory_handle().await?;
|
||||
|
||||
{
|
||||
let tx = conn.unchecked_transaction().await?;
|
||||
let e = tx.unchecked_transaction().await.unwrap_err();
|
||||
assert_nested_tx_error(e);
|
||||
tx.finish().await?;
|
||||
// default: rollback
|
||||
}
|
||||
{
|
||||
let tx = conn.unchecked_transaction().await?;
|
||||
tx.execute("INSERT INTO foo VALUES(?)", &[1]).await?;
|
||||
// Ensure this doesn't interfere with ongoing transaction
|
||||
let e = tx.unchecked_transaction().await.unwrap_err();
|
||||
assert_nested_tx_error(e);
|
||||
|
||||
tx.execute("INSERT INTO foo VALUES(?)", &[1]).await?;
|
||||
tx.commit().await?;
|
||||
}
|
||||
|
||||
let mut result = conn.query("SELECT SUM(x) FROM foo", ()).await?;
|
||||
assert_eq!(
|
||||
2,
|
||||
*result
|
||||
.next()
|
||||
.await?
|
||||
.unwrap()
|
||||
.get_value(0)?
|
||||
.as_integer()
|
||||
.unwrap()
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_explicit_rollback_commit() -> Result<()> {
|
||||
let mut conn = checked_memory_handle().await?;
|
||||
{
|
||||
let tx = conn.transaction().await?;
|
||||
tx.execute("INSERT INTO foo VALUES(?)", &[1]).await?;
|
||||
tx.rollback().await?;
|
||||
|
||||
// This is a current Turso's limitation.
|
||||
// Since we don't have support for savepoints yet,
|
||||
// a rollback ends with a transaction so we need to immediately open a new one.
|
||||
let tx = conn.transaction().await?;
|
||||
tx.execute("INSERT INTO foo VALUES(?)", &[2]).await?;
|
||||
tx.commit().await?;
|
||||
}
|
||||
{
|
||||
let tx = conn.transaction().await?;
|
||||
tx.execute("INSERT INTO foo VALUES(?)", &[4]).await?;
|
||||
tx.commit().await?;
|
||||
}
|
||||
{
|
||||
let mut result = conn.query("SELECT SUM(x) FROM foo", ()).await?;
|
||||
assert_eq!(
|
||||
2,
|
||||
*result
|
||||
.next()
|
||||
.await?
|
||||
.unwrap()
|
||||
.get_value(0)?
|
||||
.as_integer()
|
||||
.unwrap()
|
||||
);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user