Skip to main content

data_modelling_core/export/
dbmv.rs

1//! Databricks Metric Views (DBMV) exporter
2//!
3//! Exports DBMVDocument models to DBMV YAML format.
4
5use crate::export::ExportError;
6use crate::models::dbmv::{DBMVDocument, DBMVMetricView};
7
8/// DBMV exporter for generating Databricks Metric Views YAML
9pub struct DBMVExporter;
10
11impl DBMVExporter {
12    /// Export a DBMV document to YAML format (instance method for WASM compatibility)
13    ///
14    /// Validates against the DBMV JSON Schema if the `schema-validation` feature is enabled.
15    pub fn export(&self, doc: &DBMVDocument) -> Result<String, ExportError> {
16        let yaml = Self::export_document(doc);
17
18        #[cfg(feature = "schema-validation")]
19        {
20            use crate::validation::schema::validate_dbmv_internal;
21            validate_dbmv_internal(&yaml).map_err(ExportError::ValidationError)?;
22        }
23
24        Ok(yaml)
25    }
26
27    /// Export a full multi-view DBMV document to YAML
28    pub fn export_document(doc: &DBMVDocument) -> String {
29        match serde_yaml::to_string(doc) {
30            Ok(yaml) => yaml,
31            Err(e) => format!("# Error serializing DBMV document: {}\n", e),
32        }
33    }
34
35    /// Export a single standalone Databricks metric view to YAML (no wrapper envelope)
36    pub fn export_single_view(view: &DBMVMetricView) -> String {
37        match serde_yaml::to_string(view) {
38            Ok(yaml) => yaml,
39            Err(e) => format!("# Error serializing metric view: {}\n", e),
40        }
41    }
42}
43
44#[cfg(test)]
45mod tests {
46    use super::*;
47    use crate::models::dbmv::*;
48
49    #[test]
50    fn test_export_document_basic() {
51        let doc = DBMVDocument::new("test-system");
52        let yaml = DBMVExporter::export_document(&doc);
53        assert!(yaml.contains("apiVersion: v1.0.0"));
54        assert!(yaml.contains("kind: MetricViews"));
55        assert!(yaml.contains("system: test-system"));
56    }
57
58    #[test]
59    fn test_export_document_with_views() {
60        let mut doc = DBMVDocument::new("sales-system");
61        doc.add_metric_view(DBMVMetricView {
62            name: "orders".to_string(),
63            source: "catalog.schema.orders".to_string(),
64            dimensions: vec![DBMVDimension {
65                name: "order_date".to_string(),
66                expr: "order_date".to_string(),
67                display_name: None,
68                comment: None,
69            }],
70            measures: vec![DBMVMeasure {
71                name: "total".to_string(),
72                expr: "SUM(amount)".to_string(),
73                display_name: None,
74                comment: None,
75                format: None,
76                window: vec![],
77            }],
78            ..Default::default()
79        });
80
81        let yaml = DBMVExporter::export_document(&doc);
82        assert!(yaml.contains("orders"));
83        assert!(yaml.contains("SUM(amount)"));
84    }
85
86    #[test]
87    fn test_export_single_view() {
88        let view = DBMVMetricView {
89            name: "test_view".to_string(),
90            source: "catalog.schema.table".to_string(),
91            ..Default::default()
92        };
93
94        let yaml = DBMVExporter::export_single_view(&view);
95        assert!(yaml.contains("name: test_view"));
96        assert!(yaml.contains("source: catalog.schema.table"));
97        // Should NOT contain envelope fields
98        assert!(!yaml.contains("apiVersion"));
99        assert!(!yaml.contains("kind"));
100    }
101}