JSONB on table scripts also now
This commit is contained in:
@@ -45,6 +45,14 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
".komp_ac.table_definition.TableDefinitionResponse",
|
||||
"#[derive(serde::Serialize, serde::Deserialize)]"
|
||||
)
|
||||
.type_attribute(
|
||||
".komp_ac.table_script.PostTableScriptRequest",
|
||||
"#[derive(serde::Serialize, serde::Deserialize)]",
|
||||
)
|
||||
.type_attribute(
|
||||
".komp_ac.table_script.TableScriptResponse",
|
||||
"#[derive(serde::Serialize, serde::Deserialize)]",
|
||||
)
|
||||
.compile_protos(
|
||||
&[
|
||||
"proto/common.proto",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// This file is @generated by prost-build.
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct PostTableScriptRequest {
|
||||
#[prost(int64, tag = "1")]
|
||||
@@ -10,6 +11,7 @@ pub struct PostTableScriptRequest {
|
||||
#[prost(string, tag = "4")]
|
||||
pub description: ::prost::alloc::string::String,
|
||||
}
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct TableScriptResponse {
|
||||
#[prost(int64, tag = "1")]
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
// src/table_script/mod.rs
|
||||
|
||||
pub mod handlers;
|
||||
pub mod repo;
|
||||
|
||||
pub use handlers::*;
|
||||
pub use repo::*;
|
||||
|
||||
49
server/src/table_script/repo.rs
Normal file
49
server/src/table_script/repo.rs
Normal 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)
|
||||
}
|
||||
Reference in New Issue
Block a user