Use ValueTuple to replace Vec<Value>

This commit is contained in:
Chris Tsang 2022-11-23 23:12:18 +08:00
parent 6c7a162f05
commit 0abe9c9657

View File

@ -1,6 +1,6 @@
use crate::{ use crate::{
ColumnTrait, Condition, ConnectionTrait, DbErr, EntityTrait, Identity, ModelTrait, QueryFilter, ColumnTrait, Condition, ConnectionTrait, DbErr, EntityTrait, Identity, ModelTrait, QueryFilter,
Related, RelationType, Select, Value, Related, RelationType, Select,
}; };
use async_trait::async_trait; use async_trait::async_trait;
use sea_query::{Expr, IntoColumnRef, SimpleExpr, ValueTuple}; use sea_query::{Expr, IntoColumnRef, SimpleExpr, ValueTuple};
@ -57,14 +57,14 @@ where
let rel_def = <<<Self as LoaderTrait>::Model as ModelTrait>::Entity as Related<R>>::to(); let rel_def = <<<Self as LoaderTrait>::Model as ModelTrait>::Entity as Related<R>>::to();
// we verify that is has_one relation // we verify that is has_one relation
match (&rel_def).rel_type { match (rel_def).rel_type {
RelationType::HasOne => (), RelationType::HasOne => (),
RelationType::HasMany => { RelationType::HasMany => {
return Err(DbErr::Type("Relation is HasMany instead of HasOne".into())) return Err(DbErr::Type("Relation is HasMany instead of HasOne".into()))
} }
} }
let keys: Vec<Vec<Value>> = self let keys: Vec<ValueTuple> = self
.iter() .iter()
.map(|model: &M| extract_key(&rel_def.from_col, model)) .map(|model: &M| extract_key(&rel_def.from_col, model))
.collect(); .collect();
@ -91,11 +91,7 @@ where
let result: Vec<Option<<R as EntityTrait>::Model>> = keys let result: Vec<Option<<R as EntityTrait>::Model>> = keys
.iter() .iter()
.map(|key| { .map(|key| hashmap.remove(&format!("{:?}", key)))
let model = hashmap.remove(&format!("{:?}", key));
model
})
.collect(); .collect();
Ok(result) Ok(result)
@ -113,14 +109,14 @@ where
let rel_def = <<<Self as LoaderTrait>::Model as ModelTrait>::Entity as Related<R>>::to(); let rel_def = <<<Self as LoaderTrait>::Model as ModelTrait>::Entity as Related<R>>::to();
// we verify that is has_many relation // we verify that is has_many relation
match (&rel_def).rel_type { match (rel_def).rel_type {
RelationType::HasMany => (), RelationType::HasMany => (),
RelationType::HasOne => { RelationType::HasOne => {
return Err(DbErr::Type("Relation is HasOne instead of HasMany".into())) return Err(DbErr::Type("Relation is HasOne instead of HasMany".into()))
} }
} }
let keys: Vec<Vec<Value>> = self let keys: Vec<ValueTuple> = self
.iter() .iter()
.map(|model: &M| extract_key(&rel_def.from_col, model)) .map(|model: &M| extract_key(&rel_def.from_col, model))
.collect(); .collect();
@ -133,7 +129,7 @@ where
let mut hashmap: BTreeMap<String, Vec<<R as EntityTrait>::Model>> = let mut hashmap: BTreeMap<String, Vec<<R as EntityTrait>::Model>> =
keys.iter() keys.iter()
.fold(BTreeMap::new(), |mut acc, key: &Vec<Value>| { .fold(BTreeMap::new(), |mut acc, key: &ValueTuple| {
acc.insert(format!("{:?}", key), Vec::new()); acc.insert(format!("{:?}", key), Vec::new());
acc acc
@ -152,10 +148,9 @@ where
let result: Vec<Vec<R::Model>> = keys let result: Vec<Vec<R::Model>> = keys
.iter() .iter()
.map(|key: &Vec<Value>| { .map(|key: &ValueTuple| {
hashmap hashmap
.remove(&format!("{:?}", key)) .remove(&format!("{:?}", key))
.to_owned()
.expect("Failed to convert key to owned") .expect("Failed to convert key to owned")
}) })
.collect(); .collect();
@ -164,7 +159,7 @@ where
} }
} }
fn extract_key<Model>(target_col: &Identity, model: &Model) -> Vec<Value> fn extract_key<Model>(target_col: &Identity, model: &Model) -> ValueTuple
where where
Model: ModelTrait, Model: ModelTrait,
<<<Model as ModelTrait>::Entity as EntityTrait>::Column as FromStr>::Err: Debug, <<<Model as ModelTrait>::Entity as EntityTrait>::Column as FromStr>::Err: Debug,
@ -176,7 +171,7 @@ where
&a.to_string(), &a.to_string(),
) )
.expect("Failed at mapping string to column A:1"); .expect("Failed at mapping string to column A:1");
vec![model.get(column_a)] ValueTuple::One(model.get(column_a))
} }
Identity::Binary(a, b) => { Identity::Binary(a, b) => {
let column_a = let column_a =
@ -189,7 +184,7 @@ where
&b.to_string(), &b.to_string(),
) )
.expect("Failed at mapping string to column B:2"); .expect("Failed at mapping string to column B:2");
vec![model.get(column_a), model.get(column_b)] ValueTuple::Two(model.get(column_a), model.get(column_b))
} }
Identity::Ternary(a, b, c) => { Identity::Ternary(a, b, c) => {
let column_a = let column_a =
@ -207,16 +202,16 @@ where
&c.to_string(), &c.to_string(),
) )
.expect("Failed at mapping string to column C:3"); .expect("Failed at mapping string to column C:3");
vec![ ValueTuple::Three(
model.get(column_a), model.get(column_a),
model.get(column_b), model.get(column_b),
model.get(column_c), model.get(column_c),
] )
} }
} }
} }
fn prepare_condition<M>(col: &Identity, keys: &Vec<Vec<Value>>) -> Condition fn prepare_condition<M>(col: &Identity, keys: &[ValueTuple]) -> Condition
where where
M: ModelTrait, M: ModelTrait,
<<<M as ModelTrait>::Entity as EntityTrait>::Column as FromStr>::Err: Debug, <<<M as ModelTrait>::Entity as EntityTrait>::Column as FromStr>::Err: Debug,
@ -228,9 +223,7 @@ where
.expect("Failed at mapping string to column *A:1"); .expect("Failed at mapping string to column *A:1");
Condition::all().add(ColumnTrait::is_in( Condition::all().add(ColumnTrait::is_in(
&column_a, &column_a,
keys.iter() keys.iter().cloned().flatten(),
.map(|key| key[0].clone())
.collect::<Vec<Value>>(),
)) ))
} }
Identity::Binary(column_a, column_b) => { Identity::Binary(column_a, column_b) => {
@ -245,11 +238,7 @@ where
SimpleExpr::Column(column_a.into_column_ref()), SimpleExpr::Column(column_a.into_column_ref()),
SimpleExpr::Column(column_b.into_column_ref()), SimpleExpr::Column(column_b.into_column_ref()),
]) ])
.in_tuples( .in_tuples(keys.iter().cloned()),
keys.iter()
.map(|key| ValueTuple::Two(key[0].clone(), key[1].clone()))
.collect::<Vec<ValueTuple>>(),
),
) )
} }
Identity::Ternary(column_a, column_b, column_c) => { Identity::Ternary(column_a, column_b, column_c) => {
@ -268,13 +257,7 @@ where
SimpleExpr::Column(column_b.into_column_ref()), SimpleExpr::Column(column_b.into_column_ref()),
SimpleExpr::Column(column_c.into_column_ref()), SimpleExpr::Column(column_c.into_column_ref()),
]) ])
.in_tuples( .in_tuples(keys.iter().cloned()),
keys.iter()
.map(|key| {
ValueTuple::Three(key[0].clone(), key[1].clone(), key[2].clone())
})
.collect::<Vec<ValueTuple>>(),
),
) )
} }
} }