Remove PrimaryKeyValue
trait
This commit is contained in:
parent
ade06b4240
commit
2f90207d64
@ -30,7 +30,7 @@ futures-util = { version = "^0.3" }
|
||||
log = { version = "^0.4", optional = true }
|
||||
rust_decimal = { version = "^1", optional = true }
|
||||
sea-orm-macros = { version = "^0.2.5", path = "sea-orm-macros", optional = true }
|
||||
sea-query = { version = "^0.17.0", features = ["thread-safe"] }
|
||||
sea-query = { version = "^0.17.0", git = "https://github.com/SeaQL/sea-query.git", branch = "from-value-tuple", features = ["thread-safe"] }
|
||||
sea-strum = { version = "^0.21", features = ["derive", "sea-orm"] }
|
||||
serde = { version = "^1.0", features = ["derive"] }
|
||||
serde_json = { version = "^1", optional = true }
|
||||
|
@ -1,7 +1,7 @@
|
||||
use heck::SnakeCase;
|
||||
use proc_macro2::{Ident, TokenStream};
|
||||
use quote::{quote, quote_spanned, ToTokens};
|
||||
use syn::{punctuated::Punctuated, token::Comma, Data, DataEnum, Fields, Variant};
|
||||
use quote::{quote, quote_spanned};
|
||||
use syn::{Data, DataEnum, Fields, Variant};
|
||||
|
||||
pub fn expand_derive_primary_key(ident: Ident, data: Data) -> syn::Result<TokenStream> {
|
||||
let variants = match data {
|
||||
@ -30,21 +30,6 @@ pub fn expand_derive_primary_key(ident: Ident, data: Data) -> syn::Result<TokenS
|
||||
})
|
||||
.collect();
|
||||
|
||||
let primary_key_value: Punctuated<_, Comma> =
|
||||
variants.iter().fold(Punctuated::new(), |mut acc, v| {
|
||||
let variant = &v.ident;
|
||||
acc.push(
|
||||
quote! { active_model.take(#ident::#variant.into_column()).unwrap().unwrap() },
|
||||
);
|
||||
acc
|
||||
});
|
||||
let mut primary_key_value = primary_key_value.to_token_stream();
|
||||
if variants.len() > 1 {
|
||||
primary_key_value = quote! {
|
||||
(#primary_key_value)
|
||||
};
|
||||
}
|
||||
|
||||
Ok(quote!(
|
||||
impl sea_orm::Iden for #ident {
|
||||
fn unquoted(&self, s: &mut dyn std::fmt::Write) {
|
||||
@ -76,16 +61,5 @@ pub fn expand_derive_primary_key(ident: Ident, data: Data) -> syn::Result<TokenS
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PrimaryKeyValue<Entity> for #ident {
|
||||
fn get_primary_key_value<A>(
|
||||
mut active_model: A,
|
||||
) -> <<Entity as EntityTrait>::PrimaryKey as PrimaryKeyTrait>::ValueType
|
||||
where
|
||||
A: ActiveModelTrait<Entity = Entity>,
|
||||
{
|
||||
#primary_key_value
|
||||
}
|
||||
}
|
||||
))
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ use crate::{
|
||||
error::*, DatabaseConnection, DeleteResult, EntityTrait, Iterable, PrimaryKeyToColumn, Value,
|
||||
};
|
||||
use async_trait::async_trait;
|
||||
use sea_query::ValueTuple;
|
||||
use std::fmt::Debug;
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
@ -9,7 +10,8 @@ pub struct ActiveValue<V>
|
||||
where
|
||||
V: Into<Value>,
|
||||
{
|
||||
value: Option<V>,
|
||||
// Don't want to call ActiveValue::unwrap() and cause panic
|
||||
pub(self) value: Option<V>,
|
||||
state: ActiveValueState,
|
||||
}
|
||||
|
||||
@ -66,6 +68,41 @@ pub trait ActiveModelTrait: Clone + Debug {
|
||||
|
||||
fn default() -> Self;
|
||||
|
||||
fn get_primary_key_value(&self) -> Option<ValueTuple> {
|
||||
let mut cols = <Self::Entity as EntityTrait>::PrimaryKey::iter();
|
||||
macro_rules! next {
|
||||
() => {
|
||||
if let Some(col) = cols.next() {
|
||||
if let Some(val) = self.get(col.into_column()).value {
|
||||
val
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
};
|
||||
}
|
||||
match <Self::Entity as EntityTrait>::PrimaryKey::iter().count() {
|
||||
1 => {
|
||||
let s1 = next!();
|
||||
Some(ValueTuple::One(s1))
|
||||
}
|
||||
2 => {
|
||||
let s1 = next!();
|
||||
let s2 = next!();
|
||||
Some(ValueTuple::Two(s1, s2))
|
||||
}
|
||||
3 => {
|
||||
let s1 = next!();
|
||||
let s2 = next!();
|
||||
let s3 = next!();
|
||||
Some(ValueTuple::Three(s1, s2, s3))
|
||||
}
|
||||
_ => panic!("The arity cannot be larger than 3"),
|
||||
}
|
||||
}
|
||||
|
||||
async fn insert(self, db: &DatabaseConnection) -> Result<Self, DbErr>
|
||||
where
|
||||
<Self::Entity as EntityTrait>::Model: IntoActiveModel<Self>,
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
ActiveModelTrait, ColumnTrait, Delete, DeleteMany, DeleteOne, FromQueryResult, Insert,
|
||||
ModelTrait, PrimaryKeyToColumn, PrimaryKeyTrait, PrimaryKeyValue, QueryFilter, Related,
|
||||
RelationBuilder, RelationTrait, RelationType, Select, Update, UpdateMany, UpdateOne,
|
||||
ModelTrait, PrimaryKeyToColumn, PrimaryKeyTrait, 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;
|
||||
@ -49,9 +49,7 @@ pub trait EntityTrait: EntityName {
|
||||
|
||||
type Relation: RelationTrait;
|
||||
|
||||
type PrimaryKey: PrimaryKeyTrait
|
||||
+ PrimaryKeyToColumn<Column = Self::Column>
|
||||
+ PrimaryKeyValue<Self>;
|
||||
type PrimaryKey: PrimaryKeyTrait + PrimaryKeyToColumn<Column = Self::Column>;
|
||||
|
||||
fn belongs_to<R>(related: R) -> RelationBuilder<Self, R>
|
||||
where
|
||||
|
@ -1,8 +1,8 @@
|
||||
pub use crate::{
|
||||
error::*, ActiveModelBehavior, ActiveModelTrait, ColumnDef, ColumnTrait, ColumnType,
|
||||
EntityName, EntityTrait, EnumIter, ForeignKeyAction, Iden, IdenStatic, Linked, ModelTrait,
|
||||
PrimaryKeyToColumn, PrimaryKeyTrait, PrimaryKeyValue, QueryFilter, QueryResult, Related,
|
||||
RelationDef, RelationTrait, Select, Value,
|
||||
PrimaryKeyToColumn, PrimaryKeyTrait, QueryFilter, QueryResult, Related, RelationDef,
|
||||
RelationTrait, Select, Value,
|
||||
};
|
||||
|
||||
#[cfg(feature = "macros")]
|
||||
|
@ -1,11 +1,18 @@
|
||||
use super::{ColumnTrait, IdenStatic, Iterable};
|
||||
use crate::{ActiveModelTrait, EntityTrait, TryFromU64, TryGetableMany};
|
||||
use sea_query::IntoValueTuple;
|
||||
use crate::{TryFromU64, TryGetableMany};
|
||||
use sea_query::{FromValueTuple, IntoValueTuple};
|
||||
use std::fmt::Debug;
|
||||
|
||||
//LINT: composite primary key cannot auto increment
|
||||
pub trait PrimaryKeyTrait: IdenStatic + Iterable {
|
||||
type ValueType: Sized + Send + Debug + PartialEq + IntoValueTuple + TryGetableMany + TryFromU64;
|
||||
type ValueType: Sized
|
||||
+ Send
|
||||
+ Debug
|
||||
+ PartialEq
|
||||
+ IntoValueTuple
|
||||
+ FromValueTuple
|
||||
+ TryGetableMany
|
||||
+ TryFromU64;
|
||||
|
||||
fn auto_increment() -> bool;
|
||||
}
|
||||
@ -19,12 +26,3 @@ 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>;
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ use crate::{
|
||||
error::*, ActiveModelTrait, DatabaseConnection, DbBackend, EntityTrait, Insert,
|
||||
PrimaryKeyTrait, Statement, TryFromU64,
|
||||
};
|
||||
use sea_query::InsertStatement;
|
||||
use sea_query::{FromValueTuple, InsertStatement, ValueTuple};
|
||||
use std::{future::Future, marker::PhantomData};
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -10,7 +10,7 @@ pub struct Inserter<A>
|
||||
where
|
||||
A: ActiveModelTrait,
|
||||
{
|
||||
primary_key: Option<<<<A as ActiveModelTrait>::Entity as EntityTrait>::PrimaryKey as PrimaryKeyTrait>::ValueType>,
|
||||
primary_key: Option<ValueTuple>,
|
||||
query: InsertStatement,
|
||||
model: PhantomData<A>,
|
||||
}
|
||||
@ -35,7 +35,6 @@ where
|
||||
where
|
||||
A: 'a,
|
||||
{
|
||||
// TODO: extract primary key's value from query
|
||||
// so that self is dropped before entering await
|
||||
let mut query = self.query;
|
||||
if db.get_database_backend() == DbBackend::Postgres {
|
||||
@ -49,7 +48,6 @@ where
|
||||
}
|
||||
}
|
||||
Inserter::<A>::new(self.primary_key, query).exec(db)
|
||||
// TODO: return primary key if extracted before, otherwise use InsertResult
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,10 +55,7 @@ impl<A> Inserter<A>
|
||||
where
|
||||
A: ActiveModelTrait,
|
||||
{
|
||||
pub fn new(
|
||||
primary_key: Option<<<<A as ActiveModelTrait>::Entity as EntityTrait>::PrimaryKey as PrimaryKeyTrait>::ValueType>,
|
||||
query: InsertStatement,
|
||||
) -> Self {
|
||||
pub fn new(primary_key: Option<ValueTuple>, query: InsertStatement) -> Self {
|
||||
Self {
|
||||
primary_key,
|
||||
query,
|
||||
@ -82,7 +77,7 @@ where
|
||||
|
||||
// Only Statement impl Send
|
||||
async fn exec_insert<A>(
|
||||
primary_key: Option<<<<A as ActiveModelTrait>::Entity as EntityTrait>::PrimaryKey as PrimaryKeyTrait>::ValueType>,
|
||||
primary_key: Option<ValueTuple>,
|
||||
statement: Statement,
|
||||
db: &DatabaseConnection,
|
||||
) -> Result<InsertResult<A>, DbErr>
|
||||
@ -108,7 +103,7 @@ where
|
||||
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,
|
||||
Some(value_tuple) => FromValueTuple::from_value_tuple(value_tuple),
|
||||
None => return Err(DbErr::Exec("Fail to unpack last_insert_id".to_owned())),
|
||||
},
|
||||
};
|
||||
|
@ -1,9 +1,9 @@
|
||||
use crate::{
|
||||
ActiveModelTrait, EntityName, EntityTrait, IntoActiveModel, Iterable, PrimaryKeyTrait,
|
||||
PrimaryKeyValue, QueryTrait,
|
||||
QueryTrait,
|
||||
};
|
||||
use core::marker::PhantomData;
|
||||
use sea_query::InsertStatement;
|
||||
use sea_query::{InsertStatement, ValueTuple};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Insert<A>
|
||||
@ -12,7 +12,7 @@ where
|
||||
{
|
||||
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) primary_key: Option<ValueTuple>,
|
||||
pub(crate) model: PhantomData<A>,
|
||||
}
|
||||
|
||||
@ -114,7 +114,7 @@ where
|
||||
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()))
|
||||
am.get_primary_key_value()
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user