dry some stuff. also lot of yelling at the compiler
This commit is contained in:
Generated
+1
@@ -2714,6 +2714,7 @@ dependencies = [
|
||||
"itertools",
|
||||
"log",
|
||||
"parking_lot",
|
||||
"rand 0.8.3",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
|
||||
@@ -56,7 +56,7 @@ pub(crate) async fn create(
|
||||
match wg.define_object(ObjectModel {
|
||||
id: Default::default(),
|
||||
name: form.name.clone(),
|
||||
name_property: form.name_property
|
||||
name_property: form.name_property,
|
||||
}) {
|
||||
Ok(_id) => {
|
||||
wg.persist().err_to_500()?;
|
||||
@@ -96,10 +96,13 @@ pub(crate) async fn update_form(
|
||||
context.insert("model", &model);
|
||||
} else {
|
||||
context.insert("model", model);
|
||||
context.insert("old", &ObjectModelForm {
|
||||
context.insert(
|
||||
"old",
|
||||
&ObjectModelForm {
|
||||
name: model.name.to_string(),
|
||||
name_property: model.name_property
|
||||
});
|
||||
name_property: model.name_property,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
let properties = rg.get_property_models_for_parent(*model_id).collect_vec();
|
||||
@@ -162,14 +165,13 @@ pub(crate) async fn delete(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub mod my_string_empty_as_none {
|
||||
use serde::{Deserializer, Serializer, Serialize};
|
||||
use std::str::FromStr;
|
||||
use std::fmt::{Display, Write};
|
||||
use std::marker::PhantomData;
|
||||
use serde::de::{Visitor, Error};
|
||||
use serde::de::{Error, Visitor};
|
||||
use serde::{Deserializer, Serialize, Serializer};
|
||||
use std::fmt;
|
||||
use std::fmt::Display;
|
||||
use std::marker::PhantomData;
|
||||
use std::str::FromStr;
|
||||
use yopa::ID;
|
||||
|
||||
// FIXME largely copied from serde_with
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
use std::borrow::{Borrow, Cow};
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use actix_session::Session;
|
||||
use actix_web::{HttpResponse, Responder, web};
|
||||
use actix_web::{web, HttpResponse, Responder};
|
||||
use heck::TitleCase;
|
||||
use itertools::Itertools;
|
||||
use json_dotpath::DotPaths;
|
||||
use serde::Serialize;
|
||||
|
||||
use yopa::{data, ID, model, Storage};
|
||||
use yopa::data::Object;
|
||||
use yopa::{data, model, Storage, ID};
|
||||
|
||||
use yopa::insert::InsertObj;
|
||||
use yopa::model::{ObjectModel, PropertyModel, RelationModel};
|
||||
use yopa::update::UpdateObj;
|
||||
|
||||
use crate::session_ext::SessionExt;
|
||||
use crate::TERA;
|
||||
use crate::tera_ext::TeraExt;
|
||||
use crate::utils::{redirect, StorageErrorIntoResponseError};
|
||||
use crate::TERA;
|
||||
use yopa::helpers::GroupByModel;
|
||||
|
||||
// we only need references here, Context serializes everything to Value.
|
||||
// cloning would be a waste of cycles
|
||||
@@ -97,13 +98,14 @@ fn prepare_object_create_data(rg: &Storage, model_id: ID) -> actix_web::Result<O
|
||||
.get_property_models_for_parents(prop_object_ids)
|
||||
.collect(),
|
||||
},
|
||||
objects: rg.get_objects_of_types(related_ids).map(|o| {
|
||||
ObjectDisplay {
|
||||
objects: rg
|
||||
.get_objects_of_types(related_ids)
|
||||
.map(|o| ObjectDisplay {
|
||||
id: o.id,
|
||||
model: o.model,
|
||||
name: rg.get_object_name(o),
|
||||
}
|
||||
}).collect(),
|
||||
})
|
||||
.collect(),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -162,13 +164,16 @@ pub(crate) async fn list_inner(
|
||||
.sorted_by_key(|m| &m.name)
|
||||
.map(|model| {
|
||||
let objects = objects_by_model.remove(&model.id).unwrap_or_default();
|
||||
let mut objects = objects.into_iter().map(|o| {
|
||||
let mut objects = objects
|
||||
.into_iter()
|
||||
.map(|o| {
|
||||
ObjectDisplay {
|
||||
id: o.id,
|
||||
model: o.model,
|
||||
name: rg.get_object_name(o), // TODO optimize
|
||||
}
|
||||
}).collect_vec();
|
||||
})
|
||||
.collect_vec();
|
||||
|
||||
objects.sort_by(|a, b| a.name.cmp(&b.name));
|
||||
ModelWithObjects { model, objects }
|
||||
@@ -223,11 +228,14 @@ pub(crate) async fn detail(
|
||||
.get_object_model(object.model)
|
||||
.ok_or_else(|| actix_web::error::ErrorNotFound("No such model"))?;
|
||||
|
||||
context.insert("object", &ObjectDisplay {
|
||||
context.insert(
|
||||
"object",
|
||||
&ObjectDisplay {
|
||||
id: object_id,
|
||||
model: object.model,
|
||||
name: rg.get_object_name(object),
|
||||
});
|
||||
},
|
||||
);
|
||||
context.insert("model", model);
|
||||
context.insert("kind", &rg.get_model_name(object.model));
|
||||
|
||||
@@ -248,8 +256,7 @@ pub(crate) async fn detail(
|
||||
let object_values_by_model = grouped_values
|
||||
.remove(&object_id)
|
||||
.unwrap_or_default()
|
||||
.into_iter()
|
||||
.into_group_map_by(|value| value.model);
|
||||
.group_by_model();
|
||||
|
||||
let mut view_object_properties = vec![];
|
||||
for (prop_model_id, values) in object_values_by_model {
|
||||
@@ -268,7 +275,7 @@ pub(crate) async fn detail(
|
||||
{
|
||||
let grouped_relations = relations
|
||||
.iter()
|
||||
.into_group_map_by(|relation| relation.model);
|
||||
.group_by_model();
|
||||
|
||||
let mut relation_views = vec![];
|
||||
for (model_id, relations) in grouped_relations {
|
||||
@@ -283,8 +290,7 @@ pub(crate) async fn detail(
|
||||
let rel_values_by_model = grouped_values
|
||||
.remove(&rel.id)
|
||||
.unwrap_or_default()
|
||||
.into_iter()
|
||||
.into_group_map_by(|value| value.model);
|
||||
.group_by_model();
|
||||
|
||||
let mut view_rel_properties = vec![];
|
||||
for (prop_model_id, values) in rel_values_by_model {
|
||||
@@ -327,7 +333,7 @@ pub(crate) async fn detail(
|
||||
{
|
||||
let grouped_relations = reci_relations
|
||||
.iter()
|
||||
.into_group_map_by(|relation| relation.model);
|
||||
.group_by_model();
|
||||
|
||||
let mut relation_views = vec![];
|
||||
for (model_id, relations) in grouped_relations {
|
||||
@@ -342,8 +348,7 @@ pub(crate) async fn detail(
|
||||
let rel_values_by_model = grouped_values
|
||||
.remove(&rel.id)
|
||||
.unwrap_or_default()
|
||||
.into_iter()
|
||||
.into_group_map_by(|value| value.model);
|
||||
.group_by_model();
|
||||
|
||||
let mut view_rel_properties = vec![];
|
||||
for (prop_model_id, values) in rel_values_by_model {
|
||||
@@ -428,11 +433,14 @@ pub(crate) async fn update_form(
|
||||
|
||||
// maybe its useful,idk
|
||||
context.insert("model", &model);
|
||||
context.insert("object", &ObjectDisplay {
|
||||
context.insert(
|
||||
"object",
|
||||
&ObjectDisplay {
|
||||
id: object.id,
|
||||
model: object.model,
|
||||
name: rg.get_object_name(object),
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
let create_data = prepare_object_create_data(&rg, model.id)?;
|
||||
|
||||
@@ -448,7 +456,8 @@ pub(crate) async fn update_form(
|
||||
.map(|p| p.id)
|
||||
.collect_vec();
|
||||
|
||||
let mut values_grouped = rg.get_values_for_object(*id).into_group_map_by(|v| v.model);
|
||||
let mut values_grouped = rg.get_values_for_object(*id)
|
||||
.group_by_model();
|
||||
|
||||
prop_ids.into_iter().for_each(|id| {
|
||||
value_map.insert(
|
||||
@@ -472,7 +481,7 @@ pub(crate) async fn update_form(
|
||||
|
||||
let mut relations_grouped_by_model = relations
|
||||
.iter()
|
||||
.into_group_map_by(|relation| relation.model);
|
||||
.group_by_model();
|
||||
|
||||
let mut property_models_grouped_by_parent =
|
||||
rg.get_grouped_prop_models_for_parents(relation_model_ids.clone());
|
||||
@@ -497,8 +506,7 @@ pub(crate) async fn update_form(
|
||||
let mut rel_values = relation_values_grouped_by_instance
|
||||
.remove(&rel.id)
|
||||
.unwrap_or_default()
|
||||
.into_iter()
|
||||
.into_group_map_by(|relation| relation.model);
|
||||
.group_by_model();
|
||||
|
||||
prop_models_for_relation.iter().for_each(|prop_model| {
|
||||
relation_values_map.insert(
|
||||
@@ -525,7 +533,7 @@ pub(crate) async fn update_form(
|
||||
let object = EnrichedObject {
|
||||
id: object.id,
|
||||
model: object.model,
|
||||
name: rg.get_object_name_by_id(object.id),
|
||||
name: rg.get_object_name(object),
|
||||
values: value_map,
|
||||
relations: relation_map,
|
||||
};
|
||||
@@ -558,7 +566,11 @@ pub(crate) async fn update(
|
||||
Ok(_id) => {
|
||||
wg.persist().err_to_500()?;
|
||||
debug!("Object created, redirecting to root");
|
||||
session.flash_success(format!("{} \"{}\" updated.", model_name, wg.get_object_name_by_id(id)));
|
||||
session.flash_success(format!(
|
||||
"{} \"{}\" updated.",
|
||||
model_name,
|
||||
wg.get_object_name_by_id(id)
|
||||
));
|
||||
Ok(HttpResponse::Ok().finish())
|
||||
}
|
||||
Err(e) => {
|
||||
|
||||
@@ -22,6 +22,7 @@ itertools = "0.10.0"
|
||||
#lazy_static = "1.4.0"
|
||||
bincode = "1.3.1"
|
||||
atomic = "0.5.0"
|
||||
rand = "0.8.3"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
|
||||
+1
-3
@@ -49,9 +49,7 @@ impl<T> IsNoneOrElse<T> for Option<T> {
|
||||
fn is_none_or_else(&self, test: impl FnOnce(&T) -> bool) -> bool {
|
||||
match self {
|
||||
None => true,
|
||||
Some(value) => {
|
||||
test(value)
|
||||
}
|
||||
Some(value) => test(value),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
//! Data value structs
|
||||
|
||||
use std::borrow::{Cow, Borrow};
|
||||
use std::borrow::{Borrow, Cow};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
|
||||
@@ -0,0 +1,200 @@
|
||||
//! Helper traits and stuff for working with lists and iterators of objects
|
||||
|
||||
// Re-export itertools for convenience
|
||||
pub use itertools;
|
||||
|
||||
use crate::{data, insert, model, update, ID};
|
||||
|
||||
use itertools::Itertools;
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub trait GetParent {
|
||||
fn get_parent(&self) -> ID;
|
||||
}
|
||||
|
||||
macro_rules! impl_get_parent {
|
||||
($($struct:ty),+) => {
|
||||
$(
|
||||
impl GetParent for $struct {
|
||||
fn get_parent(&self) -> ID { self.object }
|
||||
}
|
||||
impl GetParent for &$struct {
|
||||
fn get_parent(&self) -> ID { self.object }
|
||||
}
|
||||
impl GetParent for &&$struct {
|
||||
fn get_parent(&self) -> ID { self.object }
|
||||
}
|
||||
)+
|
||||
}
|
||||
}
|
||||
|
||||
impl_get_parent!(
|
||||
data::Value, data::Relation,
|
||||
model::RelationModel, model::PropertyModel);
|
||||
|
||||
pub trait GetModelID {
|
||||
fn get_model_id(&self) -> ID;
|
||||
}
|
||||
|
||||
macro_rules! impl_get_model_id {
|
||||
($($struct:ty),+) => {
|
||||
$(
|
||||
impl GetModelID for $struct {
|
||||
fn get_model_id(&self) -> ID { self.model }
|
||||
}
|
||||
impl GetModelID for &$struct {
|
||||
fn get_model_id(&self) -> ID { self.model }
|
||||
}
|
||||
impl GetModelID for &&$struct {
|
||||
fn get_model_id(&self) -> ID { self.model }
|
||||
}
|
||||
)+
|
||||
}
|
||||
}
|
||||
|
||||
impl_get_model_id!(
|
||||
data::Object, data::Value, data::Relation,
|
||||
insert::InsertRel, insert::InsertValue, insert::InsertObj,
|
||||
update::UpsertRelation, update::UpsertValue);
|
||||
|
||||
// This would be nice, but doesn't work
|
||||
|
||||
//
|
||||
// pub struct FilterOfParent<'a, S: 'a> { iter: S, parent: ID, marker : std::marker::PhantomData<&'a S> }
|
||||
//
|
||||
// // impl<'a, V: GetParent + 'a, S: Iterator<Item=&'a V>> Iterator for FilterOfParent<S> {
|
||||
// // type Item = &'a V;
|
||||
// //
|
||||
// // #[inline]
|
||||
// // fn next(&mut self) -> Option<Self::Item> {
|
||||
// // let parent = self.parent;
|
||||
// // self.iter.find(|x| x.get_parent() == parent)
|
||||
// // }
|
||||
// // }
|
||||
//
|
||||
// impl<'a, V: GetParent + 'a, S: Iterator<Item=V>> Iterator for FilterOfParent<'a, S> {
|
||||
// type Item = V;
|
||||
//
|
||||
// #[inline]
|
||||
// fn next(&mut self) -> Option<Self::Item> {
|
||||
// let parent = self.parent;
|
||||
// self.iter.find(|x| x.get_parent() == parent)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// pub trait WhereParent<'a>: Sized {
|
||||
// fn where_parent(self, id: ID) -> FilterOfParent<'a, Self>;
|
||||
// }
|
||||
//
|
||||
// impl<'a, V : 'a, S : 'a + Iterator<Item=V>> WhereParent<'a> for S {
|
||||
// fn where_parent(self, id: ID) -> FilterOfParent<'a, Self> {
|
||||
// FilterOfParent { iter: self, parent: id, marker: std::marker::PhantomData }
|
||||
// }
|
||||
// }
|
||||
|
||||
pub trait GroupByParent<'a, T: 'a + GetParent>: Sized {
|
||||
fn group_by_parent(self) -> HashMap<ID, Vec<T>>;
|
||||
}
|
||||
|
||||
impl<'a, T: 'a + GetParent, S: IntoIterator<Item = T>> GroupByParent<'a, T> for S {
|
||||
#[inline]
|
||||
fn group_by_parent(self) -> HashMap<ID, Vec<T>> {
|
||||
self.into_iter().into_group_map_by(|v| v.get_parent())
|
||||
}
|
||||
}
|
||||
|
||||
pub trait GroupByModel<'a, T: 'a + GetModelID>: Sized {
|
||||
fn group_by_model(self) -> HashMap<ID, Vec<T>>;
|
||||
}
|
||||
|
||||
impl<'a, T: 'a + GetModelID, S: IntoIterator<Item = T>> GroupByModel<'a, T> for S {
|
||||
#[inline]
|
||||
fn group_by_model(self) -> HashMap<ID, Vec<T>> {
|
||||
self.into_iter().into_group_map_by(|v| v.get_model_id())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::helpers::{GetParent, GroupByParent};
|
||||
use crate::id::random_id;
|
||||
use crate::ID;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
struct Child(ID, &'static str);
|
||||
|
||||
impl GetParent for Child {
|
||||
fn get_parent(&self) -> ID {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn group_vec() {
|
||||
let parent1 = random_id();
|
||||
let parent2 = random_id();
|
||||
|
||||
let vec = vec![
|
||||
Child(parent1, "A"),
|
||||
Child(parent2, "C"),
|
||||
Child(parent1, "B"),
|
||||
Child(parent2, "D"),
|
||||
];
|
||||
|
||||
let mut grouped = vec.group_by_parent();
|
||||
|
||||
assert_eq!(2, grouped.len());
|
||||
|
||||
assert_eq!(
|
||||
grouped.remove(&parent1).unwrap(),
|
||||
vec![Child(parent1, "A"), Child(parent1, "B"),]
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
grouped.remove(&parent2).unwrap(),
|
||||
vec![Child(parent2, "C"), Child(parent2, "D"),]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn group_iter() {
|
||||
let parent1 = random_id();
|
||||
let parent2 = random_id();
|
||||
|
||||
let vec = vec![
|
||||
Child(parent1, "A"),
|
||||
Child(parent2, "C"),
|
||||
Child(parent1, "B"),
|
||||
Child(parent2, "D"),
|
||||
];
|
||||
|
||||
let mut grouped = vec.into_iter().group_by_parent();
|
||||
|
||||
assert_eq!(2, grouped.len());
|
||||
|
||||
assert_eq!(
|
||||
grouped.remove(&parent1).unwrap(),
|
||||
vec![Child(parent1, "A"), Child(parent1, "B"),]
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
grouped.remove(&parent2).unwrap(),
|
||||
vec![Child(parent2, "C"), Child(parent2, "D"),]
|
||||
);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn count_where_parent() {
|
||||
// let parent1 = random_id();
|
||||
// let parent2 = random_id();
|
||||
//
|
||||
// let vec = vec![
|
||||
// Child(parent1, "A"),
|
||||
// Child(parent2, "C"),
|
||||
// Child(parent1, "B"),
|
||||
// Child(parent2, "D"),
|
||||
// ];
|
||||
//
|
||||
// let _ = vec.iter().where_parent(parent2).next();
|
||||
// }
|
||||
}
|
||||
@@ -17,3 +17,16 @@ pub type ID = u32;
|
||||
pub trait HaveId {
|
||||
fn get_id(&self) -> ID;
|
||||
}
|
||||
|
||||
#[cfg(feature = "uuid-ids")]
|
||||
#[cfg(test)]
|
||||
pub fn random_id() -> ID {
|
||||
ID::new_v4()
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "uuid-ids"))]
|
||||
#[cfg(test)]
|
||||
pub fn random_id() -> ID {
|
||||
use rand::Rng;
|
||||
rand::thread_rng().gen()
|
||||
}
|
||||
|
||||
+1
-5
@@ -48,11 +48,7 @@ pub struct InsertObj {
|
||||
}
|
||||
|
||||
impl InsertObj {
|
||||
pub fn new(
|
||||
model_id: ID,
|
||||
values: Vec<InsertValue>,
|
||||
relations: Vec<InsertRel>,
|
||||
) -> Self {
|
||||
pub fn new(model_id: ID, values: Vec<InsertValue>, relations: Vec<InsertRel>) -> Self {
|
||||
Self {
|
||||
model: model_id,
|
||||
values,
|
||||
|
||||
+34
-34
@@ -1,7 +1,8 @@
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
// #[macro_use]
|
||||
// extern crate serde_json;
|
||||
#[cfg(test)]
|
||||
#[macro_use]
|
||||
extern crate serde_json;
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashMap;
|
||||
@@ -21,10 +22,11 @@ use insert::InsertValue;
|
||||
pub use model::DataType;
|
||||
use model::ObjectModel;
|
||||
|
||||
use crate::cool::IsNoneOrElse;
|
||||
use crate::data::Object;
|
||||
use crate::helpers::{GroupByModel, GroupByParent};
|
||||
use crate::model::{PropertyModel, RelationModel};
|
||||
use crate::update::{UpdateObj, UpsertValue};
|
||||
use crate::cool::IsNoneOrElse;
|
||||
use crate::data::{Object, Value};
|
||||
|
||||
mod cool;
|
||||
pub mod data;
|
||||
@@ -33,6 +35,8 @@ pub mod insert;
|
||||
pub mod model;
|
||||
pub mod update;
|
||||
|
||||
pub mod helpers;
|
||||
|
||||
mod serde_atomic_id;
|
||||
mod serde_map_as_list;
|
||||
#[cfg(test)]
|
||||
@@ -193,7 +197,7 @@ impl Storage {
|
||||
}
|
||||
|
||||
bincode::deserialize_from(reader)?
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
let opts = std::mem::replace(&mut self.opts, StoreOpts::default());
|
||||
@@ -231,7 +235,7 @@ impl Storage {
|
||||
writer.write_all(YOPA_MAGIC)?;
|
||||
writer.write_all(&[BINARY_FORMAT])?;
|
||||
bincode::serialize_into(writer, self)?
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -262,8 +266,16 @@ impl Storage {
|
||||
}
|
||||
|
||||
pub fn get_object_name<'b, 'a: 'b>(&'a self, object: &'a Object) -> Cow<'b, str> {
|
||||
if let Some(ObjectModel{ name_property: Some(name_property), .. }) = self.get_object_model(object.model) {
|
||||
if let Some(v) = self.values.values().find(|v| v.object == object.id && &v.model == name_property) {
|
||||
if let Some(ObjectModel {
|
||||
name_property: Some(name_property),
|
||||
..
|
||||
}) = self.get_object_model(object.model)
|
||||
{
|
||||
if let Some(v) = self
|
||||
.values
|
||||
.values()
|
||||
.find(|v| v.object == object.id && &v.model == name_property)
|
||||
{
|
||||
return v.value.to_cow();
|
||||
}
|
||||
}
|
||||
@@ -293,7 +305,9 @@ impl Storage {
|
||||
|
||||
/// Iterate object models with given IDs
|
||||
pub fn get_object_models_by_ids(&self, ids: Vec<ID>) -> impl Iterator<Item = &ObjectModel> {
|
||||
self.obj_models.values().filter(move |m| ids.contains(&m.id))
|
||||
self.obj_models
|
||||
.values()
|
||||
.filter(move |m| ids.contains(&m.id))
|
||||
}
|
||||
|
||||
/// Get an object model by ID
|
||||
@@ -313,9 +327,7 @@ impl Storage {
|
||||
|
||||
/// Get all property models grouped by the parent object ID.
|
||||
pub fn get_grouped_prop_models(&self) -> HashMap<ID, Vec<&PropertyModel>> {
|
||||
self.prop_models
|
||||
.values()
|
||||
.into_group_map_by(|model| model.object)
|
||||
self.prop_models.values().group_by_parent()
|
||||
}
|
||||
|
||||
/// Get property models belonging to a group of parent IDs,
|
||||
@@ -327,7 +339,7 @@ impl Storage {
|
||||
self.prop_models
|
||||
.values()
|
||||
.filter(|p| parent_model_ids.contains(&p.object))
|
||||
.into_group_map_by(|model| model.object)
|
||||
.group_by_parent()
|
||||
}
|
||||
|
||||
/// Iterate relation models attached to an object model
|
||||
@@ -362,9 +374,7 @@ impl Storage {
|
||||
|
||||
/// Get all relation models, grouped by their source object model ID
|
||||
pub fn get_grouped_relation_models(&self) -> HashMap<ID, Vec<&RelationModel>> {
|
||||
self.rel_models
|
||||
.values()
|
||||
.into_group_map_by(|model| model.object)
|
||||
self.rel_models.values().group_by_parent()
|
||||
}
|
||||
|
||||
/// Get reciprocal relation models, grouped by their destination model ID
|
||||
@@ -411,7 +421,7 @@ impl Storage {
|
||||
self.values
|
||||
.values()
|
||||
.filter(move |prop| parents.contains(&prop.object))
|
||||
.into_group_map_by(|model| model.object)
|
||||
.group_by_parent()
|
||||
}
|
||||
|
||||
/// Get all objects belonging to a model.
|
||||
@@ -432,9 +442,7 @@ impl Storage {
|
||||
|
||||
/// Get all objects, grouped by their model ID
|
||||
pub fn get_grouped_objects(&self) -> HashMap<ID, Vec<&data::Object>> {
|
||||
self.objects
|
||||
.values()
|
||||
.into_group_map_by(|object| object.model)
|
||||
self.objects.values().group_by_model()
|
||||
}
|
||||
|
||||
/// Get object by ID
|
||||
@@ -830,7 +838,7 @@ impl Storage {
|
||||
parent_id: ID,
|
||||
parent_model_id: ID|
|
||||
-> Result<Vec<data::Value>, StorageError> {
|
||||
let mut values_by_id = values.into_iter().into_group_map_by(|iv| iv.model);
|
||||
let mut values_by_id = values.group_by_model();
|
||||
let mut values_to_insert = vec![];
|
||||
|
||||
for (prop_model_id, prop) in self
|
||||
@@ -908,10 +916,7 @@ impl Storage {
|
||||
let mut values_to_insert = find_values_to_insert(insobj.values, object_id, obj_model_id)?;
|
||||
|
||||
// And now ..... relations!
|
||||
let mut relations_by_id = insobj
|
||||
.relations
|
||||
.into_iter()
|
||||
.into_group_map_by(|ir| ir.model);
|
||||
let mut relations_by_id = insobj.relations.group_by_model();
|
||||
let mut relations_to_insert = vec![];
|
||||
|
||||
for (relation_model_id, relation_model) in self
|
||||
@@ -1020,7 +1025,7 @@ impl Storage {
|
||||
),
|
||||
StorageError,
|
||||
> {
|
||||
let mut values_by_model = values.into_iter().into_group_map_by(|iv| iv.model);
|
||||
let mut values_by_model = values.group_by_model();
|
||||
let mut values_to_insert = vec![];
|
||||
let mut ids_to_delete = vec![];
|
||||
|
||||
@@ -1028,7 +1033,7 @@ impl Storage {
|
||||
.values
|
||||
.values()
|
||||
.filter(|v| v.object == parent_id)
|
||||
.into_group_map_by(|v| v.model);
|
||||
.group_by_model();
|
||||
|
||||
for (prop_model_id, prop) in self
|
||||
.prop_models
|
||||
@@ -1113,10 +1118,7 @@ impl Storage {
|
||||
find_values_to_change(updobj.values, updated_object_id, updated_object_model_id)?;
|
||||
|
||||
// And now ..... relations!
|
||||
let mut relations_by_model = updobj
|
||||
.relations
|
||||
.into_iter()
|
||||
.into_group_map_by(|ir| ir.model);
|
||||
let mut relations_by_model = updobj.relations.group_by_model();
|
||||
let mut relations_to_insert = vec![];
|
||||
let mut relations_to_delete = vec![];
|
||||
|
||||
@@ -1124,7 +1126,7 @@ impl Storage {
|
||||
.relations
|
||||
.values()
|
||||
.filter(|v| v.object == updated_object_id)
|
||||
.into_group_map_by(|v| v.model);
|
||||
.group_by_model();
|
||||
|
||||
let rel_models_by_id = self
|
||||
.rel_models
|
||||
@@ -1196,8 +1198,6 @@ impl Storage {
|
||||
);
|
||||
}
|
||||
|
||||
let obj_mut = self.objects.get_mut(&updated_object_id).unwrap();
|
||||
|
||||
debug!("Add {} new object relations", relations_to_insert.len());
|
||||
for rel in relations_to_insert {
|
||||
self.relations.insert(rel.id, rel);
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
//! Serialize atomic ID by fetching its value
|
||||
|
||||
use crate::id::ID;
|
||||
use serde::{Serialize, Deserializer, Deserialize};
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
|
||||
pub fn serialize<S>(x: &atomic::Atomic<ID>, s: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
x.load(atomic::Ordering::Relaxed)
|
||||
.serialize(s)
|
||||
x.load(atomic::Ordering::Relaxed).serialize(s)
|
||||
}
|
||||
|
||||
pub fn deserialize<'de, D>(deserializer: D) -> Result<atomic::Atomic<ID>, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let id: ID = ID::deserialize(deserializer)?;
|
||||
Ok(atomic::Atomic::new(id))
|
||||
|
||||
@@ -5,6 +5,7 @@ fn test1() {
|
||||
let model = crate::model::ObjectModel {
|
||||
id: Default::default(),
|
||||
name: "Name".to_string(),
|
||||
name_property: None,
|
||||
};
|
||||
|
||||
println!("{}", serde_json::to_string_pretty(&model).unwrap());
|
||||
|
||||
Reference in New Issue
Block a user