WIP
This commit is contained in:
parent
484da8f6b6
commit
ccfda51a5e
@ -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,
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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")]
|
||||
|
Loading…
x
Reference in New Issue
Block a user