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 }
|
log = { version = "^0.4", optional = true }
|
||||||
rust_decimal = { version = "^1", optional = true }
|
rust_decimal = { version = "^1", optional = true }
|
||||||
sea-orm-macros = { version = "^0.2.5", path = "sea-orm-macros", 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"] }
|
sea-strum = { version = "^0.21", features = ["derive", "sea-orm"] }
|
||||||
serde = { version = "^1.0", features = ["derive"] }
|
serde = { version = "^1.0", features = ["derive"] }
|
||||||
serde_json = { version = "^1", optional = true }
|
serde_json = { version = "^1", optional = true }
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use heck::SnakeCase;
|
use heck::SnakeCase;
|
||||||
use proc_macro2::{Ident, TokenStream};
|
use proc_macro2::{Ident, TokenStream};
|
||||||
use quote::{quote, quote_spanned, ToTokens};
|
use quote::{quote, quote_spanned};
|
||||||
use syn::{punctuated::Punctuated, token::Comma, Data, DataEnum, Fields, Variant};
|
use syn::{Data, DataEnum, Fields, Variant};
|
||||||
|
|
||||||
pub fn expand_derive_primary_key(ident: Ident, data: Data) -> syn::Result<TokenStream> {
|
pub fn expand_derive_primary_key(ident: Ident, data: Data) -> syn::Result<TokenStream> {
|
||||||
let variants = match data {
|
let variants = match data {
|
||||||
@ -30,21 +30,6 @@ pub fn expand_derive_primary_key(ident: Ident, data: Data) -> syn::Result<TokenS
|
|||||||
})
|
})
|
||||||
.collect();
|
.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!(
|
Ok(quote!(
|
||||||
impl sea_orm::Iden for #ident {
|
impl sea_orm::Iden for #ident {
|
||||||
fn unquoted(&self, s: &mut dyn std::fmt::Write) {
|
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,
|
error::*, DatabaseConnection, DeleteResult, EntityTrait, Iterable, PrimaryKeyToColumn, Value,
|
||||||
};
|
};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
use sea_query::ValueTuple;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
@ -9,7 +10,8 @@ pub struct ActiveValue<V>
|
|||||||
where
|
where
|
||||||
V: Into<Value>,
|
V: Into<Value>,
|
||||||
{
|
{
|
||||||
value: Option<V>,
|
// Don't want to call ActiveValue::unwrap() and cause panic
|
||||||
|
pub(self) value: Option<V>,
|
||||||
state: ActiveValueState,
|
state: ActiveValueState,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,6 +68,41 @@ pub trait ActiveModelTrait: Clone + Debug {
|
|||||||
|
|
||||||
fn default() -> Self;
|
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>
|
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>,
|
||||||
|
@ -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, PrimaryKeyValue, QueryFilter, Related,
|
ModelTrait, PrimaryKeyToColumn, PrimaryKeyTrait, QueryFilter, Related, RelationBuilder,
|
||||||
RelationBuilder, RelationTrait, RelationType, Select, Update, UpdateMany, UpdateOne,
|
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;
|
||||||
@ -49,9 +49,7 @@ pub trait EntityTrait: EntityName {
|
|||||||
|
|
||||||
type Relation: RelationTrait;
|
type Relation: RelationTrait;
|
||||||
|
|
||||||
type PrimaryKey: PrimaryKeyTrait
|
type PrimaryKey: PrimaryKeyTrait + PrimaryKeyToColumn<Column = Self::Column>;
|
||||||
+ PrimaryKeyToColumn<Column = Self::Column>
|
|
||||||
+ PrimaryKeyValue<Self>;
|
|
||||||
|
|
||||||
fn belongs_to<R>(related: R) -> RelationBuilder<Self, R>
|
fn belongs_to<R>(related: R) -> RelationBuilder<Self, R>
|
||||||
where
|
where
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
pub use crate::{
|
pub use crate::{
|
||||||
error::*, ActiveModelBehavior, ActiveModelTrait, ColumnDef, ColumnTrait, ColumnType,
|
error::*, ActiveModelBehavior, ActiveModelTrait, ColumnDef, ColumnTrait, ColumnType,
|
||||||
EntityName, EntityTrait, EnumIter, ForeignKeyAction, Iden, IdenStatic, Linked, ModelTrait,
|
EntityName, EntityTrait, EnumIter, ForeignKeyAction, Iden, IdenStatic, Linked, ModelTrait,
|
||||||
PrimaryKeyToColumn, PrimaryKeyTrait, PrimaryKeyValue, QueryFilter, QueryResult, Related,
|
PrimaryKeyToColumn, PrimaryKeyTrait, QueryFilter, QueryResult, Related, RelationDef,
|
||||||
RelationDef, RelationTrait, Select, Value,
|
RelationTrait, Select, Value,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "macros")]
|
#[cfg(feature = "macros")]
|
||||||
|
@ -1,11 +1,18 @@
|
|||||||
use super::{ColumnTrait, IdenStatic, Iterable};
|
use super::{ColumnTrait, IdenStatic, Iterable};
|
||||||
use crate::{ActiveModelTrait, EntityTrait, TryFromU64, TryGetableMany};
|
use crate::{TryFromU64, TryGetableMany};
|
||||||
use sea_query::IntoValueTuple;
|
use sea_query::{FromValueTuple, 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 + Send + Debug + PartialEq + IntoValueTuple + TryGetableMany + TryFromU64;
|
type ValueType: Sized
|
||||||
|
+ Send
|
||||||
|
+ Debug
|
||||||
|
+ PartialEq
|
||||||
|
+ IntoValueTuple
|
||||||
|
+ FromValueTuple
|
||||||
|
+ TryGetableMany
|
||||||
|
+ TryFromU64;
|
||||||
|
|
||||||
fn auto_increment() -> bool;
|
fn auto_increment() -> bool;
|
||||||
}
|
}
|
||||||
@ -19,12 +26,3 @@ 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>;
|
|
||||||
}
|
|
||||||
|
@ -2,7 +2,7 @@ use crate::{
|
|||||||
error::*, ActiveModelTrait, DatabaseConnection, DbBackend, EntityTrait, Insert,
|
error::*, ActiveModelTrait, DatabaseConnection, DbBackend, EntityTrait, Insert,
|
||||||
PrimaryKeyTrait, Statement, TryFromU64,
|
PrimaryKeyTrait, Statement, TryFromU64,
|
||||||
};
|
};
|
||||||
use sea_query::InsertStatement;
|
use sea_query::{FromValueTuple, InsertStatement, ValueTuple};
|
||||||
use std::{future::Future, marker::PhantomData};
|
use std::{future::Future, marker::PhantomData};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -10,7 +10,7 @@ pub struct Inserter<A>
|
|||||||
where
|
where
|
||||||
A: ActiveModelTrait,
|
A: ActiveModelTrait,
|
||||||
{
|
{
|
||||||
primary_key: Option<<<<A as ActiveModelTrait>::Entity as EntityTrait>::PrimaryKey as PrimaryKeyTrait>::ValueType>,
|
primary_key: Option<ValueTuple>,
|
||||||
query: InsertStatement,
|
query: InsertStatement,
|
||||||
model: PhantomData<A>,
|
model: PhantomData<A>,
|
||||||
}
|
}
|
||||||
@ -35,7 +35,6 @@ where
|
|||||||
where
|
where
|
||||||
A: 'a,
|
A: 'a,
|
||||||
{
|
{
|
||||||
// TODO: extract primary key's value from query
|
|
||||||
// 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;
|
||||||
if db.get_database_backend() == DbBackend::Postgres {
|
if db.get_database_backend() == DbBackend::Postgres {
|
||||||
@ -49,7 +48,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Inserter::<A>::new(self.primary_key, query).exec(db)
|
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
|
where
|
||||||
A: ActiveModelTrait,
|
A: ActiveModelTrait,
|
||||||
{
|
{
|
||||||
pub fn new(
|
pub fn new(primary_key: Option<ValueTuple>, query: InsertStatement) -> Self {
|
||||||
primary_key: Option<<<<A as ActiveModelTrait>::Entity as EntityTrait>::PrimaryKey as PrimaryKeyTrait>::ValueType>,
|
|
||||||
query: InsertStatement,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
Self {
|
||||||
primary_key,
|
primary_key,
|
||||||
query,
|
query,
|
||||||
@ -82,7 +77,7 @@ where
|
|||||||
|
|
||||||
// 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>,
|
primary_key: Option<ValueTuple>,
|
||||||
statement: Statement,
|
statement: Statement,
|
||||||
db: &DatabaseConnection,
|
db: &DatabaseConnection,
|
||||||
) -> Result<InsertResult<A>, DbErr>
|
) -> Result<InsertResult<A>, DbErr>
|
||||||
@ -108,7 +103,7 @@ where
|
|||||||
let last_insert_id = match last_insert_id_opt {
|
let last_insert_id = match last_insert_id_opt {
|
||||||
Some(last_insert_id) => last_insert_id,
|
Some(last_insert_id) => last_insert_id,
|
||||||
None => match primary_key {
|
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())),
|
None => return Err(DbErr::Exec("Fail to unpack last_insert_id".to_owned())),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
ActiveModelTrait, EntityName, EntityTrait, IntoActiveModel, Iterable, PrimaryKeyTrait,
|
ActiveModelTrait, EntityName, EntityTrait, IntoActiveModel, Iterable, PrimaryKeyTrait,
|
||||||
PrimaryKeyValue, QueryTrait,
|
QueryTrait,
|
||||||
};
|
};
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use sea_query::InsertStatement;
|
use sea_query::{InsertStatement, ValueTuple};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Insert<A>
|
pub struct Insert<A>
|
||||||
@ -12,7 +12,7 @@ where
|
|||||||
{
|
{
|
||||||
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) primary_key: Option<ValueTuple>,
|
||||||
pub(crate) model: PhantomData<A>,
|
pub(crate) model: PhantomData<A>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,7 +114,7 @@ where
|
|||||||
let mut am: A = m.into_active_model();
|
let mut am: A = m.into_active_model();
|
||||||
self.primary_key =
|
self.primary_key =
|
||||||
if !<<A::Entity as EntityTrait>::PrimaryKey as PrimaryKeyTrait>::auto_increment() {
|
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 {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user