Remove ValueType: Default
This commit is contained in:
parent
c12e0cd44e
commit
f79a417150
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
error::*, DatabaseConnection, DeleteResult, EntityTrait, Iterable, PrimaryKeyToColumn,
|
||||
PrimaryKeyTrait, Value,
|
||||
PrimaryKeyValue, Value,
|
||||
};
|
||||
use async_trait::async_trait;
|
||||
use std::fmt::Debug;
|
||||
@ -70,23 +70,18 @@ pub trait ActiveModelTrait: Clone + Debug {
|
||||
async fn insert(self, db: &DatabaseConnection) -> Result<Self, DbErr>
|
||||
where
|
||||
<Self::Entity as EntityTrait>::Model: IntoActiveModel<Self>,
|
||||
<<Self as ActiveModelTrait>::Entity as EntityTrait>::PrimaryKey:
|
||||
PrimaryKeyValue<<Self as ActiveModelTrait>::Entity>,
|
||||
{
|
||||
let am = self;
|
||||
let exec = <Self::Entity as EntityTrait>::insert(am).exec(db);
|
||||
let res = exec.await?;
|
||||
// Assume valid last_insert_id is not equals to Default::default()
|
||||
if res.last_insert_id
|
||||
!= <<Self::Entity as EntityTrait>::PrimaryKey as PrimaryKeyTrait>::ValueType::default()
|
||||
{
|
||||
let found = <Self::Entity as EntityTrait>::find_by_id(res.last_insert_id)
|
||||
.one(db)
|
||||
.await?;
|
||||
match found {
|
||||
Some(model) => Ok(model.into_active_model()),
|
||||
None => Err(DbErr::Exec("Failed to find inserted item".to_owned())),
|
||||
}
|
||||
} else {
|
||||
Ok(Self::default())
|
||||
let found = <Self::Entity as EntityTrait>::find_by_id(res.last_insert_id)
|
||||
.one(db)
|
||||
.await?;
|
||||
match found {
|
||||
Some(model) => Ok(model.into_active_model()),
|
||||
None => Err(DbErr::Exec("Failed to find inserted item".to_owned())),
|
||||
}
|
||||
}
|
||||
|
||||
@ -101,6 +96,8 @@ pub trait ActiveModelTrait: Clone + Debug {
|
||||
where
|
||||
Self: ActiveModelBehavior,
|
||||
<Self::Entity as EntityTrait>::Model: IntoActiveModel<Self>,
|
||||
<<Self as ActiveModelTrait>::Entity as EntityTrait>::PrimaryKey:
|
||||
PrimaryKeyValue<<Self as ActiveModelTrait>::Entity>,
|
||||
{
|
||||
let mut am = self;
|
||||
am = ActiveModelBehavior::before_save(am);
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
ActiveModelTrait, ColumnTrait, Delete, DeleteMany, DeleteOne, FromQueryResult, Insert,
|
||||
ModelTrait, PrimaryKeyToColumn, PrimaryKeyTrait, QueryFilter, Related, RelationBuilder,
|
||||
RelationTrait, RelationType, Select, Update, UpdateMany, UpdateOne,
|
||||
ModelTrait, PrimaryKeyToColumn, PrimaryKeyTrait, PrimaryKeyValue, QueryFilter, Related,
|
||||
RelationBuilder, RelationTrait, RelationType, Select, Update, UpdateMany, UpdateOne,
|
||||
};
|
||||
use sea_query::{Alias, Iden, IntoIden, IntoTableRef, IntoValueTuple, TableRef};
|
||||
pub use sea_strum::IntoEnumIterator as Iterable;
|
||||
@ -299,6 +299,8 @@ pub trait EntityTrait: EntityName {
|
||||
fn insert<A>(model: A) -> Insert<A>
|
||||
where
|
||||
A: ActiveModelTrait<Entity = Self>,
|
||||
<<A as ActiveModelTrait>::Entity as EntityTrait>::PrimaryKey:
|
||||
PrimaryKeyValue<<A as ActiveModelTrait>::Entity>,
|
||||
{
|
||||
Insert::one(model)
|
||||
}
|
||||
@ -352,6 +354,8 @@ pub trait EntityTrait: EntityName {
|
||||
where
|
||||
A: ActiveModelTrait<Entity = Self>,
|
||||
I: IntoIterator<Item = A>,
|
||||
<<A as ActiveModelTrait>::Entity as EntityTrait>::PrimaryKey:
|
||||
PrimaryKeyValue<<A as ActiveModelTrait>::Entity>,
|
||||
{
|
||||
Insert::many(models)
|
||||
}
|
||||
|
@ -2,8 +2,9 @@ pub use crate::{
|
||||
error::*, ActiveModelBehavior, ActiveModelTrait, ColumnDef, ColumnTrait, ColumnType,
|
||||
DeriveActiveModel, DeriveActiveModelBehavior, DeriveColumn, DeriveCustomColumn, DeriveEntity,
|
||||
DeriveEntityModel, DeriveModel, DerivePrimaryKey, DeriveRelation, EntityName, EntityTrait,
|
||||
EnumIter, ForeignKeyAction, Iden, IdenStatic, Linked, ModelTrait, PrimaryKeyToColumn,
|
||||
PrimaryKeyTrait, QueryFilter, QueryResult, Related, RelationDef, RelationTrait, Select, Value,
|
||||
EnumIter, ForeignKeyAction, Iden, IdenStatic, IntoActiveModel, Linked, ModelTrait,
|
||||
PrimaryKeyToColumn, PrimaryKeyTrait, PrimaryKeyValue, QueryFilter, QueryResult, Related,
|
||||
RelationDef, RelationTrait, Select, Value,
|
||||
};
|
||||
|
||||
#[cfg(feature = "with-json")]
|
||||
|
@ -1,18 +1,11 @@
|
||||
use super::{ColumnTrait, IdenStatic, Iterable};
|
||||
use crate::{TryFromU64, TryGetableMany};
|
||||
use crate::{ActiveModelTrait, EntityTrait, TryFromU64, TryGetableMany};
|
||||
use sea_query::IntoValueTuple;
|
||||
use std::fmt::Debug;
|
||||
|
||||
//LINT: composite primary key cannot auto increment
|
||||
pub trait PrimaryKeyTrait: IdenStatic + Iterable {
|
||||
type ValueType: Sized
|
||||
+ Send
|
||||
+ Default
|
||||
+ Debug
|
||||
+ PartialEq
|
||||
+ IntoValueTuple
|
||||
+ TryGetableMany
|
||||
+ TryFromU64;
|
||||
type ValueType: Sized + Send + Debug + PartialEq + IntoValueTuple + TryGetableMany + TryFromU64;
|
||||
|
||||
fn auto_increment() -> bool;
|
||||
}
|
||||
@ -26,3 +19,12 @@ pub trait PrimaryKeyToColumn {
|
||||
where
|
||||
Self: Sized;
|
||||
}
|
||||
|
||||
pub trait PrimaryKeyValue<E>
|
||||
where
|
||||
E: EntityTrait,
|
||||
{
|
||||
fn get_primary_key_value<A>(active_model: A) -> <E::PrimaryKey as PrimaryKeyTrait>::ValueType
|
||||
where
|
||||
A: ActiveModelTrait<Entity = E>;
|
||||
}
|
||||
|
@ -5,11 +5,12 @@ use crate::{
|
||||
use sea_query::InsertStatement;
|
||||
use std::{future::Future, marker::PhantomData};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Debug)]
|
||||
pub struct Inserter<A>
|
||||
where
|
||||
A: ActiveModelTrait,
|
||||
{
|
||||
primary_key: Option<<<<A as ActiveModelTrait>::Entity as EntityTrait>::PrimaryKey as PrimaryKeyTrait>::ValueType>,
|
||||
query: InsertStatement,
|
||||
model: PhantomData<A>,
|
||||
}
|
||||
@ -48,7 +49,7 @@ where
|
||||
);
|
||||
}
|
||||
}
|
||||
Inserter::<A>::new(query).exec(db)
|
||||
Inserter::<A>::new(self.primary_key, query).exec(db)
|
||||
// TODO: return primary key if extracted before, otherwise use InsertResult
|
||||
}
|
||||
}
|
||||
@ -57,8 +58,12 @@ impl<A> Inserter<A>
|
||||
where
|
||||
A: ActiveModelTrait,
|
||||
{
|
||||
pub fn new(query: InsertStatement) -> Self {
|
||||
pub fn new(
|
||||
primary_key: Option<<<<A as ActiveModelTrait>::Entity as EntityTrait>::PrimaryKey as PrimaryKeyTrait>::ValueType>,
|
||||
query: InsertStatement,
|
||||
) -> Self {
|
||||
Self {
|
||||
primary_key,
|
||||
query,
|
||||
model: PhantomData,
|
||||
}
|
||||
@ -72,12 +77,13 @@ where
|
||||
A: 'a,
|
||||
{
|
||||
let builder = db.get_database_backend();
|
||||
exec_insert(builder.build(&self.query), db)
|
||||
exec_insert(self.primary_key, builder.build(&self.query), db)
|
||||
}
|
||||
}
|
||||
|
||||
// Only Statement impl Send
|
||||
async fn exec_insert<A>(
|
||||
primary_key: Option<<<<A as ActiveModelTrait>::Entity as EntityTrait>::PrimaryKey as PrimaryKeyTrait>::ValueType>,
|
||||
statement: Statement,
|
||||
db: &DatabaseConnection,
|
||||
) -> Result<InsertResult<A>, DbErr>
|
||||
@ -86,7 +92,7 @@ where
|
||||
{
|
||||
type PrimaryKey<A> = <<A as ActiveModelTrait>::Entity as EntityTrait>::PrimaryKey;
|
||||
type ValueTypeOf<A> = <PrimaryKey<A> as PrimaryKeyTrait>::ValueType;
|
||||
let last_insert_id = match db {
|
||||
let last_insert_id_opt = match db {
|
||||
#[cfg(feature = "sqlx-postgres")]
|
||||
DatabaseConnection::SqlxPostgresPoolConnection(conn) => {
|
||||
use crate::{sea_query::Iden, Iterable};
|
||||
@ -94,14 +100,19 @@ where
|
||||
.map(|col| col.to_string())
|
||||
.collect::<Vec<_>>();
|
||||
let res = conn.query_one(statement).await?.unwrap();
|
||||
res.try_get_many("", cols.as_ref()).unwrap_or_default()
|
||||
Some(res.try_get_many("", cols.as_ref()).unwrap_or_default())
|
||||
}
|
||||
_ => {
|
||||
let last_insert_id = db.execute(statement).await?.last_insert_id();
|
||||
ValueTypeOf::<A>::try_from_u64(last_insert_id)
|
||||
.ok()
|
||||
.unwrap_or_default()
|
||||
ValueTypeOf::<A>::try_from_u64(last_insert_id).ok()
|
||||
}
|
||||
};
|
||||
let last_insert_id = match last_insert_id_opt {
|
||||
Some(last_insert_id) => last_insert_id,
|
||||
None => match primary_key {
|
||||
Some(primary_key) => primary_key,
|
||||
None => return Err(DbErr::Exec("Fail to unpack last_insert_id".to_owned())),
|
||||
},
|
||||
};
|
||||
Ok(InsertResult { last_insert_id })
|
||||
}
|
||||
|
@ -1,14 +1,18 @@
|
||||
use crate::{ActiveModelTrait, EntityName, EntityTrait, IntoActiveModel, Iterable, QueryTrait};
|
||||
use crate::{
|
||||
ActiveModelTrait, EntityName, EntityTrait, IntoActiveModel, Iterable, PrimaryKeyTrait,
|
||||
PrimaryKeyValue, QueryTrait,
|
||||
};
|
||||
use core::marker::PhantomData;
|
||||
use sea_query::InsertStatement;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Debug)]
|
||||
pub struct Insert<A>
|
||||
where
|
||||
A: ActiveModelTrait,
|
||||
{
|
||||
pub(crate) query: InsertStatement,
|
||||
pub(crate) columns: Vec<bool>,
|
||||
pub(crate) primary_key: Option<<<<A as ActiveModelTrait>::Entity as EntityTrait>::PrimaryKey as PrimaryKeyTrait>::ValueType>,
|
||||
pub(crate) model: PhantomData<A>,
|
||||
}
|
||||
|
||||
@ -31,6 +35,7 @@ where
|
||||
.into_table(A::Entity::default().table_ref())
|
||||
.to_owned(),
|
||||
columns: Vec::new(),
|
||||
primary_key: None,
|
||||
model: PhantomData,
|
||||
}
|
||||
}
|
||||
@ -68,6 +73,8 @@ where
|
||||
pub fn one<M>(m: M) -> Insert<A>
|
||||
where
|
||||
M: IntoActiveModel<A>,
|
||||
<<A as ActiveModelTrait>::Entity as EntityTrait>::PrimaryKey:
|
||||
PrimaryKeyValue<<A as ActiveModelTrait>::Entity>,
|
||||
{
|
||||
Self::new().add(m)
|
||||
}
|
||||
@ -97,6 +104,8 @@ where
|
||||
where
|
||||
M: IntoActiveModel<A>,
|
||||
I: IntoIterator<Item = M>,
|
||||
<<A as ActiveModelTrait>::Entity as EntityTrait>::PrimaryKey:
|
||||
PrimaryKeyValue<<A as ActiveModelTrait>::Entity>,
|
||||
{
|
||||
Self::new().add_many(models)
|
||||
}
|
||||
@ -105,8 +114,16 @@ where
|
||||
pub fn add<M>(mut self, m: M) -> Self
|
||||
where
|
||||
M: IntoActiveModel<A>,
|
||||
<<A as ActiveModelTrait>::Entity as EntityTrait>::PrimaryKey:
|
||||
PrimaryKeyValue<<A as ActiveModelTrait>::Entity>,
|
||||
{
|
||||
let mut am: A = m.into_active_model();
|
||||
self.primary_key =
|
||||
if !<<A::Entity as EntityTrait>::PrimaryKey as PrimaryKeyTrait>::auto_increment() {
|
||||
Some(<<A::Entity as EntityTrait>::PrimaryKey as PrimaryKeyValue<A::Entity>>::get_primary_key_value::<A>(am.clone()))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let mut columns = Vec::new();
|
||||
let mut values = Vec::new();
|
||||
let columns_empty = self.columns.is_empty();
|
||||
@ -132,6 +149,8 @@ where
|
||||
where
|
||||
M: IntoActiveModel<A>,
|
||||
I: IntoIterator<Item = M>,
|
||||
<<A as ActiveModelTrait>::Entity as EntityTrait>::PrimaryKey:
|
||||
PrimaryKeyValue<<A as ActiveModelTrait>::Entity>,
|
||||
{
|
||||
for model in models.into_iter() {
|
||||
self = self.add(model);
|
||||
|
Loading…
x
Reference in New Issue
Block a user