Skip to main content
Glama
lib.rs4.3 kB
//! Provides macro(s) for building materialized views. use manyhow::manyhow; use quote::quote; struct BuildMv { ctx: syn::Expr, frigg: syn::Expr, change: syn::Expr, mv_id: syn::Expr, mv_name: syn::Path, build_fn: syn::Expr, } impl syn::parse::Parse for BuildMv { fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> { let ctx = input.parse::<syn::Expr>()?; input.parse::<syn::Token![,]>()?; let frigg = input.parse::<syn::Expr>()?; input.parse::<syn::Token![,]>()?; let change = input.parse::<syn::Expr>()?; input.parse::<syn::Token![,]>()?; let mv_id = input.parse::<syn::Expr>()?; input.parse::<syn::Token![,]>()?; let mv_name = input.parse::<syn::Path>()?; input.parse::<syn::Token![,]>()?; let build_fn = input.parse::<syn::Expr>()?; input.parse::<Option<syn::Token![,]>>()?; Ok(BuildMv { ctx, frigg, change, mv_id, mv_name, build_fn, }) } } #[manyhow] #[proc_macro] // You can also merge the two attributes: #[manyhow(proc_macro)] pub fn build_mv(input: proc_macro2::TokenStream) -> syn::Result<proc_macro2::TokenStream> { let BuildMv { ctx, frigg, change, mv_id, mv_name, build_fn, } = syn::parse::<BuildMv>(input.into())?; let output = quote! { { let ctx = #ctx; let frigg = #frigg; let change = #change; let mv_id = #mv_id; let maybe_patch = if <#mv_name as si_frontend_types::materialized_view::MaterializedView>::trigger_entity() != change.entity_kind { None } else { if !ctx .workspace_snapshot()? .node_exists(change.entity_id) .await { // Object was removed Some(( si_frontend_types::object::patch::ObjectPatch { kind: <#mv_name as si_frontend_types::materialized_view::MaterializedView>::kind().to_string(), id: mv_id, // TODO: we need to get the prior version of this from_checksum: Checksum::default().to_string(), to_checksum: "0".to_string(), patch: json_patch::Patch(vec![json_patch::PatchOperation::Remove( json_patch::RemoveOperation::default(), )]), }, None )) } else { let mv = #build_fn?; let mv_json = serde_json::to_value(&mv)?; let to_checksum = si_frontend_types::checksum::FrontendChecksum::checksum(&mv).to_string(); let frontend_object: si_frontend_types::object::FrontendObject = mv.try_into()?; let kind = <#mv_name as si_frontend_types::materialized_view::MaterializedView>::kind().to_string(); let (from_checksum, previous_data) = if let Some(previous_version) = frigg.get_current_object(ctx.workspace_pk()?, ctx.change_set_id(), &kind, &mv_id).await? { (previous_version.checksum, previous_version.data) } else { // Object is new ("0".to_string(), serde_json::Value::Null) }; if from_checksum == to_checksum { None } else { Some(( si_frontend_types::object::patch::ObjectPatch { kind, id: mv_id, from_checksum, to_checksum, patch: json_patch::diff(&previous_data, &mv_json), }, Some(frontend_object), )) } } }; Ok(maybe_patch) } }; Ok(output) }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/systeminit/si'

If you have feedback or need assistance with the MCP directory API, please join our Discord server