mod analysis;
mod render;
use candid::Decode;
use icydb::db::EntitySchemaCheckDescription;
use crate::{
cli::CanisterTarget,
config::{SCHEMA_CHECK_ENDPOINT, require_configured_endpoint},
icp::require_created_canister,
};
use self::{analysis::analyze_schema_check, render::render_schema_check_report_from_summary};
use super::call_query;
pub(crate) fn run_schema_check_command(target: CanisterTarget) -> Result<(), String> {
require_configured_endpoint(target.canister_name(), SCHEMA_CHECK_ENDPOINT)?;
require_created_canister(target.environment(), target.canister_name())?;
let candid_bytes = call_query(
target.environment(),
target.canister_name(),
SCHEMA_CHECK_ENDPOINT.method(),
"()",
)?;
let response = Decode!(
candid_bytes.as_slice(),
Result<Vec<icydb::db::EntitySchemaCheckDescription>, icydb::Error>
)
.map_err(|err| err.to_string())?;
match response {
Ok(report) => {
print!("{}", render_schema_check_report(report.as_slice()));
let summary = analyze_schema_check(report.as_slice());
if summary.mismatches == 0 {
Ok(())
} else {
Err(format!(
"IcyDB schema check found {} mismatch(es) on canister '{}' in environment '{}'",
summary.mismatches,
target.canister_name(),
target.environment(),
))
}
}
Err(err) => Err(format!(
"IcyDB schema check method '{}' failed on canister '{}' in environment '{}': {err}",
SCHEMA_CHECK_ENDPOINT.method(),
target.canister_name(),
target.environment(),
)),
}
}
pub(crate) fn render_schema_check_report(report: &[EntitySchemaCheckDescription]) -> String {
let summary = analyze_schema_check(report);
render_schema_check_report_from_summary(&summary)
}