athena_rs 3.23.0

Hyper performant polyglot Database driver
Documentation
//! Athena management-schema adapters for outbound webhook events.
//!
//! The canonical route keys live in `athena-webhooks`; this module keeps the
//! `AppState` and management-operation wiring local to `athena_rs`.

use actix_web::HttpRequest;
use actix_web::web::Data;
use serde_json::{Value, json};

pub use athena_webhooks::schema::{
    ROUTE_SCHEMA_COLUMN_ADDED, ROUTE_SCHEMA_COLUMN_ALTERED, ROUTE_SCHEMA_COLUMN_DROPPED,
    ROUTE_SCHEMA_COLUMN_RENAMED, ROUTE_SCHEMA_EXTENSION_INSTALLED, ROUTE_SCHEMA_INDEX_CREATED,
    ROUTE_SCHEMA_INDEX_DROPPED, ROUTE_SCHEMA_TABLE_CREATED, ROUTE_SCHEMA_TABLE_DROPPED,
    ROUTE_SCHEMA_VIEW_CREATED, ROUTE_SCHEMA_VIEW_DROPPED,
};

use crate::AppState;
use crate::api::management::types::TableEditOperation;

use super::{gateway_webhook_trigger_from_http, spawn_gateway_webhook_dispatch};

/// Fires a webhook after a successful management mutation on a client database.
pub fn spawn_management_schema_webhook(
    app_state: Data<AppState>,
    req: &HttpRequest,
    client_name: &str,
    request_id: Option<String>,
    route_key: &str,
    table_name: Option<String>,
    payload: Value,
    response: Value,
) {
    spawn_gateway_webhook_dispatch(
        app_state,
        gateway_webhook_trigger_from_http(
            req,
            client_name,
            route_key,
            table_name,
            request_id,
            Some(payload),
            Some(response),
        ),
    );
}

fn push_column_altered(
    out: &mut Vec<(&'static str, Value)>,
    schema_name: &str,
    table_name: &str,
    resource_suffix: &str,
    op: &TableEditOperation,
) {
    let rid: String = format!("{}.{}{}", schema_name, table_name, resource_suffix);
    out.push((
        ROUTE_SCHEMA_COLUMN_ALTERED,
        json!({
            "schema_name": schema_name,
            "table_name": table_name,
            "resource_id": rid,
            "operation": serde_json::to_value(op).unwrap_or(json!({})),
        }),
    ));
}

/// Maps each management `TableEditOperation` to one outbound webhook event.
pub fn schema_webhooks_for_edit_operations(
    schema_name: &str,
    table_name: &str,
    operations: &[TableEditOperation],
) -> Vec<(&'static str, Value)> {
    let mut out: Vec<(&'static str, Value)> = Vec::with_capacity(operations.len());
    for op in operations {
        match op {
            TableEditOperation::AddColumn { column } => {
                let rid: String = format!("{}.{}.column:{}", schema_name, table_name, column.name);
                out.push((
                    ROUTE_SCHEMA_COLUMN_ADDED,
                    json!({
                        "schema_name": schema_name,
                        "table_name": table_name,
                        "resource_id": rid,
                        "column": column,
                    }),
                ));
            }
            TableEditOperation::RenameColumn { from, to } => {
                let rid: String = format!("{}.{}.rename:{}->{}", schema_name, table_name, from, to);
                out.push((
                    ROUTE_SCHEMA_COLUMN_RENAMED,
                    json!({
                        "schema_name": schema_name,
                        "table_name": table_name,
                        "resource_id": rid,
                        "from": from,
                        "to": to,
                    }),
                ));
            }
            TableEditOperation::SetDefault { column_name, .. } => {
                push_column_altered(
                    &mut out,
                    schema_name,
                    table_name,
                    &format!(".set_default:{column_name}"),
                    op,
                );
            }
            TableEditOperation::DropDefault { column_name } => {
                push_column_altered(
                    &mut out,
                    schema_name,
                    table_name,
                    &format!(".drop_default:{column_name}"),
                    op,
                );
            }
            TableEditOperation::SetNotNull { column_name } => {
                push_column_altered(
                    &mut out,
                    schema_name,
                    table_name,
                    &format!(".set_not_null:{column_name}"),
                    op,
                );
            }
            TableEditOperation::DropNotNull { column_name } => {
                push_column_altered(
                    &mut out,
                    schema_name,
                    table_name,
                    &format!(".drop_not_null:{column_name}"),
                    op,
                );
            }
        }
    }
    out
}