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