diff --git a/examples/proxy_gluesql_example/src/main.rs b/examples/proxy_gluesql_example/src/main.rs index 616b612fa..59efb7d1c 100644 --- a/examples/proxy_gluesql_example/src/main.rs +++ b/examples/proxy_gluesql_example/src/main.rs @@ -4,6 +4,7 @@ mod entity; +use serde_json::json; use std::{ collections::BTreeMap, sync::{Arc, Mutex}, @@ -12,7 +13,7 @@ use std::{ use gluesql::{memory_storage::MemoryStorage, prelude::Glue}; use sea_orm::{ ActiveValue::Set, Database, DbBackend, DbErr, EntityTrait, ProxyDatabaseTrait, ProxyExecResult, - ProxyRow, Statement, + ProxyInsertResult, ProxyRow, Statement, }; use entity::post::{ActiveModel, Entity}; @@ -81,7 +82,7 @@ impl ProxyDatabaseTrait for ProxyDb { } Ok(ProxyExecResult { - last_insert_id: 1, + last_insert_id: ProxyInsertResult::Inserted(vec![json!(1)]), rows_affected: 1, }) } diff --git a/examples/proxy_surrealdb_example/src/main.rs b/examples/proxy_surrealdb_example/src/main.rs index 90610c18b..28a2bdc0d 100644 --- a/examples/proxy_surrealdb_example/src/main.rs +++ b/examples/proxy_surrealdb_example/src/main.rs @@ -4,6 +4,7 @@ mod entity; +use serde_json::json; use std::{ collections::BTreeMap, sync::{Arc, Mutex}, @@ -11,7 +12,7 @@ use std::{ use sea_orm::{ ActiveValue::Set, Database, DbBackend, DbErr, EntityTrait, ProxyDatabaseTrait, ProxyExecResult, - ProxyRow, Statement, + ProxyInsertResult, ProxyRow, Statement, }; use surrealdb::{ engine::local::{Db, Mem}, @@ -134,7 +135,7 @@ impl ProxyDatabaseTrait for ProxyDb { .unwrap(); Ok(ProxyExecResult { - last_insert_id: 1, + last_insert_id: ProxyInsertResult::Inserted(vec![json!(1)]), rows_affected: 1, }) } diff --git a/src/database/proxy.rs b/src/database/proxy.rs index 470810670..0cbec48d5 100644 --- a/src/database/proxy.rs +++ b/src/database/proxy.rs @@ -1,6 +1,7 @@ use crate::{error::*, ExecResult, ExecResultHolder, QueryResult, QueryResultRow, Statement}; use sea_query::{Value, ValueType}; +use serde_json::json; use std::{collections::BTreeMap, fmt::Debug}; /// Defines the [ProxyDatabaseTrait] to save the functions @@ -26,18 +27,30 @@ pub trait ProxyDatabaseTrait: Send + Sync + std::fmt::Debug { } } +/// The types of results for a proxy INSERT operation +#[derive(Clone, Debug, Default, serde::Serialize, serde::Deserialize)] +pub enum ProxyInsertResult { + /// The INSERT statement did not have any value to insert + #[default] + Empty, + /// The INSERT operation did not insert any valid value + Conflicted, + /// Successfully inserted + Inserted(Vec), +} + /// Defines the results obtained from a [ProxyDatabase] #[derive(Clone, Debug, Default, serde::Serialize, serde::Deserialize)] pub struct ProxyExecResult { /// The last inserted id on auto-increment - pub last_insert_id: u64, + pub last_insert_id: ProxyInsertResult, /// The number of rows affected by the database operation pub rows_affected: u64, } impl ProxyExecResult { /// Create a new [ProxyExecResult] from the last inserted id and the number of rows affected - pub fn new(last_insert_id: u64, rows_affected: u64) -> Self { + pub fn new(last_insert_id: ProxyInsertResult, rows_affected: u64) -> Self { Self { last_insert_id, rows_affected, @@ -64,22 +77,26 @@ impl From for ProxyExecResult { match result.result { #[cfg(feature = "sqlx-mysql")] ExecResultHolder::SqlxMySql(result) => Self { - last_insert_id: result.last_insert_id() as u64, + last_insert_id: ProxyInsertResult::Inserted(vec![json!( + result.last_insert_id() as u64 + )]), rows_affected: result.rows_affected(), }, #[cfg(feature = "sqlx-postgres")] ExecResultHolder::SqlxPostgres(result) => Self { - last_insert_id: 0, + last_insert_id: ProxyInsertResult::Empty, rows_affected: result.rows_affected(), }, #[cfg(feature = "sqlx-sqlite")] ExecResultHolder::SqlxSqlite(result) => Self { - last_insert_id: result.last_insert_rowid() as u64, + last_insert_id: ProxyInsertResult::Inserted(vec![json!( + result.last_insert_rowid() as u64 + )]), rows_affected: result.rows_affected(), }, #[cfg(feature = "mock")] ExecResultHolder::Mock(result) => Self { - last_insert_id: result.last_insert_id, + last_insert_id: ProxyInsertResult::Inserted(vec![json!(result.last_insert_id)]), rows_affected: result.rows_affected, }, ExecResultHolder::Proxy(result) => result, @@ -866,6 +883,8 @@ impl ProxyRow { #[cfg(test)] mod tests { + use serde_json::json; + use crate::{ entity::*, tests_cfg::*, Database, DbBackend, DbErr, ProxyDatabaseTrait, ProxyExecResult, ProxyRow, Statement, @@ -884,7 +903,7 @@ mod tests { fn execute(&self, statement: Statement) -> Result { println!("SQL execute: {}", statement.sql); Ok(ProxyExecResult { - last_insert_id: 1, + last_insert_id: crate::ProxyInsertResult::Inserted(vec![json!(1)]), rows_affected: 1, }) } diff --git a/src/executor/execute.rs b/src/executor/execute.rs index 626dd81b8..b60a59c4e 100644 --- a/src/executor/execute.rs +++ b/src/executor/execute.rs @@ -1,3 +1,5 @@ +use crate::ProxyInsertResult; + /// Defines the result of executing an operation #[derive(Debug)] pub struct ExecResult { @@ -55,7 +57,14 @@ impl ExecResult { #[cfg(feature = "mock")] ExecResultHolder::Mock(result) => result.last_insert_id, #[cfg(feature = "proxy")] - ExecResultHolder::Proxy(result) => result.last_insert_id, + ExecResultHolder::Proxy(result) => match &result.last_insert_id { + ProxyInsertResult::Empty | ProxyInsertResult::Conflicted => 0, + ProxyInsertResult::Inserted(val) => val + .first() + .expect("Cannot get first value of proxy insert result") + .as_u64() + .expect("Cannot convert proxy id to u64"), + }, #[allow(unreachable_patterns)] _ => unreachable!(), }