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> {
|
pub(crate) fn query_result_into_exec_result<T>(res: QueryResult) -> Result<ExecResult, DbErr>
|
||||||
let last_insert_id: i32 = res.try_get("", "last_insert_id")?;
|
where
|
||||||
|
T: TryGetable,
|
||||||
|
{
|
||||||
|
let last_insert_id: T = res.try_get("", "last_insert_id")?;
|
||||||
Ok(ExecResult {
|
Ok(ExecResult {
|
||||||
result: ExecResultHolder::SqlxPostgres {
|
result: ExecResultHolder::SqlxPostgres {
|
||||||
last_insert_id: last_insert_id as u64,
|
last_insert_id: last_insert_id as u64,
|
||||||
|
@ -221,7 +221,11 @@ where
|
|||||||
let exec = E::insert(am).exec(db);
|
let exec = E::insert(am).exec(db);
|
||||||
let res = exec.await?;
|
let res = exec.await?;
|
||||||
// TODO: if the entity does not have auto increment primary key, then last_insert_id is a wrong value
|
// 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 find = E::find_by_id(res.last_insert_id).one(db);
|
||||||
let found = find.await;
|
let found = find.await;
|
||||||
let model: Option<E::Model> = found?;
|
let model: Option<E::Model> = found?;
|
||||||
@ -230,7 +234,7 @@ where
|
|||||||
None => Err(DbErr::Exec(format!(
|
None => Err(DbErr::Exec(format!(
|
||||||
"Failed to find inserted item: {} {}",
|
"Failed to find inserted item: {} {}",
|
||||||
E::default().to_string(),
|
E::default().to_string(),
|
||||||
res.last_insert_id
|
last_insert_id
|
||||||
))),
|
))),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
use super::{ColumnTrait, IdenStatic, Iterable};
|
use super::{ColumnTrait, IdenStatic, Iterable};
|
||||||
|
use crate::TryGetable;
|
||||||
|
use sea_query::IntoValueTuple;
|
||||||
|
use std::fmt::{Debug, Display};
|
||||||
|
|
||||||
//LINT: composite primary key cannot auto increment
|
//LINT: composite primary key cannot auto increment
|
||||||
pub trait PrimaryKeyTrait: IdenStatic + Iterable {
|
pub trait PrimaryKeyTrait: IdenStatic + Iterable {
|
||||||
type ValueType: Sized;
|
type ValueType: Sized + Default + Debug + Display + PartialEq + IntoValueTuple + TryGetable;
|
||||||
|
|
||||||
fn auto_increment() -> bool;
|
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 sea_query::InsertStatement;
|
||||||
use std::future::Future;
|
use std::{future::Future, marker::PhantomData};
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Inserter {
|
pub struct Inserter<A>
|
||||||
|
where
|
||||||
|
A: ActiveModelTrait,
|
||||||
|
{
|
||||||
query: InsertStatement,
|
query: InsertStatement,
|
||||||
|
model: PhantomData<A>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Debug)]
|
||||||
pub struct InsertResult {
|
pub struct InsertResult<A>
|
||||||
pub last_insert_id: u64,
|
where
|
||||||
|
A: ActiveModelTrait,
|
||||||
|
{
|
||||||
|
pub last_insert_id: <<<A as ActiveModelTrait>::Entity as EntityTrait>::PrimaryKey as PrimaryKeyTrait>::ValueType,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A> Insert<A>
|
impl<A> Insert<A>
|
||||||
@ -17,10 +26,13 @@ where
|
|||||||
A: ActiveModelTrait,
|
A: ActiveModelTrait,
|
||||||
{
|
{
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
pub fn exec(
|
pub fn exec<'a>(
|
||||||
self,
|
self,
|
||||||
db: &DatabaseConnection,
|
db: &'a DatabaseConnection,
|
||||||
) -> impl Future<Output = Result<InsertResult, DbErr>> + '_ {
|
) -> impl Future<Output = Result<InsertResult<A>, DbErr>> + 'a
|
||||||
|
where
|
||||||
|
A: 'a,
|
||||||
|
{
|
||||||
// so that self is dropped before entering await
|
// so that self is dropped before entering await
|
||||||
let mut query = self.query;
|
let mut query = self.query;
|
||||||
#[cfg(feature = "sqlx-postgres")]
|
#[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 {
|
pub fn new(query: InsertStatement) -> Self {
|
||||||
Self { query }
|
Self {
|
||||||
|
query,
|
||||||
|
model: PhantomData,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn exec(
|
pub fn exec<'a>(
|
||||||
self,
|
self,
|
||||||
db: &DatabaseConnection,
|
db: &'a DatabaseConnection,
|
||||||
) -> impl Future<Output = Result<InsertResult, DbErr>> + '_ {
|
) -> impl Future<Output = Result<InsertResult<A>, DbErr>> + 'a
|
||||||
|
where
|
||||||
|
A: 'a,
|
||||||
|
{
|
||||||
let builder = db.get_database_backend();
|
let builder = db.get_database_backend();
|
||||||
exec_insert(builder.build(&self.query), db)
|
exec_insert(builder.build(&self.query), db)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only Statement impl Send
|
// 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
|
// TODO: Postgres instead use query_one + returning clause
|
||||||
let result = match db {
|
let result = match db {
|
||||||
#[cfg(feature = "sqlx-postgres")]
|
#[cfg(feature = "sqlx-postgres")]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user