use std::collections::BTreeMap;
use std::path::PathBuf;
use schemars::JsonSchema;
use serde::Serialize;
use crate::codes::{Code, ErrorCode, Kind};
use crate::settings::Settings;
type JsonMap = serde_json::Map<String, serde_json::Value>;
pub const SCHEMA_VERSION: &str = "dre/run-results/v1";
#[derive(Debug, Clone, Serialize, JsonSchema)]
#[schemars(title = "DRE run results")]
pub struct RunResults {
#[schemars(schema_with = "schema_version")]
pub schema_version: &'static str,
pub run_id: String,
pub report: String,
pub set: Option<String>,
pub binding: String,
pub managed: bool,
pub profile: Option<String>,
pub connections: Vec<String>,
pub target: String,
pub schedule: Option<String>,
pub schedule_vars: Option<JsonMap>,
pub vars: JsonMap,
pub run_date: String,
pub scheduled_at: Option<String>,
pub timezone: String,
pub params: Params,
pub status: Status,
pub error: Option<String>,
pub error_code: Option<ErrorCode>,
pub error_kind: Option<Kind>,
pub preview: bool,
pub row_limit: Option<u64>,
pub started_at: String,
pub duration_ms: u64,
pub result_sets: Vec<ResultSet>,
pub outputs: Vec<OutputFile>,
pub output_results: Vec<OutputResult>,
pub delivery: Option<String>,
pub deliveries: Vec<Delivery>,
pub schema_drift: Vec<String>,
pub target_path: PathBuf,
#[schemars(schema_with = "settings")]
pub settings: Settings,
pub manifest_checksum: Option<String>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum Status {
Success,
Error,
DryRun,
Checked,
Cancelled,
TimedOut,
}
#[derive(Debug, Clone, Serialize, JsonSchema)]
pub struct Params {
pub selector: Option<String>,
pub set: Option<String>,
pub schedule: Option<String>,
pub target: Option<String>,
pub profile: Option<String>,
pub vars: BTreeMap<String, String>,
pub run_date: String,
pub scheduled_at: Option<String>,
pub timezone: Option<String>,
pub output_name: Option<String>,
pub output_path: Option<String>,
pub dry_run: bool,
pub preview: Option<u64>,
pub accept_schema_change: bool,
}
#[derive(Debug, Clone, Serialize, JsonSchema)]
pub struct ResultSet {
pub name: String,
pub query: String,
pub connection: String,
pub rows: u64,
pub columns: Vec<String>,
}
#[derive(Debug, Clone, Serialize, JsonSchema)]
pub struct OutputFile {
pub path: PathBuf,
pub size: u64,
pub delivered_to: Option<String>,
pub output: Option<String>,
}
#[derive(Debug, Clone, Serialize, JsonSchema)]
pub struct OutputResult {
pub name: Option<String>,
pub format: String,
pub queries: Vec<String>,
#[schemars(schema_with = "output_status")]
pub status: &'static str,
pub error: Option<String>,
pub files: Vec<OutputFileRef>,
pub delivery: Option<String>,
pub deliveries: Vec<Delivery>,
#[serde(skip_serializing_if = "Option::is_none")]
pub when: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub message: Option<Message>,
}
#[derive(Debug, Clone, Serialize, JsonSchema)]
pub struct OutputFileRef {
pub path: PathBuf,
pub size: u64,
pub delivered_to: Option<String>,
}
#[derive(Debug, Clone, Serialize, JsonSchema)]
pub struct Message {
pub title: String,
pub text: String,
}
#[derive(Debug, Clone, Serialize, JsonSchema)]
pub struct Delivery {
pub profile: String,
#[serde(rename = "type")]
pub kind: Option<String>,
pub target: String,
#[schemars(schema_with = "delivery_status")]
pub status: &'static str,
#[serde(skip_serializing_if = "Option::is_none")]
pub location: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub attempts: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub error: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub error_code: Option<ErrorCode>,
}
fn schema_version(_: &mut schemars::SchemaGenerator) -> schemars::Schema {
schemars::json_schema!({"const": SCHEMA_VERSION})
}
fn output_status(_: &mut schemars::SchemaGenerator) -> schemars::Schema {
schemars::json_schema!({"enum": ["delivered", "kept", "skipped", "failed"]})
}
fn delivery_status(_: &mut schemars::SchemaGenerator) -> schemars::Schema {
schemars::json_schema!({"enum": ["delivered", "not_delivered", "failed"]})
}
fn settings(_: &mut schemars::SchemaGenerator) -> schemars::Schema {
schemars::json_schema!({
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {"type": "string"},
"value": {"type": ["string", "null"]},
"source": {"type": "string", "description": "A flag (`--target`), an environment variable (`DRE_TARGET`), a dre_project.yml key, how it was found, or `default`."}
},
"required": ["name", "value", "source"]
},
"x-dre-null": true
})
}
impl JsonSchema for Code {
fn schema_name() -> std::borrow::Cow<'static, str> {
"Code".into()
}
fn json_schema(_: &mut schemars::SchemaGenerator) -> schemars::Schema {
schemars::json_schema!({"type": "string", "description": "A code from the error codes reference, e.g. `query-failed`."})
}
fn inline_schema() -> bool {
true
}
}
impl JsonSchema for ErrorCode {
fn schema_name() -> std::borrow::Cow<'static, str> {
"ErrorCode".into()
}
fn json_schema(_: &mut schemars::SchemaGenerator) -> schemars::Schema {
schemars::json_schema!({"type": "string", "description": "A code from the error codes reference, e.g. `query-failed`, or a plugin's own, namespaced by the plugin, e.g. `sftp/host-key-mismatch`."})
}
fn inline_schema() -> bool {
true
}
}
impl JsonSchema for Kind {
fn schema_name() -> std::borrow::Cow<'static, str> {
"Kind".into()
}
fn json_schema(_: &mut schemars::SchemaGenerator) -> schemars::Schema {
schemars::json_schema!({"enum": ["usage", "config", "plugin", "refused", "connection", "auth", "query", "delivery", "internal", "cancelled", "timed_out"]})
}
fn inline_schema() -> bool {
true
}
}