JSONB on table scripts also now

This commit is contained in:
Priec
2025-09-18 10:47:01 +02:00
parent 73bc6dc99c
commit 7350b0985c
5 changed files with 89 additions and 6 deletions

View File

@@ -2,6 +2,7 @@
use std::collections::HashMap;
use tonic::Status;
use serde::{Deserialize, Serialize};
use serde_json::{json, Value};
/// Represents the state of a node during dependency graph traversal.
@@ -40,18 +41,38 @@ impl DependencyType {
DependencyType::SqlQuery { .. } => "sql_query",
}
}
}
/// Generates context JSON for database storage.
pub fn context_json(&self) -> Value {
/// Strongly-typed JSON for script_dependencies.context_info
/// Using untagged so JSON stays minimal (no "type" field), and we can still
/// deserialize it into a proper enum.
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum ScriptDependencyContext {
ColumnAccess { column: String },
IndexedAccess { column: String, index: i64 },
SqlQuery { query_fragment: String },
}
impl DependencyType {
/// Convert this dependency into its JSON context struct.
pub fn to_context(&self) -> ScriptDependencyContext {
match self {
DependencyType::ColumnAccess { column } => {
json!({ "column": column })
ScriptDependencyContext::ColumnAccess {
column: column.clone(),
}
}
DependencyType::IndexedAccess { column, index } => {
json!({ "column": column, "index": index })
ScriptDependencyContext::IndexedAccess {
column: column.clone(),
index: *index,
}
}
DependencyType::SqlQuery { query_fragment } => {
json!({ "query_fragment": query_fragment })
ScriptDependencyContext::SqlQuery {
query_fragment: query_fragment.clone(),
}
}
}
}
@@ -554,7 +575,7 @@ impl DependencyAnalyzer {
table_id,
target_id,
dep.dependency_type.as_str(),
dep.dependency_type.context_json()
serde_json::to_value(dep.dependency_type.to_context()).unwrap()
)
.execute(&mut **tx)
.await

View File

@@ -1,4 +1,7 @@
// src/table_script/mod.rs
pub mod handlers;
pub mod repo;
pub use handlers::*;
pub use repo::*;

View File

@@ -0,0 +1,49 @@
// src/table_script/repo.rs
use anyhow::Result;
use sqlx::PgPool;
use crate::table_script::handlers::dependency_analyzer::ScriptDependencyContext;
#[derive(Debug, Clone)]
pub struct ScriptDependencyRecord {
pub script_id: i64,
pub source_table_id: i64,
pub target_table_id: i64,
pub dependency_type: String,
pub context: Option<ScriptDependencyContext>,
}
pub async fn get_dependencies_for_script(
db: &PgPool,
script_id: i64,
) -> Result<Vec<ScriptDependencyRecord>> {
let rows = sqlx::query!(
r#"
SELECT script_id, source_table_id, target_table_id, dependency_type, context_info
FROM script_dependencies
WHERE script_id = $1
ORDER BY source_table_id, target_table_id
"#,
script_id
)
.fetch_all(db)
.await?;
let mut out = Vec::new();
for r in rows {
let context = match r.context_info {
Some(value) => Some(serde_json::from_value::<ScriptDependencyContext>(value)?),
None => None,
};
out.push(ScriptDependencyRecord {
script_id: r.script_id,
source_table_id: r.source_table_id,
target_table_id: r.target_table_id,
dependency_type: r.dependency_type,
context,
});
}
Ok(out)
}