added version history

This commit is contained in:
dal 2025-03-11 15:55:30 -06:00
parent 70121cc629
commit e9fc5cf9bb
No known key found for this signature in database
GPG Key ID: 16F4B0E1E9F61122
9 changed files with 116 additions and 19 deletions

View File

@ -5,10 +5,11 @@ use database::{
models::{DashboardFile, MetricFile},
pool::get_pg_pool,
schema::{datasets, metric_files},
types::VersionHistory,
};
use indexmap::IndexMap;
use query_engine::{data_source_query_routes::query_engine::query_engine, data_types::DataType};
use serde_json;
use serde_json::{self};
use serde_yaml;
use tracing::{debug, error};
use uuid::Uuid;
@ -589,12 +590,16 @@ pub async fn process_metric_file(
Err(e) => return Err(format!("Invalid SQL query: {}", e)),
};
let metric_yml_json = match serde_json::to_value(metric_yml.clone()) {
Ok(json) => json,
Err(e) => return Err(format!("Failed to process metric: {}", e)),
};
let metric_file = MetricFile {
id: metric_id,
name: file_name.clone(),
file_name: file_name.clone(),
content: serde_json::to_value(metric_yml.clone())
.map_err(|e| format!("Failed to process metric: {}", e))?,
content: metric_yml_json.clone(),
created_by: Uuid::new_v4(),
verification: Verification::NotRequested,
evaluation_obj: None,
@ -607,6 +612,7 @@ pub async fn process_metric_file(
publicly_accessible: false,
publicly_enabled_by: None,
public_expiry_date: None,
version_history: VersionHistory::new(1, metric_yml_json),
};
Ok((metric_file, metric_yml, message, results))

View File

@ -4,11 +4,11 @@ use std::time::Instant;
use anyhow::{anyhow, Result};
use async_trait::async_trait;
use chrono::Utc;
use database::{models::DashboardFile, pool::get_pg_pool, schema::dashboard_files};
use database::{models::DashboardFile, pool::get_pg_pool, schema::dashboard_files, types::VersionHistory};
use diesel::insert_into;
use diesel_async::RunQueryDsl;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use serde_json::{self, json, Value};
use tracing::debug;
use uuid::Uuid;
@ -19,10 +19,7 @@ use crate::{
use super::{
common::{generate_deterministic_uuid, validate_metric_ids},
file_types::{
dashboard_yml::DashboardYml,
file::{FileWithId},
},
file_types::{dashboard_yml::DashboardYml, file::FileWithId},
FileModificationTool,
};
@ -95,12 +92,16 @@ async fn process_dashboard_file(
}
}
let dashboard_yml_json = match serde_json::to_value(dashboard_yml.clone()) {
Ok(json) => json,
Err(e) => return Err(format!("Failed to process dashboard: {}", e)),
};
let dashboard_file = DashboardFile {
id: dashboard_id,
name: dashboard_yml.name.clone(),
file_name: file.name.clone(),
content: serde_json::to_value(dashboard_yml.clone())
.map_err(|e| format!("Failed to process dashboard: {}", e))?,
content: dashboard_yml_json.clone(),
filter: None,
organization_id: Uuid::new_v4(),
created_by: Uuid::new_v4(),
@ -110,6 +111,7 @@ async fn process_dashboard_file(
publicly_accessible: false,
publicly_enabled_by: None,
public_expiry_date: None,
version_history: VersionHistory::new(1, dashboard_yml_json),
};
Ok((dashboard_file, dashboard_yml))

View File

@ -4,5 +4,6 @@ pub mod models;
pub mod schema;
pub mod vault;
pub mod helpers;
pub mod types;
pub use helpers::*;

View File

@ -5,6 +5,7 @@ use diesel::prelude::*;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use uuid::Uuid;
use crate::types::VersionHistory;
#[derive(Queryable, Insertable, Identifiable, Associations, Debug)]
#[diesel(belongs_to(User, foreign_key = owner_id))]
@ -35,6 +36,7 @@ pub struct DashboardFile {
pub publicly_accessible: bool,
pub publicly_enabled_by: Option<Uuid>,
pub public_expiry_date: Option<DateTime<Utc>>,
pub version_history: VersionHistory,
}
#[derive(Queryable, Insertable, Identifiable, Associations, Debug, Clone, Serialize)]
@ -85,6 +87,7 @@ pub struct MetricFile {
pub publicly_accessible: bool,
pub publicly_enabled_by: Option<Uuid>,
pub public_expiry_date: Option<DateTime<Utc>>,
pub version_history: VersionHistory,
}
#[derive(Queryable, Insertable, Identifiable, Associations, Debug, Clone, Serialize)]

View File

@ -143,6 +143,7 @@ diesel::table! {
publicly_accessible -> Bool,
publicly_enabled_by -> Nullable<Uuid>,
public_expiry_date -> Nullable<Timestamptz>,
version_history -> Jsonb,
}
}
@ -399,6 +400,7 @@ diesel::table! {
publicly_accessible -> Bool,
publicly_enabled_by -> Nullable<Uuid>,
public_expiry_date -> Nullable<Timestamptz>,
version_history -> Jsonb,
}
}

View File

@ -0,0 +1,67 @@
use std::io::Write;
use diesel::{
deserialize::FromSql,
pg::Pg,
serialize::{IsNull, Output, ToSql},
sql_types::Jsonb,
AsExpression, FromSqlRow,
};
use serde::{Deserialize, Serialize};
use serde_json::Value;
#[derive(Debug, Serialize, Deserialize, FromSqlRow, AsExpression, Clone)]
#[diesel(sql_type = Jsonb)]
#[serde(transparent)]
pub struct VersionHistory(pub std::collections::HashMap<String, Version>);
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Version {
pub version_number: i32,
pub content: Value,
}
impl VersionHistory {
pub fn new(version_number: i32, content: Value) -> Self {
Self(std::collections::HashMap::from([(
version_number.to_string(),
Version {
content,
version_number,
},
)]))
}
pub fn add_version(&mut self, version_number: i32, content: Value) {
self.0.insert(
version_number.to_string(),
Version {
content,
version_number,
},
);
}
pub fn get_version(&self, version_number: i32) -> Option<&Version> {
self.0.get(&version_number.to_string())
}
pub fn get_latest_version(&self) -> Option<&Version> {
self.0.values().max_by_key(|v| v.version_number)
}
}
impl FromSql<Jsonb, Pg> for VersionHistory {
fn from_sql(bytes: diesel::pg::PgValue) -> diesel::deserialize::Result<Self> {
let value = <serde_json::Value as FromSql<Jsonb, Pg>>::from_sql(bytes)?;
Ok(serde_json::from_value(value)?)
}
}
impl ToSql<Jsonb, Pg> for VersionHistory {
fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Pg>) -> diesel::serialize::Result {
out.write_all(&[1])?; // JSONB version 1 header
out.write_all(&serde_json::to_vec(self)?)?;
Ok(IsNull::No)
}
}

View File

@ -1,12 +1,10 @@
use anyhow::{anyhow, Result};
use diesel::{
ExpressionMethods, NullableExpressionMethods, QueryDsl, Queryable, Selectable, SelectableHelper,
};
use database::types::VersionHistory;
use diesel::{ExpressionMethods, QueryDsl, Queryable, Selectable, SelectableHelper};
use diesel_async::RunQueryDsl;
use serde_json::{json, Value};
use serde_json::Value;
use serde_yaml;
use uuid::Uuid;
use middleware::AuthenticatedUser;
use crate::metrics::types::{
BusterMetric, ColumnMetaData, ColumnType, DataMetadata, Dataset, MinMaxValue, SimpleType,
@ -14,7 +12,7 @@ use crate::metrics::types::{
use agents::tools::file_tools::file_types::metric_yml::MetricYml;
use database::enums::Verification;
use database::pool::get_pg_pool;
use database::schema::{datasets, metric_files, users};
use database::schema::{datasets, metric_files};
#[derive(Queryable, Selectable)]
#[diesel(table_name = metric_files)]
@ -30,6 +28,7 @@ struct QueryableMetricFile {
created_by: Uuid,
created_at: chrono::DateTime<chrono::Utc>,
updated_at: chrono::DateTime<chrono::Utc>,
version_history: VersionHistory,
}
#[derive(Queryable)]
@ -70,6 +69,7 @@ pub async fn get_metric_handler(metric_id: &Uuid, user_id: &Uuid) -> Result<Bust
metric_files::created_by,
metric_files::created_at,
metric_files::updated_at,
metric_files::version_history,
))
.first::<QueryableMetricFile>(&mut conn)
.await
@ -180,5 +180,6 @@ pub async fn get_metric_handler(metric_id: &Uuid, user_id: &Uuid) -> Result<Bust
code: None,
dashboards: vec![], // TODO: Get associated dashboards
collections: vec![], // TODO: Get associated collections
versions: metric_file.version_history,
})
}

View File

@ -1,4 +1,4 @@
use database::enums::Verification;
use database::{enums::Verification, types::VersionHistory};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::collections::HashMap;
@ -9,6 +9,12 @@ pub struct Dataset {
pub id: String,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Version {
pub version_number: i32,
pub updated_at: String,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct BusterMetric {
pub id: String,
@ -36,6 +42,7 @@ pub struct BusterMetric {
pub code: Option<String>,
pub dashboards: Vec<Dashboard>,
pub collections: Vec<Collection>,
pub versions: VersionHistory,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
@ -133,4 +140,4 @@ pub enum DataValue {
String(String),
Number(f64),
Null,
}
}

View File

@ -26,3 +26,11 @@ ALTER TABLE dashboard_files
ADD COLUMN publicly_accessible boolean NOT NULL DEFAULT false,
ADD COLUMN publicly_enabled_by uuid NULL REFERENCES users(id),
ADD COLUMN public_expiry_date timestamp with time zone NULL;
-- Add version_history column to metric_files table
ALTER TABLE metric_files
ADD COLUMN version_history JSONB NOT NULL DEFAULT '{}'::jsonb;
-- Add version_history column to dashboard_files table
ALTER TABLE dashboard_files
ADD COLUMN version_history JSONB NOT NULL DEFAULT '{}'::jsonb;