|
@@ -9,6 +9,7 @@ use crate::{
|
|
|
entity::{Entity, EntityID, EntityPart, EntityPartList, EntityPartVisitor},
|
|
|
relation::{Relation, RelationDomain, RelationMap, RelationRange},
|
|
|
},
|
|
|
+ ConnectionLease,
|
|
|
};
|
|
|
|
|
|
// helper alias for later
|
|
@@ -19,6 +20,7 @@ impl<EI: EntityInterface> Autogenerate<EI> {
|
|
|
pub fn perform(
|
|
|
self,
|
|
|
ctx: &EI::Context,
|
|
|
+ lease: &mut ConnectionLease,
|
|
|
query_ctx: impl Queryable<EntityOutput = EI::Entity> + Insertable<EI::Entity>,
|
|
|
) -> Result<(), EI::Error> {
|
|
|
match self.verb {
|
|
@@ -36,7 +38,7 @@ impl<EI: EntityInterface> Autogenerate<EI> {
|
|
|
)
|
|
|
.unwrap(),
|
|
|
)
|
|
|
- .get()?
|
|
|
+ .get(lease)?
|
|
|
.ok_or(<EI::Error>::no_such_entity(
|
|
|
EI::Entity::entity_name(),
|
|
|
local_keys
|
|
@@ -50,6 +52,7 @@ impl<EI: EntityInterface> Autogenerate<EI> {
|
|
|
let mut attacher = Attacher {
|
|
|
do_attach: true,
|
|
|
relation: relation.as_str(),
|
|
|
+ lease,
|
|
|
remote_keys,
|
|
|
err: None,
|
|
|
_ghost: Default::default(),
|
|
@@ -67,7 +70,7 @@ impl<EI: EntityInterface> Autogenerate<EI> {
|
|
|
UniqueList::<EI::Entity>::build_equivalent(keys.iter().map(String::as_str))
|
|
|
.unwrap(),
|
|
|
)
|
|
|
- .delete()?;
|
|
|
+ .delete(lease)?;
|
|
|
},
|
|
|
Verb::Detach {
|
|
|
local_keys,
|
|
@@ -83,7 +86,7 @@ impl<EI: EntityInterface> Autogenerate<EI> {
|
|
|
)
|
|
|
.unwrap(),
|
|
|
)
|
|
|
- .get()?
|
|
|
+ .get(lease)?
|
|
|
.ok_or(<EI::Error>::no_such_entity(
|
|
|
EI::Entity::entity_name(),
|
|
|
local_keys
|
|
@@ -97,6 +100,7 @@ impl<EI: EntityInterface> Autogenerate<EI> {
|
|
|
let mut attacher = Attacher {
|
|
|
do_attach: false,
|
|
|
relation: relation.as_str(),
|
|
|
+ lease,
|
|
|
remote_keys,
|
|
|
err: None,
|
|
|
_ghost: Default::default(),
|
|
@@ -111,9 +115,9 @@ impl<EI: EntityInterface> Autogenerate<EI> {
|
|
|
println!(
|
|
|
"Listing all {}(s): ({})",
|
|
|
EI::Entity::entity_name(),
|
|
|
- query_ctx.clone().count()?
|
|
|
+ query_ctx.clone().count(lease)?
|
|
|
);
|
|
|
- for obj in query_ctx.get()?.into_iter() {
|
|
|
+ for obj in query_ctx.get(lease)?.into_iter() {
|
|
|
println!(
|
|
|
" - {}",
|
|
|
EI::summarize(&obj).unwrap_or_else(|| format!("{:?}", obj))
|
|
@@ -127,7 +131,7 @@ impl<EI: EntityInterface> Autogenerate<EI> {
|
|
|
UniqueList::<EI::Entity>::build_equivalent(keys.iter().map(String::as_str))
|
|
|
.unwrap(),
|
|
|
)
|
|
|
- .get()?
|
|
|
+ .get(lease)?
|
|
|
.ok_or(<EI::Error>::no_such_entity(
|
|
|
EI::Entity::entity_name(),
|
|
|
keys.iter()
|
|
@@ -138,20 +142,27 @@ impl<EI: EntityInterface> Autogenerate<EI> {
|
|
|
))?;
|
|
|
println!("{:#?}", obj.as_ref());
|
|
|
|
|
|
- fn inspect_ai<AI: RelationInterface>(name: &'static str, ai: &AI) {
|
|
|
- println!("{}: ({})", name, ai.count().unwrap());
|
|
|
- for a in ai.get().expect("couldn't get object relations") {
|
|
|
+ fn inspect_ai<AI: RelationInterface>(
|
|
|
+ name: &'static str,
|
|
|
+ lease: &mut ConnectionLease<'_>,
|
|
|
+ ai: &AI,
|
|
|
+ ) {
|
|
|
+ println!("{}: ({})", name, ai.count(lease).unwrap());
|
|
|
+ for a in ai.get(lease).expect("couldn't get object relations") {
|
|
|
println!("[#{:3}]: {:?}", a.id().into_raw(), a.wrapped());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- struct RelationFieldWalker<E: Entity>(std::marker::PhantomData<E>);
|
|
|
- impl<E: Entity> EntityPartVisitor for RelationFieldWalker<E> {
|
|
|
+ struct RelationFieldWalker<'r, 'l: 'r, E: Entity>(
|
|
|
+ &'r mut ConnectionLease<'l>,
|
|
|
+ std::marker::PhantomData<E>,
|
|
|
+ );
|
|
|
+ impl<'r, 'l: 'r, E: Entity> EntityPartVisitor for RelationFieldWalker<'r, 'l, E> {
|
|
|
type Entity = E;
|
|
|
fn visit_datum<EP: EntityPart>(&mut self, datum: &EP::Datum) {
|
|
|
- struct Discriminator(&'static str);
|
|
|
+ struct Discriminator<'r, 'l: 'r>(&'r mut ConnectionLease<'l>, &'static str);
|
|
|
|
|
|
- impl DatumDiscriminatorRef for Discriminator {
|
|
|
+ impl<'r, 'l> DatumDiscriminatorRef for Discriminator<'r, 'l> {
|
|
|
fn visit_serialized<
|
|
|
T: serde::Serialize + serde::de::DeserializeOwned,
|
|
|
>(
|
|
@@ -162,30 +173,30 @@ impl<EI: EntityInterface> Autogenerate<EI> {
|
|
|
fn visit_bare_field<T: Datum>(&mut self, _: &T) {}
|
|
|
fn visit_entity_id<E: Entity>(&mut self, _: &E::ID) {}
|
|
|
fn visit_relation_map<E: Entity>(&mut self, amap: &RelationMap<E>) {
|
|
|
- inspect_ai(self.0, amap);
|
|
|
+ inspect_ai(self.1, self.0, amap);
|
|
|
}
|
|
|
fn visit_relation_domain<R: Relation>(
|
|
|
&mut self,
|
|
|
adomain: &RelationDomain<R>,
|
|
|
) {
|
|
|
- inspect_ai(self.0, adomain);
|
|
|
+ inspect_ai(self.1, self.0, adomain);
|
|
|
}
|
|
|
fn visit_relation_range<R: Relation>(
|
|
|
&mut self,
|
|
|
arange: &RelationRange<R>,
|
|
|
) {
|
|
|
- inspect_ai(self.0, arange);
|
|
|
+ inspect_ai(self.1, self.0, arange);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- datum.accept_discriminator_ref(&mut Discriminator(EP::part_name()));
|
|
|
+ datum.accept_discriminator_ref(&mut Discriminator(self.0, EP::part_name()));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- obj.accept_part_visitor_ref(&mut RelationFieldWalker(Default::default()));
|
|
|
+ obj.accept_part_visitor_ref(&mut RelationFieldWalker(lease, Default::default()));
|
|
|
},
|
|
|
Verb::Custom(custom) => {
|
|
|
- EI::run_custom(ctx, custom, query_ctx)?;
|
|
|
+ EI::run_custom(ctx, custom, lease, query_ctx)?;
|
|
|
},
|
|
|
}
|
|
|
|
|
@@ -194,15 +205,16 @@ impl<EI: EntityInterface> Autogenerate<EI> {
|
|
|
}
|
|
|
|
|
|
/// helper type for attach and detach verbs
|
|
|
-struct Attacher<'l, Error: CLIError, E: Entity> {
|
|
|
+struct Attacher<'r, 'l: 'r, Error: CLIError, E: Entity> {
|
|
|
do_attach: bool,
|
|
|
- relation: &'l str,
|
|
|
+ relation: &'r str,
|
|
|
+ lease: &'r mut ConnectionLease<'l>,
|
|
|
remote_keys: Vec<String>,
|
|
|
err: Option<Error>,
|
|
|
_ghost: std::marker::PhantomData<E>,
|
|
|
}
|
|
|
|
|
|
-impl<'l, Error: CLIError, OE: Entity> Attacher<'l, Error, OE> {
|
|
|
+impl<'r, 'l: 'r, Error: CLIError, OE: Entity> Attacher<'r, 'l, Error, OE> {
|
|
|
fn do_operation<E: Entity>(&mut self, map: &impl RelationInterface<RemoteEntity = E>) {
|
|
|
match map
|
|
|
.query_all()
|
|
@@ -210,13 +222,16 @@ impl<'l, Error: CLIError, OE: Entity> Attacher<'l, Error, OE> {
|
|
|
UniqueList::<E>::build_equivalent(self.remote_keys.iter().map(String::as_str))
|
|
|
.unwrap(),
|
|
|
)
|
|
|
- .get()
|
|
|
+ .get(self.lease)
|
|
|
{
|
|
|
Ok(Some(obj)) => {
|
|
|
if self.do_attach {
|
|
|
- self.err = map.connect_to(obj.id()).err().map(Into::into);
|
|
|
+ self.err = map.connect_to(self.lease, obj.id()).err().map(Into::into);
|
|
|
} else {
|
|
|
- self.err = map.disconnect_from(obj.id()).err().map(Into::into);
|
|
|
+ self.err = map
|
|
|
+ .disconnect_from(self.lease, obj.id())
|
|
|
+ .err()
|
|
|
+ .map(Into::into);
|
|
|
}
|
|
|
},
|
|
|
Ok(None) => {
|
|
@@ -237,7 +252,7 @@ impl<'l, Error: CLIError, OE: Entity> Attacher<'l, Error, OE> {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl<'l, Error: CLIError, E: Entity> EntityPartVisitor for Attacher<'l, Error, E> {
|
|
|
+impl<'r, 'l: 'r, Error: CLIError, E: Entity> EntityPartVisitor for Attacher<'r, 'l, Error, E> {
|
|
|
type Entity = E;
|
|
|
fn visit_datum<EP: EntityPart>(&mut self, datum: &EP::Datum) {
|
|
|
if EP::part_name() != self.relation {
|
|
@@ -248,7 +263,9 @@ impl<'l, Error: CLIError, E: Entity> EntityPartVisitor for Attacher<'l, Error, E
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl<'l, Error: CLIError, OE: Entity> DatumDiscriminatorRef for Attacher<'l, Error, OE> {
|
|
|
+impl<'r, 'l: 'r, Error: CLIError, OE: Entity> DatumDiscriminatorRef
|
|
|
+ for Attacher<'r, 'l, Error, OE>
|
|
|
+{
|
|
|
fn visit_entity_id<E: Entity>(&mut self, _: &E::ID) {
|
|
|
unreachable!()
|
|
|
}
|