From 7a980c0d765e96af657fd363b860e445cc685979 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 12 Jan 2024 15:12:51 +0800 Subject: [PATCH] update create implementation --- Cargo.toml | 11 ++++-- luna-orm-macro/Cargo.toml | 2 +- luna-orm-trait/src/lib.rs | 15 ++++++++ src/command_executor.rs | 19 ++++++---- src/database/lib.rs | 3 +- src/database/mysql.rs | 10 ++--- src/database/postgres.rs | 22 ++++++++++- src/database/sqlite.rs | 44 +++++++++++++++++++++- src/lib.rs | 15 ++++++++ src/sql_executor.rs | 19 +++++++++- src/sql_generator.rs | 61 ++++++++++++++++++++++++++++-- src/transaction.rs | 10 +++++ tests/common/mod.rs | 1 + tests/common/mutex.rs | 9 +++++ tests/common/setup_database.rs | 2 + tests/create.rs | 69 ++++++++++++++++++++++++++++++++++ tests/database_test.rs | 7 +++- tests/insert.rs | 11 +++--- tests/location.rs | 6 +-- tests/schema_test.rs | 7 +++- tests/transaction_test.rs | 7 +++- 21 files changed, 313 insertions(+), 37 deletions(-) create mode 100644 tests/common/mutex.rs create mode 100644 tests/create.rs diff --git a/Cargo.toml b/Cargo.toml index 49faccf..14d3852 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,14 +1,14 @@ [package] name = "luna-orm" -version = "0.3.5" +version = "0.3.6" edition = "2021" license-file = "LICENSE" description = "ORM based on sqlx" homepage = "https://github.com/thegenius/luna-orm" [dependencies] -luna-orm-trait = { path = "luna-orm-trait", version = "0.3.5" } -luna-orm-macro = { path = "luna-orm-macro", version = "0.3.5" } +luna-orm-trait = { path = "luna-orm-trait", version = "0.3.6" } +luna-orm-macro = { path = "luna-orm-macro", version = "0.3.6" } thiserror = {workspace = true} sqlx = {workspace = true} path-absolutize = {workspace = true} @@ -36,7 +36,7 @@ members = [ ] [workspace.package] -version = "0.3.5" +version = "0.3.6" [workspace.dependencies] @@ -58,3 +58,6 @@ serde_yaml = "0.9.27" nom = "7.1.3" runtime-fmt = "0.4.1" + +[profile.test] +test-threads = 1 diff --git a/luna-orm-macro/Cargo.toml b/luna-orm-macro/Cargo.toml index cdc1e59..95cfebe 100644 --- a/luna-orm-macro/Cargo.toml +++ b/luna-orm-macro/Cargo.toml @@ -17,5 +17,5 @@ syn = { version = "1.0", features = ["full"] } proc-macro2 = "1.0" case = "1.0" -luna-orm-trait = { path = "../luna-orm-trait", version = "0.3.5" } +luna-orm-trait = { path = "../luna-orm-trait", version = "0.3.6" } sqlx = { workspace = true } diff --git a/luna-orm-trait/src/lib.rs b/luna-orm-trait/src/lib.rs index 2f2ef92..9eb247e 100644 --- a/luna-orm-trait/src/lib.rs +++ b/luna-orm-trait/src/lib.rs @@ -114,6 +114,21 @@ impl SelectedEntity for RecordCount { } } +#[derive(Clone, Debug)] +pub struct LastRowId { + pub id: i64, +} + +impl SelectedEntity for LastRowId { + fn from_any_row(row: AnyRow) -> Result + where + Self: Sized, + { + let last_row_id: i64 = row.try_get("last_row_id")?; + Ok(Self { id: last_row_id }) + } +} + #[derive(Clone, Debug)] pub struct Pagination { pub page_size: usize, diff --git a/src/command_executor.rs b/src/command_executor.rs index f672d50..0af40b3 100644 --- a/src/command_executor.rs +++ b/src/command_executor.rs @@ -30,14 +30,19 @@ pub trait CommandExecutor: SqlExecutor + Debug { return Ok(result); } - async fn create<'a>(&mut self, entity: &'a mut dyn Entity) -> LunaOrmResult<&'a dyn Entity> { - debug!(target: "luna_orm", command = "insert", entity = ?entity); - let sql = self.get_generator().get_insert_sql(entity); - debug!(target: "luna_orm", command = "insert", sql = sql); + async fn create<'a>(&mut self, entity: &'a mut dyn Entity) -> LunaOrmResult { + debug!(target: "luna_orm2", command = "create", entity = ?entity); + let sql = self.get_generator().get_create_sql(entity); + debug!(target: "luna_orm", command = "create", sql = sql); let args = entity.any_arguments_of_insert(); - self.execute(&sql, args).await?; - debug!(target: "luna_orm", command = "insert", result = ?entity); - return Ok(entity); + if entity.get_auto_increment_field().is_some() { + let last_row_id: LastRowId = self.fetch_one(&sql, args).await?; + entity.set_auto_increment_field(Some(last_row_id.id)); + } else { + self.execute(&sql, args).await?; + } + debug!(target: "luna_orm", command = "create", result = ?entity); + return Ok(true); } #[timed] diff --git a/src/database/lib.rs b/src/database/lib.rs index f790f5a..5ad83fa 100644 --- a/src/database/lib.rs +++ b/src/database/lib.rs @@ -72,13 +72,14 @@ pub trait Database: CommandExecutor + SqlExecutor + std::fmt::Debug { } } -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum DatabaseType { SqliteLocal, MySql, PostgreSql, } +#[derive(Debug, Clone)] pub struct DB(pub T); impl Deref for DB diff --git a/src/database/mysql.rs b/src/database/mysql.rs index cf5b079..48101b6 100644 --- a/src/database/mysql.rs +++ b/src/database/mysql.rs @@ -34,15 +34,15 @@ impl CommandExecutor for MysqlDatabase { &self.sql_generator } - async fn create<'a>(&mut self, entity: &'a mut dyn Entity) -> LunaOrmResult<&'a dyn Entity> { - debug!(target: "luna_orm", command = "insert", entity = ?entity); + async fn create<'a>(&mut self, entity: &'a mut dyn Entity) -> LunaOrmResult { + debug!(target: "luna_orm", command = "create", entity = ?entity); let sql = self.get_generator().get_insert_sql(entity); - debug!(target: "luna_orm", command = "insert", sql = sql); + debug!(target: "luna_orm", command = "create", sql = sql); let args = entity.any_arguments_of_insert(); let result = self.execute(&sql, args).await?; entity.set_auto_increment_field(result.last_insert_id()); - debug!(target: "luna_orm", command = "insert", result = ?entity); - return Ok(entity); + debug!(target: "luna_orm", command = "create", result = ?entity); + return Ok(result.rows_affected() > 0); } } diff --git a/src/database/postgres.rs b/src/database/postgres.rs index 35927af..a07dec6 100644 --- a/src/database/postgres.rs +++ b/src/database/postgres.rs @@ -6,11 +6,14 @@ use crate::{error::LunaOrmError, LunaOrmResult}; use sqlx::any::AnyConnectOptions; use sqlx::AnyPool; -use std::str::FromStr; - use crate::command_executor::CommandExecutor; use crate::sql_executor::SqlExecutor; use crate::sql_generator::PostgresGenerator; +use crate::sql_generator::SqlGenerator; +use luna_orm_trait::Entity; +use luna_orm_trait::LastRowId; +use std::str::FromStr; +use tracing::debug; #[derive(Debug)] pub struct PostgresDatabase { @@ -31,6 +34,21 @@ impl CommandExecutor for PostgresDatabase { fn get_generator(&self) -> &Self::G { &self.sql_generator } + + async fn create<'a>(&mut self, entity: &'a mut dyn Entity) -> LunaOrmResult { + debug!(target: "luna_orm", command = "create", entity = ?entity); + let sql = self.get_generator().get_create_sql(entity); + debug!(target: "luna_orm", command = "create", sql = sql); + let args = entity.any_arguments_of_insert(); + if entity.get_auto_increment_field().is_some() { + let last_row_id: LastRowId = self.fetch_one(&sql, args).await?; + entity.set_auto_increment_field(Some(last_row_id.id)); + } else { + self.execute(&sql, args).await?; + } + debug!(target: "luna_orm", command = "create", result = ?entity); + return Ok(true); + } } impl Database for PostgresDatabase { diff --git a/src/database/sqlite.rs b/src/database/sqlite.rs index cdde04d..771f7c3 100644 --- a/src/database/sqlite.rs +++ b/src/database/sqlite.rs @@ -3,7 +3,9 @@ use crate::database::lib::DatabaseType; use crate::database::DB; use crate::{error::LunaOrmError, LunaOrmResult}; +use luna_orm_trait::LastRowId; use sqlx::any::AnyConnectOptions; +use sqlx::any::AnyPoolOptions; use sqlx::sqlite::{SqliteConnectOptions, SqliteJournalMode, SqlitePool, SqliteSynchronous}; use sqlx::AnyPool; @@ -14,6 +16,12 @@ use std::str::FromStr; use crate::command_executor::CommandExecutor; use crate::sql_executor::SqlExecutor; use crate::sql_generator::DefaultSqlGenerator; +use crate::sql_generator::SqlGenerator; +use luna_orm_trait::Entity; +use luna_orm_trait::SelectedEntity; +use sqlx::any::AnyArguments; +use sqlx::any::AnyRow; +use tracing::debug; use path_absolutize::*; @@ -34,7 +42,7 @@ impl SqliteLocalConfig { } } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct SqliteDatabase { database_type: DatabaseType, pool: AnyPool, @@ -53,6 +61,28 @@ impl CommandExecutor for SqliteDatabase { fn get_generator(&self) -> &Self::G { &self.sql_generator } + + // sqlx sqlite driver has bug #2099, it returns result before the actual commit on insert returning clause + // the work around is create a transaction + async fn create<'a>(&mut self, entity: &'a mut dyn Entity) -> LunaOrmResult { + debug!(target: "luna_orm2", command = "create", entity = ?entity); + let sql = self.get_generator().get_create_sql(entity); + debug!(target: "luna_orm", command = "create", sql = sql); + let args = entity.any_arguments_of_insert(); + if entity.get_auto_increment_field().is_some() { + let last_row_id: LastRowId = self.fetch_one(&sql, args).await?; + entity.set_auto_increment_field(Some(last_row_id.id)); + } else { + self.execute(&sql, args).await?; + } + debug!(target: "luna_orm", command = "create", result = ?entity); + + // the work around + let trx = self.pool.begin().await?; + // query the record + trx.commit().await?; + return Ok(true); + } } impl Database for SqliteDatabase { @@ -107,4 +137,16 @@ impl SqliteDatabase { }; return Ok(database); } + + /* + pub async fn from_sqlite_pool(pool: SqlitePool) -> Self { + let generator = DefaultSqlGenerator::new(); + + Self { + database_type: DatabaseType::SqliteLocal, + pool: + sql_generator: generator, + } + } + */ } diff --git a/src/lib.rs b/src/lib.rs index 6ef8656..bca3521 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,18 @@ +//! +//! # LUNA-ORM +//! luna-orm is build for time saving +//! +//! **LUNA-ORM** is an async orm framework based on SQLx. Built with :heart: +//! - **Intuitive** : Simple API, the most simple orm in this world. +//! - **Time Saving** : Most useful API is implemented by default, no need to waste your life. +//! - **Smooth Transaction** : Transaction is almost same as normal. +//! - **Template SQL** : You can execute your own sql with no pain. +//! - **Dynamic Parameters** : Handle complex dynamic sql with default. +//! - **Truly Asynchronous** : Based on SQLx, luna-orm is fully async. +//! - **Error Soundly** : Every error has its meaning. +//! +//! + #![allow(dead_code)] #![allow(async_fn_in_trait)] #![forbid(unsafe_code)] diff --git a/src/sql_executor.rs b/src/sql_executor.rs index dd34eec..5c10eaa 100644 --- a/src/sql_executor.rs +++ b/src/sql_executor.rs @@ -13,6 +13,24 @@ pub trait SqlExecutor { Err(LunaOrmError::NotImplement) } + async fn fetch_one_plain(&mut self, stmt: &str) -> LunaOrmResult + where + SE: SelectedEntity + Send + Unpin, + { + let query = sqlx::query(stmt).try_map(|row: AnyRow| SE::from_any_row(row)); + let result_opt: SE = query.fetch_one(self.get_pool()?).await?; + Ok(result_opt) + } + + async fn fetch_one(&mut self, stmt: &str, args: AnyArguments<'_>) -> LunaOrmResult + where + SE: SelectedEntity + Send + Unpin, + { + let query = sqlx::query_with(stmt, args).try_map(|row: AnyRow| SE::from_any_row(row)); + let result_opt: SE = query.fetch_one(self.get_pool()?).await?; + Ok(result_opt) + } + async fn fetch_optional_plain(&mut self, stmt: &str) -> LunaOrmResult> where SE: SelectedEntity + Send + Unpin, @@ -21,7 +39,6 @@ pub trait SqlExecutor { let result_opt: Option = query.fetch_optional(self.get_pool()?).await?; Ok(result_opt) } - async fn fetch_optional( &mut self, stmt: &str, diff --git a/src/sql_generator.rs b/src/sql_generator.rs index 6074769..e690d9f 100644 --- a/src/sql_generator.rs +++ b/src/sql_generator.rs @@ -3,7 +3,7 @@ use luna_orm_trait::FromClause; use luna_orm_trait::JoinedConditions; use luna_orm_trait::{Entity, Location, Mutation, OrderBy, Pagination, Primary, Selection}; -#[derive(Default, Debug)] +#[derive(Default, Debug, Clone)] pub struct DefaultSqlGenerator {} impl DefaultSqlGenerator { pub fn new() -> Self { @@ -12,7 +12,7 @@ impl DefaultSqlGenerator { } impl SqlGenerator for DefaultSqlGenerator {} -#[derive(Default, Debug)] +#[derive(Default, Debug, Clone)] pub struct MySqlGenerator {} impl MySqlGenerator { pub fn new() -> Self { @@ -45,9 +45,26 @@ impl SqlGenerator for MySqlGenerator { .to_string(); self.post_process(upsert_sql) } + + fn get_create_sql(&self, entity: &dyn Entity) -> String { + let table_name = entity.get_table_name(); + let field_names = entity.get_insert_fields(); + let fields = wrap_fields(&field_names, self.get_wrap_char()); + let marks = generate_question_mark_list(&field_names); + let insert_sql = format!( + "INSERT INTO {}{}{} ({}) VALUES({})", + self.get_wrap_char(), + table_name, + self.get_wrap_char(), + fields, + marks + ) + .to_string(); + self.post_process(insert_sql) + } } -#[derive(Default, Debug)] +#[derive(Default, Debug, Clone)] pub struct PostgresGenerator {} impl PostgresGenerator { pub fn new() -> Self { @@ -90,6 +107,10 @@ pub trait SqlGenerator { origin } + fn get_last_row_id_sql(&self) -> &'static str { + "SELECT last_insert_rowid() as `last_row_id`" + } + fn get_select_sql(&self, selection: &dyn Selection, primay: &dyn Primary) -> String { let table_name = primay.get_table_name(); let selected_fields: Vec = selection.get_selected_fields(); @@ -281,6 +302,40 @@ pub trait SqlGenerator { self.post_process(insert_sql) } + fn get_create_sql(&self, entity: &dyn Entity) -> String { + let table_name = entity.get_table_name(); + let field_names = entity.get_insert_fields(); + let fields = wrap_fields(&field_names, self.get_wrap_char()); + let marks = generate_question_mark_list(&field_names); + let auto_field_name = entity.get_auto_increment_field(); + let create_sql = if auto_field_name.is_some() { + let auto_field_name = auto_field_name.unwrap(); + format!( + "INSERT INTO {}{}{} ({}) VALUES({}) RETURNING {}{}{} AS last_row_id", + self.get_wrap_char(), + table_name, + self.get_wrap_char(), + fields, + marks, + self.get_wrap_char(), + auto_field_name, + self.get_wrap_char() + ) + .to_string() + } else { + format!( + "INSERT INTO {}{}{} ({}) VALUES({})", + self.get_wrap_char(), + table_name, + self.get_wrap_char(), + fields, + marks + ) + .to_string() + }; + self.post_process(create_sql) + } + fn get_upsert_sql(&self, entity: &dyn Entity) -> String { let table_name = entity.get_table_name(); diff --git a/src/transaction.rs b/src/transaction.rs index c6c8640..8b9bd53 100644 --- a/src/transaction.rs +++ b/src/transaction.rs @@ -57,6 +57,16 @@ where let result_vec: Vec = query.fetch_all(&mut *self.transaction).await?; Ok(result_vec) } + + async fn fetch_all_plain(&mut self, stmt: &str) -> LunaOrmResult> + where + SE: SelectedEntity + Send + Unpin, + { + let query = sqlx::query(stmt).try_map(|row: AnyRow| SE::from_any_row(row)); + let result_vec: Vec = query.fetch_all(&mut *self.transaction).await?; + Ok(result_vec) + } + async fn execute( &mut self, stmt: &str, diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 488c209..8c177de 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -1,4 +1,5 @@ mod logger; +pub mod mutex; pub mod schema; mod setup_database; diff --git a/tests/common/mutex.rs b/tests/common/mutex.rs new file mode 100644 index 0000000..69de026 --- /dev/null +++ b/tests/common/mutex.rs @@ -0,0 +1,9 @@ +use std::sync::Arc; +use std::sync::OnceLock; +use tokio::sync::Mutex; + +static GLOBAL_TEST_MUTEX: OnceLock>> = OnceLock::new(); + +pub fn get_test_mutex() -> &'static Arc> { + GLOBAL_TEST_MUTEX.get_or_init(|| Arc::new(Mutex::new(()))) +} diff --git a/tests/common/setup_database.rs b/tests/common/setup_database.rs index 33718d7..808e216 100644 --- a/tests/common/setup_database.rs +++ b/tests/common/setup_database.rs @@ -25,5 +25,7 @@ where let drop_stmt = format!("DROP TABLE IF EXISTS `{}`", table_name); db.execute_plain(&drop_stmt).await?; db.execute_plain(create_table_stmt).await?; + //let delete_stmt = format!("DELETE FROM `{}`", table_name); + //db.execute_plain(&delete_stmt).await?; Ok(true) } diff --git a/tests/create.rs b/tests/create.rs new file mode 100644 index 0000000..b9dc6f2 --- /dev/null +++ b/tests/create.rs @@ -0,0 +1,69 @@ +use luna_orm::prelude::*; +use luna_orm::LunaOrmResult; +mod common; +use common::create_table; +use common::mutex::get_test_mutex; +use common::setup_database; +use common::setup_logger; +use sqlx::sqlx_macros; +use tracing::debug; + +#[derive(Schema, Clone, Debug)] +#[TableName = "user"] +pub struct UserEntity { + #[PrimaryKey] + #[AutoIncrement] + id: Option, + age: Option, + name: String, +} + +#[sqlx_macros::test] +pub async fn test_create() -> LunaOrmResult<()> { + let test_mutex = get_test_mutex(); + let test_lock = test_mutex.lock(); + setup_logger(); + let mut db = setup_database().await?; + create_table(&mut db, "user" , + "create table if not exists `user`(`id` integer primary key autoincrement, `age` INT, `name` VARCHAR(60), create_time DATETIME default current_timestamp)" ).await?; + let mut entity = UserEntity { + id: None, + age: Some(23), + name: "test".to_string(), + }; + + // sqlx sqlite has bug #2099, it does not actually commit insert returning stmt + let result = db.create(&mut entity).await?; + assert_eq!(entity.id, Some(1)); + + let db_clone = db.clone(); + let mut trx = db_clone.transaction().await?; + let selection = UserSelection { + id: true, + age: true, + name: true, + }; + let entities: Vec = trx.search_all(&selection).await?; + trx.commit().await?; + + let location = UserLocation { + id: None, + age: Some(LocationExpr { + val: 23, + cmp: CmpOperator::Eq, + }), + name: None, + }; + let selected: Vec = db.search(&location, None, &selection).await?; + let sql = db + .get_generator() + .get_search_sql(&selection, &location, None); + dbg!(&sql); + assert_eq!(selected.len(), 1); + let selected_one = selected.first().unwrap(); + assert_eq!(selected_one.id, Some(1)); + assert_eq!(selected_one.age, Some(23)); + assert_eq!(selected_one.name, Some("test".to_string())); + + Ok(()) +} diff --git a/tests/database_test.rs b/tests/database_test.rs index 7da1273..bd0b2ba 100644 --- a/tests/database_test.rs +++ b/tests/database_test.rs @@ -1,5 +1,8 @@ use luna_orm::prelude::*; +mod common; +use common::mutex::get_test_mutex; use luna_orm::LunaOrmResult; +use sqlx::sqlx_macros; #[derive(Selection, Debug, Default, Clone)] pub struct HelloSelection { @@ -153,8 +156,10 @@ async fn test_execute_template(db: &mut DB) -> LunaOrmResult<()> Ok(()) } -#[tokio::test] +#[sqlx_macros::test] pub async fn test_database() -> LunaOrmResult<()> { + let test_mutex = get_test_mutex(); + let test_lock = test_mutex.lock(); let config = SqliteLocalConfig::new("./workspace", "test.db"); let mut db: SqliteDatabase = SqliteDatabase::build(config).await.unwrap(); let mut db: DB = DB(db); diff --git a/tests/insert.rs b/tests/insert.rs index e2888e6..f9ee738 100644 --- a/tests/insert.rs +++ b/tests/insert.rs @@ -2,8 +2,10 @@ use luna_orm::prelude::*; use luna_orm::LunaOrmResult; mod common; use common::create_table; +use common::mutex::get_test_mutex; use common::setup_database; use common::setup_logger; +use sqlx::sqlx_macros; use tracing::debug; #[derive(Schema, Clone, Debug)] @@ -16,8 +18,10 @@ pub struct UserEntity { name: String, } -#[tokio::test] +#[sqlx_macros::test] pub async fn test_insert_normal() -> LunaOrmResult<()> { + let test_mutex = get_test_mutex(); + let test_lock = test_mutex.lock(); setup_logger(); let mut db = setup_database().await?; create_table(&mut db, "user" , @@ -28,7 +32,6 @@ pub async fn test_insert_normal() -> LunaOrmResult<()> { name: "test".to_string(), }; - let sql = db.get_generator().get_insert_sql(&entity); let result = db.insert(&entity).await?; assert_eq!(result, true); @@ -49,10 +52,6 @@ pub async fn test_insert_normal() -> LunaOrmResult<()> { name: None, }; let selected: Vec = db.search(&location, None, &selection).await?; - let sql = db - .get_generator() - .get_search_sql(&selection, &location, None); - dbg!(&sql); assert_eq!(selected.len(), 1); let selected_one = selected.first().unwrap(); assert_eq!(selected_one.id, Some(1)); diff --git a/tests/location.rs b/tests/location.rs index a7581b6..6aabdcd 100644 --- a/tests/location.rs +++ b/tests/location.rs @@ -6,10 +6,10 @@ use luna_orm_trait::Location; use luna_orm_trait::LocationExpr; use luna_orm_trait::Selection; */ - use luna_orm::prelude::*; use serde::{Deserialize, Serialize}; use serde_json; +use sqlx::sqlx_macros; fn false_value() -> bool { false @@ -67,8 +67,8 @@ pub struct JoinedQuery { class: ClassJoinedQuery, } -#[tokio::test] -pub async fn test_location() { +#[test] +pub fn test_location() { let content = "{ \"student_name\": true, \"class_name\": false }"; let result: Result = serde_json::from_str(content); assert_eq!(result.is_ok(), true); diff --git a/tests/schema_test.rs b/tests/schema_test.rs index 9aae692..fa50b4d 100644 --- a/tests/schema_test.rs +++ b/tests/schema_test.rs @@ -1,5 +1,8 @@ use luna_orm::prelude::*; use luna_orm::LunaOrmResult; +use sqlx::sqlx_macros; +mod common; +use common::mutex::get_test_mutex; #[derive(OrderBy, Debug, Clone)] pub enum HelloOrderBy { @@ -169,8 +172,10 @@ async fn test_execute_template(db: &mut DB) -> LunaOrmResult<()> Ok(()) } -#[tokio::test] +#[sqlx_macros::test] pub async fn test_database() -> LunaOrmResult<()> { + let test_mutex = get_test_mutex(); + let test_lock = test_mutex.lock(); let config = SqliteLocalConfig { work_dir: "./workspace".to_string(), db_file: "test.db".to_string(), diff --git a/tests/transaction_test.rs b/tests/transaction_test.rs index 464bbe1..d8deea8 100644 --- a/tests/transaction_test.rs +++ b/tests/transaction_test.rs @@ -1,5 +1,8 @@ use luna_orm::prelude::*; use luna_orm::LunaOrmResult; +use sqlx::sqlx_macros; +mod common; +use common::mutex::get_test_mutex; #[derive(Selection, Default, Debug, Clone)] pub struct HelloSelection { @@ -59,8 +62,10 @@ async fn clear_db(db: &mut DB) { db.execute_plain("DELETE FROM `article`").await.unwrap(); } -#[tokio::test] +#[sqlx_macros::test] pub async fn test_transaction() -> LunaOrmResult<()> { + let test_mutex = get_test_mutex(); + let test_lock = test_mutex.lock(); let mut db = build_db().await; inner_test_transaction(&db).await?;