/// Activate the recipe by migrating the Soup data-flow graph wrapped in `mig` to the recipe.
/// This causes all necessary changes to said graph to be applied; however, it is the caller's
/// responsibility to call `mig.commit()` afterwards.
// crate viz for tests
Activate the recipe by migrating the Soup data-flow graph wrapped in `mig` to the recipe.
This causes all necessary changes to said graph to be applied; however, it is the caller's
responsibility to call `mig.commit()` afterwards.
crate viz for tests
Activate the recipe by migrating the Soup data - flow graph wrapped in ` mig ` to the recipe . This causes all necessary changes to said graph to be applied ; however it is the caller ' s responsibility to call ` mig . commit () ` afterwards . crate viz for tests
pub(crate) fn activate(&mut self, mig: &mut Migration) -> Result<ActivationResult, String> {
        debug!(self.log, "{} queries, {} of which are named",
                                 self.expressions.len(),
                                 self.aliases.len(); "version" => self.version);
        let (added, removed) = match self.prior {
            None => self.compute_delta(&Recipe::blank(None)),
            Some(ref pr) => {
                // compute delta over prior recipe
                self.compute_delta(pr)
            }
        };
        let mut result = ActivationResult {
            new_nodes: HashMap::default(),
            removed_leaves: Vec::default(),
            expressions_added: added.len(),
            expressions_removed: removed.len(),
        };
        // upgrade schema version *before* applying changes, so that new queries are correctly
        // tagged with the new version. If this recipe was just created, there is no need to
        // upgrade the schema version, as the SqlIncorporator's version will still be at zero.
        if self.version > 0 {
            self.inc.as_mut().unwrap().upgrade_schema(self.version);
        }
        // create nodes to enforce security configuration
        if self.security_config.is_some() {
            info!(
                self.log,
                "Found a security configuration, bootstrapping groups..."
            );
            let config = self.security_config.take().unwrap();
            for group in config.groups.values() {
                info!(
                    self.log,
                    "Creating membership view for group {}",
                    group.name()
                );
                let qfp = self.inc.as_mut().unwrap().add_parsed_query(
                    group.membership(),
                    Some(group.name()),
                    true,
                    mig,
                )?;
                /// Add trigger node below group membership views
                let group_creation = TriggerEvent::GroupCreation {
                    group: group.name(),
                };
                let trigger = Trigger::new(qfp.query_leaf, group_creation, 1);
                mig.add_ingredient(
                    &format!("{}-trigger", group.name()),
                    &["uid", "gid"],
                    trigger,
                );
                result.new_nodes.insert(group.name(), qfp.query_leaf);
            }
            self.security_config = Some(config);
        }
        // add new queries to the Soup graph carried by `mig`, and reflect state in the
        // incorporator in `inc`. `NodeIndex`es for new nodes are collected in `new_nodes` to be
        // returned to the caller (who may use them to obtain mutators and getters)
        for qid in added {
            let (n, q, is_leaf) = self.expressions[&qid].clone();
            // add the query
            let qfp = self
                .inc
                .as_mut()
                .unwrap()
                .add_parsed_query(q, n.clone(), is_leaf, mig)?;
            // If the user provided us with a query name, use that.
            // If not, use the name internally used by the QFP.
            let query_name = match n {
                Some(name) => name,
                None => qfp.name.clone(),
            };
            result.new_nodes.insert(query_name, qfp.query_leaf);
        }
        result.removed_leaves = removed
            .iter()
            .filter_map(|qid| {
                let (ref n, ref q, _) = self.prior.as_ref().unwrap().expressions[qid];
                match q {
                    SqlQuery::CreateTable(ref ctq) => {
                        // a base may have many dependent queries, including ones that also lost
                        // nodes; the code handling `removed_leaves` therefore needs to take care
                        // not to remove bases while they still have children, or to try removing
                        // them twice.
                        self.inc.as_mut().unwrap().remove_base(&ctq.table.name);
                        match self.prior.as_ref().unwrap().node_addr_for(&ctq.table.name) {
                            Ok(ni) => Some(ni),
                            Err(e) => {
                                crit!(
                                    self.log,
                                    "failed to remove base {} whose  address could not be resolved",
                                    ctq.table.name
                                );
                                unimplemented!()
                            }
                        }
                    }
                    _ => self
                        .inc
                        .as_mut()
                        .unwrap()
                        .remove_query(n.as_ref().unwrap(), mig),
                }
            })
            .collect();
        Ok(result)
    }
pub ( crate ) fn activate ( & mut self , mig : & mut Migration ) -> Result < ActivationResult , String > { debug ! ( self log " " self expressions len ( ) self aliases len ( ) " " self version ) ; let ( added , removed ) = match self . prior { None => self . compute_delta ( & Recipe :: blank ( None ) ) , Some ( ref pr ) => { // compute delta over prior recipe self . compute_delta ( pr ) } } ; let mut result = ActivationResult { new_nodes : HashMap :: default ( ) , removed_leaves : Vec :: default ( ) , expressions_added : added . len ( ) , expressions_removed : removed . len ( ) , } ; // upgrade schema version *before* applying changes, so that new queries are correctly // tagged with the new version. If this recipe was just created, there is no need to // upgrade the schema version, as the SqlIncorporator's version will still be at zero. if self . version > 0 { self . inc . as_mut ( ) . unwrap ( ) . upgrade_schema ( self . version ) ; } // create nodes to enforce security configuration if self . security_config . is_some ( ) { info ! ( self log " " ) ; let config = self . security_config . take ( ) . unwrap ( ) ; for group in config . groups . values ( ) { info ! ( self log " " group name ( ) ) ; let qfp = self . inc . as_mut ( ) . unwrap ( ) . add_parsed_query ( group . membership ( ) , Some ( group . name ( ) ) , true , mig , ) ? ; /// Add trigger node below group membership views let group_creation = TriggerEvent :: GroupCreation { group : group . name ( ) , } ; let trigger = Trigger :: new ( qfp . query_leaf , group_creation , 1 ) ; mig . add_ingredient ( & format ! ( " " group name ( ) ) , & [ " " , " " ] , trigger , ) ; result . new_nodes . insert ( group . name ( ) , qfp . query_leaf ) ; } self . security_config = Some ( config ) ; } // add new queries to the Soup graph carried by `mig`, and reflect state in the // incorporator in `inc`. `NodeIndex`es for new nodes are collected in `new_nodes` to be // returned to the caller (who may use them to obtain mutators and getters) for qid in added { let ( n , q , is_leaf ) = self . expressions [ & qid ] . clone ( ) ; // add the query let qfp = self . inc . as_mut ( ) . unwrap ( ) . add_parsed_query ( q , n . clone ( ) , is_leaf , mig ) ? ; // If the user provided us with a query name, use that. // If not, use the name internally used by the QFP. let query_name = match n { Some ( name ) => name , None => qfp . name . clone ( ) , } ; result . new_nodes . insert ( query_name , qfp . query_leaf ) ; } result . removed_leaves = removed . iter ( ) . filter_map ( | qid | { let ( ref n , ref q , _ ) = self . prior . as_ref ( ) . unwrap ( ) . expressions [ qid ] ; match q { SqlQuery :: CreateTable ( ref ctq ) => { // a base may have many dependent queries, including ones that also lost // nodes; the code handling `removed_leaves` therefore needs to take care // not to remove bases while they still have children, or to try removing // them twice. self . inc . as_mut ( ) . unwrap ( ) . remove_base ( & ctq . table . name ) ; match self . prior . as_ref ( ) . unwrap ( ) . node_addr_for ( & ctq . table . name ) { Ok ( ni ) => Some ( ni ) , Err ( e ) => { crit ! ( self log " " ctq table name ) ; unimplemented ! ( ) } } } _ => self . inc . as_mut ( ) . unwrap ( ) . remove_query ( n . as_ref ( ) . unwrap ( ) , mig ) , } } ) . collect ( ) ; Ok ( result ) }
Activate the recipe by migrating the Soup data-flow graph wrapped in `mig` to the recipe.
Activate the recipe by migrating the Soup data - flow graph wrapped in ` mig ` to the recipe .
&mut self
mig
&mut Migration