This commit is contained in:
Billy Chan 2021-08-28 23:48:13 +08:00
parent 484da8f6b6
commit ccfda51a5e
No known key found for this signature in database
GPG Key ID: A2D690CAC7DF3CC7
4 changed files with 58 additions and 21 deletions

View File

@ -110,8 +110,11 @@ impl From<PgQueryResult> for ExecResult {
}
}
pub(crate) fn query_result_into_exec_result(res: QueryResult) -> Result<ExecResult, DbErr> {
let last_insert_id: i32 = res.try_get("", "last_insert_id")?;
pub(crate) fn query_result_into_exec_result<T>(res: QueryResult) -> Result<ExecResult, DbErr>
where
T: TryGetable,
{
let last_insert_id: T = res.try_get("", "last_insert_id")?;
Ok(ExecResult {
result: ExecResultHolder::SqlxPostgres {
last_insert_id: last_insert_id as u64,

View File

@ -221,7 +221,11 @@ where
let exec = E::insert(am).exec(db);
let res = exec.await?;
// TODO: if the entity does not have auto increment primary key, then last_insert_id is a wrong value
if <E::PrimaryKey as PrimaryKeyTrait>::auto_increment() && res.last_insert_id != 0 {
// FIXME: Assumed valid last_insert_id is not equals to Default::default()
if <E::PrimaryKey as PrimaryKeyTrait>::auto_increment()
&& res.last_insert_id != <E::PrimaryKey as PrimaryKeyTrait>::ValueType::default()
{
let last_insert_id = res.last_insert_id.to_string();
let find = E::find_by_id(res.last_insert_id).one(db);
let found = find.await;
let model: Option<E::Model> = found?;
@ -230,7 +234,7 @@ where
None => Err(DbErr::Exec(format!(
"Failed to find inserted item: {} {}",
E::default().to_string(),
res.last_insert_id
last_insert_id
))),
}
} else {

View File

@ -1,8 +1,11 @@
use super::{ColumnTrait, IdenStatic, Iterable};
use crate::TryGetable;
use sea_query::IntoValueTuple;
use std::fmt::{Debug, Display};
//LINT: composite primary key cannot auto increment
pub trait PrimaryKeyTrait: IdenStatic + Iterable {
type ValueType: Sized;
type ValueType: Sized + Default + Debug + Display + PartialEq + IntoValueTuple + TryGetable;
fn auto_increment() -> bool;
}

View File

@ -1,15 +1,24 @@
use crate::{error::*, ActiveModelTrait, DatabaseConnection, Insert, Statement};
use crate::{
error::*, ActiveModelTrait, DatabaseConnection, EntityTrait, Insert, PrimaryKeyTrait, Statement,
};
use sea_query::InsertStatement;
use std::future::Future;
use std::{future::Future, marker::PhantomData};
#[derive(Clone, Debug)]
pub struct Inserter {
pub struct Inserter<A>
where
A: ActiveModelTrait,
{
query: InsertStatement,
model: PhantomData<A>,
}
#[derive(Clone, Debug)]
pub struct InsertResult {
pub last_insert_id: u64,
#[derive(Debug)]
pub struct InsertResult<A>
where
A: ActiveModelTrait,
{
pub last_insert_id: <<<A as ActiveModelTrait>::Entity as EntityTrait>::PrimaryKey as PrimaryKeyTrait>::ValueType,
}
impl<A> Insert<A>
@ -17,10 +26,13 @@ where
A: ActiveModelTrait,
{
#[allow(unused_mut)]
pub fn exec(
pub fn exec<'a>(
self,
db: &DatabaseConnection,
) -> impl Future<Output = Result<InsertResult, DbErr>> + '_ {
db: &'a DatabaseConnection,
) -> impl Future<Output = Result<InsertResult<A>, DbErr>> + 'a
where
A: 'a,
{
// so that self is dropped before entering await
let mut query = self.query;
#[cfg(feature = "sqlx-postgres")]
@ -35,26 +47,41 @@ where
);
}
}
Inserter::new(query).exec(db)
Inserter::<A>::new(query).exec(db)
}
}
impl Inserter {
impl<A> Inserter<A>
where
A: ActiveModelTrait,
{
pub fn new(query: InsertStatement) -> Self {
Self { query }
Self {
query,
model: PhantomData,
}
}
pub fn exec(
pub fn exec<'a>(
self,
db: &DatabaseConnection,
) -> impl Future<Output = Result<InsertResult, DbErr>> + '_ {
db: &'a DatabaseConnection,
) -> impl Future<Output = Result<InsertResult<A>, DbErr>> + 'a
where
A: 'a,
{
let builder = db.get_database_backend();
exec_insert(builder.build(&self.query), db)
}
}
// Only Statement impl Send
async fn exec_insert(statement: Statement, db: &DatabaseConnection) -> Result<InsertResult, DbErr> {
async fn exec_insert<A>(
statement: Statement,
db: &DatabaseConnection,
) -> Result<InsertResult<A>, DbErr>
where
A: ActiveModelTrait,
{
// TODO: Postgres instead use query_one + returning clause
let result = match db {
#[cfg(feature = "sqlx-postgres")]