From d44215e011e261dedc7d11f55c9fcc89d2c58de2 Mon Sep 17 00:00:00 2001 From: Edyta Pawlak Date: Fri, 29 Mar 2024 12:34:43 +0100 Subject: [PATCH] feat: split ocafile validation and building logic --- oca/src/facade/build.rs | 196 ++++++++++++++++++++++------------------ 1 file changed, 109 insertions(+), 87 deletions(-) diff --git a/oca/src/facade/build.rs b/oca/src/facade/build.rs index 481d866..919c5e6 100644 --- a/oca/src/facade/build.rs +++ b/oca/src/facade/build.rs @@ -12,13 +12,11 @@ use crate::repositories::{ #[cfg(feature = "local-references")] use log::debug; use oca_ast::ast::{OCAAst, ObjectKind, RefValue, ReferenceAttrType}; -use oca_bundle::build::OCABuild; +use oca_bundle::build::{OCABuild, OCABuildStep}; use oca_bundle::state::oca::OCABundle; use oca_bundle::Encode; use oca_dag::build_core_db_model; -use std::borrow::Borrow; - #[derive(thiserror::Error, Debug, serde::Serialize)] #[serde(untagged)] pub enum Error { @@ -62,6 +60,63 @@ impl References for Box { } impl Facade { + #[cfg(not(feature = "local-references"))] + pub fn validate_ocafile(&self, ocafile: String) -> Result> { + let (base, oca_ast) = Self::parse_and_check_base(self.storage(), ocafile)?; + oca_bundle::build::from_ast(base, &oca_ast).map_err(|e| { + e.iter() + .map(|e| ValidationError::OCABundleBuild(e.clone())) + .collect::>() + }) + } + + /// Validate ocafile using external references for dereferencing `refn`. It + /// won't update facade internal database with `refn`-> `said` mapping, so `refn` + /// can't be dereferenced in ocafiles processed later. + #[cfg(feature = "local-references")] + pub fn validate_ocafile_with_external_references( + &self, + ocafile: String, + references: &mut R, + ) -> Result> { + let (base, oca_ast) = Self::parse_and_check_base(self.storage(), ocafile)?; + Self::oca_ast_to_oca_build_with_references(base, oca_ast, references) + } + + /// Validate ocafile using internal references for dereferencing `refn`. + /// Mapping between `refn` -> `said` is saved in facades database, so it can + /// be dereferenced in other ocafiles later. + #[cfg(feature = "local-references")] + pub fn validate_ocafile(&mut self, ocafile: String) -> Result> { + let (base, oca_ast) = Self::parse_and_check_base(self.storage(), ocafile)?; + Self::oca_ast_to_oca_build_with_references(base, oca_ast, &mut self.db) + } + + pub fn build(&mut self, oca_build: &OCABuild) -> Result> { + self.build_cache(&oca_build.oca_bundle); + + self.build_meta(&oca_build.oca_bundle); + + oca_build + .steps + .iter() + .for_each(|step| self.build_step(step)); + + let _ = self.add_relations(oca_build.oca_bundle.clone()); + + self.build_models(&oca_build); + + Ok(oca_build.oca_bundle.clone()) + } + + pub fn build_from_ocafile(&mut self, ocafile: String) -> Result> { + let oca_build = self + .validate_ocafile(ocafile) + .map_err(|errs| vec![Error::ValidationError(errs)])?; + + self.build(&oca_build) + } + fn parse_and_check_base( storage: &dyn DataStorage, ocafile: String, @@ -147,49 +202,18 @@ impl Facade { Ok(oca_build) } - #[cfg(feature = "local-references")] - pub fn validate_ocafile( - storage: &dyn DataStorage, - ocafile: String, - references: &mut R, - ) -> Result> { - let (base, oca_ast) = Self::parse_and_check_base(storage, ocafile)?; - Self::oca_ast_to_oca_build_with_references(base, oca_ast, references) - } - - #[cfg(not(feature = "local-references"))] - pub fn validate_ocafile( - storage: &dyn DataStorage, - ocafile: String, - ) -> Result> { - let (base, oca_ast) = Self::parse_and_check_base(storage, ocafile)?; - oca_bundle::build::from_ast(base, &oca_ast).map_err(|e| { - e.iter() - .map(|e| ValidationError::OCABundleBuild(e.clone())) - .collect::>() - }) - } - - pub fn build_from_ocafile(&mut self, ocafile: String) -> Result> { - let oca_build = Self::validate_ocafile( - self.db_cache.borrow(), - ocafile, - #[cfg(feature = "local-references")] - &mut self.db, - ) - .map_err(|errs| vec![Error::ValidationError(errs)])?; - + fn build_cache(&self, oca_bundle: &OCABundle) { let oca_bundle_cache_repo = OCABundleCacheRepo::new(self.connection()); - let oca_bundle_cache_record = OCABundleCacheRecord::new(&oca_build.oca_bundle); + let oca_bundle_cache_record = OCABundleCacheRecord::new(&oca_bundle); oca_bundle_cache_repo.insert(oca_bundle_cache_record); let capture_base_cache_repo = CaptureBaseCacheRepo::new(self.connection()); - let capture_base_cache_record = - CaptureBaseCacheRecord::new(&oca_build.oca_bundle.capture_base); + let capture_base_cache_record = CaptureBaseCacheRecord::new(&oca_bundle.capture_base); capture_base_cache_repo.insert(capture_base_cache_record); + } - let meta_overlays = oca_build - .oca_bundle + fn build_meta(&self, oca_bundle: &OCABundle) { + let meta_overlays = oca_bundle .overlays .iter() .filter_map(|x| { @@ -197,11 +221,11 @@ impl Facade { .downcast_ref::() }) .collect::>(); - if !meta_overlays.is_empty() { + if meta_overlays.is_empty() { let oca_bundle_fts_repo = OCABundleFTSRepo::new(self.connection()); for meta_overlay in meta_overlays { let oca_bundle_fts_record = OCABundleFTSRecord::new( - oca_build.oca_bundle.said.clone().unwrap().to_string(), + oca_bundle.said.clone().unwrap().to_string(), meta_overlay .attr_pairs .get(&"name".to_string()) @@ -218,59 +242,59 @@ impl Facade { oca_bundle_fts_repo.insert(oca_bundle_fts_record); } } + } - oca_build.steps.iter().for_each(|step| { - let mut input: Vec = vec![]; - match &step.parent_said { - Some(said) => { - input.push(said.to_string().as_bytes().len().try_into().unwrap()); - input.extend(said.to_string().as_bytes()); - } - None => { - input.push(0); - } + fn build_step(&mut self, step: &OCABuildStep) { + let mut input: Vec = vec![]; + match &step.parent_said { + Some(said) => { + input.push(said.to_string().as_bytes().len().try_into().unwrap()); + input.extend(said.to_string().as_bytes()); } + None => { + input.push(0); + } + } - let command_str = serde_json::to_string(&step.command).unwrap(); - input.extend(command_str.as_bytes()); - let result_bundle = step.result.clone(); - self.db - .insert( - Namespace::OCA, - &format!("oca.{}.operation", result_bundle.said.clone().unwrap()), - &input, - ) - .unwrap(); - - self.db_cache - .insert( - Namespace::OCABundlesJSON, - &result_bundle.said.clone().unwrap().to_string(), - &result_bundle.encode().unwrap(), - ) - .unwrap(); + let command_str = serde_json::to_string(&step.command).unwrap(); + input.extend(command_str.as_bytes()); + let result_bundle = step.result.clone(); + self.db + .insert( + Namespace::OCA, + &format!("oca.{}.operation", result_bundle.said.clone().unwrap()), + &input, + ) + .unwrap(); + + self.db_cache + .insert( + Namespace::OCABundlesJSON, + &result_bundle.said.clone().unwrap().to_string(), + &result_bundle.encode().unwrap(), + ) + .unwrap(); + self.db_cache + .insert( + Namespace::OCAObjectsJSON, + &result_bundle.capture_base.said.clone().unwrap().to_string(), + &serde_json::to_string(&result_bundle.capture_base) + .unwrap() + .into_bytes(), + ) + .unwrap(); + result_bundle.overlays.iter().for_each(|overlay| { self.db_cache .insert( Namespace::OCAObjectsJSON, - &result_bundle.capture_base.said.clone().unwrap().to_string(), - &serde_json::to_string(&result_bundle.capture_base) - .unwrap() - .into_bytes(), + &overlay.said().clone().unwrap().to_string(), + &serde_json::to_string(&overlay).unwrap().into_bytes(), ) .unwrap(); - result_bundle.overlays.iter().for_each(|overlay| { - self.db_cache - .insert( - Namespace::OCAObjectsJSON, - &overlay.said().clone().unwrap().to_string(), - &serde_json::to_string(&overlay).unwrap().into_bytes(), - ) - .unwrap(); - }); }); + } - let _ = self.add_relations(oca_build.oca_bundle.clone()); - + fn build_models(&mut self, oca_build: &OCABuild) { let result_models = build_core_db_model(&oca_build); result_models.iter().for_each(|model| { if let Some(command_model) = &model.command { @@ -384,7 +408,5 @@ impl Facade { .unwrap(); } }); - - Ok(oca_build.oca_bundle) } }