1002 char *manifest_path = NULL;
1003 char *migration_fixture_rel = NULL;
1004 char *entity_fixture_rel = NULL;
1005 char *query_fixture_rel = NULL;
1006 char *migration_fixture = NULL;
1007 char *entity_fixture = NULL;
1008 char *query_fixture = NULL;
1009 char *preferred_backend_json = NULL;
1010 char *development_backend_json = NULL;
1011 char *testing_backend_json = NULL;
1012 char *schema_version_json = NULL;
1013 char *required_tables_json = NULL;
1014 char *required_migration_ids_json = NULL;
1015 char *seed_expectations_json = NULL;
1016 char *verification_contract_json = NULL;
1017 char *sqlite_db_path = NULL;
1018 char *sqlite_db_path_json = NULL;
1019 char *target_id_json = NULL;
1020 char *migration_fixture_json = NULL;
1021 char *entity_fixture_json = NULL;
1022 char *query_fixture_json = NULL;
1023 char *db_config_json = NULL;
1024 char *result = NULL;
1025 char *status_json = NULL;
1026 char *table_checks_json = NULL;
1027 char *seed_checks_json = NULL;
1028 char *migration_checks_json = NULL;
1029 char *missing_tables_json = NULL;
1030 char *missing_migrations_json = NULL;
1031 char *drifted_migrations_json = NULL;
1032 char *failed_seed_expectations_json = NULL;
1037 Buffer missing_migrations;
1038 Buffer drifted_migrations;
1039 Buffer failed_seed_expectations;
1040 int first_table = 1;
1042 int first_migration = 1;
1043 int first_missing_table = 1;
1044 int first_missing_migration = 1;
1045 int first_drifted_migration = 1;
1046 int first_failed_seed = 1;
1047 int database_present = 0;
1048 int ledger_table_present = 0;
1050 const char *verification_status =
"verification_failed";
1063 long schema_version = 0;
1065 if (status_out != NULL) {
1068 if (error_out != NULL) {
1071 if (config == NULL || app == NULL || app->
app_root == NULL ||
1088 if (manifest_path == NULL || !
path_exists(manifest_path)) {
1092 if (manifest_doc == NULL) {
1097 if (database_obj == NULL) {
1101 migration_fixture_rel =
1106 if (migration_fixture_rel == NULL) {
1111 entity_fixture = entity_fixture_rel != NULL
1114 query_fixture = query_fixture_rel != NULL
1117 if (migration_fixture == NULL || !
path_exists(migration_fixture)) {
1122 if (migration_doc == NULL) {
1129 required_migration_ids =
1134 preferred_backend_json =
1137 development_backend_json =
1140 testing_backend_json =
1147 required_migration_ids_json =
1149 seed_expectations_json =
1151 verification_contract_json =
1156 database_present = sqlite_db_path != NULL &&
path_exists(sqlite_db_path);
1157 ledger_table_present =
1161 if (required_tables != NULL) {
1168 const char *table_name = NULL;
1170 char *table_json = NULL;
1171 char *item_json = NULL;
1180 item_needed = (table_json != NULL ? strlen(table_json) : 0) + 96;
1181 item_json = (
char *)malloc(item_needed);
1182 if (table_json == NULL || item_json == NULL) {
1187 snprintf(item_json, item_needed,
1188 "{\"table\":%s,\"exists\":%s,\"status\":\"%s\"}",
1189 table_json, exists ?
"true" :
"false",
1190 exists ?
"ok" :
"missing_table");
1198 &first_missing_table) != 0) {
1208 if (seed_expectations != NULL) {
1215 char *table_name = NULL;
1216 char *table_json = NULL;
1217 char *item_json = NULL;
1218 long minimum_rows = 0;
1219 long exact_rows = 0;
1220 int minimum_present = 0;
1221 int exact_present = 0;
1222 int table_exists = 0;
1225 const char *reason =
"missing_table";
1226 char minimum_buf[64];
1238 if (table_name != NULL && database_present) {
1243 row_count, minimum_present, minimum_rows, exact_present, exact_rows,
1248 snprintf(minimum_buf,
sizeof(minimum_buf),
"%ld", minimum_rows);
1249 snprintf(exact_buf,
sizeof(exact_buf),
"%ld", exact_rows);
1250 item_needed = (table_json != NULL ? strlen(table_json) : 0) +
1251 strlen(reason) + 192;
1252 item_json = (
char *)malloc(item_needed);
1253 if (table_json == NULL || item_json == NULL) {
1259 snprintf(item_json, item_needed,
1260 "{\"table\":%s,\"table_exists\":%s,\"row_count\":%ld,"
1261 "\"minimum_rows\":%s,\"exact_rows\":%s,\"satisfied\":%s,"
1262 "\"reason\":\"%s\"}",
1263 table_json, table_exists ?
"true" :
"false", row_count,
1264 minimum_present ? minimum_buf :
"null",
1265 exact_present ? exact_buf :
"null",
1266 satisfied ?
"true" :
"false", reason);
1274 &first_failed_seed) == NULL) {
1286 if (required_migration_ids != NULL) {
1293 const char *migration_id = NULL;
1295 yyjson_val *accepted_legacy_checksums = NULL;
1296 char *migration_json = NULL;
1297 char *schema_json = NULL;
1298 char *applied_schema_json = NULL;
1299 char *expected_checksum = NULL;
1300 char *legacy_expected_checksum = NULL;
1301 char *applied_checksum = NULL;
1302 char *accepted_legacy_checksums_json = NULL;
1303 char *item_json = NULL;
1304 long applied_count = 0;
1306 int checksum_match = 0;
1307 long migration_schema_version = 0;
1319 migration_record,
"schema_version", 0, NULL);
1322 accepted_legacy_checksums_json =
1325 app->
app_root, migration_record, NULL, NULL,
"sqlite");
1327 app->
app_root, migration_record, entity_fixture, query_fixture,
"sqlite",
1330 if (ledger_table_present) {
1334 applied = applied_count > 0;
1336 sqlite_db_path, migration_id,
"sqlite");
1338 sqlite_db_path, migration_id,
"sqlite");
1340 applied, applied_checksum, expected_checksum, legacy_expected_checksum,
1341 accepted_legacy_checksums);
1344 item_needed = (migration_json != NULL ? strlen(migration_json) : 0) +
1345 (schema_json != NULL ? strlen(schema_json) : 1) +
1346 (applied_schema_json != NULL ? strlen(applied_schema_json) : 4) +
1347 (expected_checksum != NULL ? strlen(expected_checksum) : 0) +
1348 (legacy_expected_checksum != NULL
1349 ? strlen(legacy_expected_checksum)
1351 (applied_checksum != NULL ? strlen(applied_checksum) : 0) +
1352 (accepted_legacy_checksums_json != NULL
1353 ? strlen(accepted_legacy_checksums_json)
1356 item_json = (
char *)malloc(item_needed);
1357 if (migration_json == NULL || schema_json == NULL ||
1358 accepted_legacy_checksums_json == NULL || item_json == NULL) {
1359 free(migration_json);
1361 free(applied_schema_json);
1362 free(expected_checksum);
1363 free(legacy_expected_checksum);
1364 free(applied_checksum);
1365 free(accepted_legacy_checksums_json);
1370 char *expected_json =
1373 legacy_expected_checksum != NULL ? legacy_expected_checksum :
"");
1374 char *applied_checksum_json =
1375 applied_checksum != NULL && applied_checksum[0] !=
'\0'
1378 if (expected_json == NULL || legacy_json == NULL ||
1379 applied_checksum_json == NULL) {
1380 free(expected_json);
1382 free(applied_checksum_json);
1383 free(migration_json);
1385 free(applied_schema_json);
1386 free(expected_checksum);
1387 free(legacy_expected_checksum);
1388 free(applied_checksum);
1389 free(accepted_legacy_checksums_json);
1393 snprintf(item_json, item_needed,
1394 "{\"migration_id\":%s,\"backend\":\"sqlite\","
1395 "\"schema_version\":%s,\"applied\":%s,"
1396 "\"applied_count\":%ld,\"applied_schema_version\":%s,"
1397 "\"expected_checksum\":%s,"
1398 "\"legacy_expected_checksum\":%s,"
1399 "\"accepted_legacy_checksums\":%s,"
1400 "\"applied_checksum\":%s,\"checksum_match\":%s}",
1401 migration_json, schema_json, applied ?
"true" :
"false",
1403 applied_schema_json != NULL && applied_schema_json[0] !=
'\0'
1404 ? applied_schema_json
1406 expected_json, legacy_json, accepted_legacy_checksums_json,
1407 applied_checksum_json, checksum_match ?
"true" :
"false");
1408 free(expected_json);
1410 free(applied_checksum_json);
1414 free(migration_json);
1416 free(applied_schema_json);
1417 free(expected_checksum);
1418 free(legacy_expected_checksum);
1419 free(applied_checksum);
1420 free(accepted_legacy_checksums_json);
1426 &first_missing_migration) != 0) {
1427 free(migration_json);
1429 free(applied_schema_json);
1430 free(expected_checksum);
1431 free(legacy_expected_checksum);
1432 free(applied_checksum);
1433 free(accepted_legacy_checksums_json);
1437 if (applied && !checksum_match &&
1439 &first_drifted_migration) != 0) {
1440 free(migration_json);
1442 free(applied_schema_json);
1443 free(expected_checksum);
1444 free(legacy_expected_checksum);
1445 free(applied_checksum);
1446 free(accepted_legacy_checksums_json);
1450 free(migration_json);
1452 free(applied_schema_json);
1453 free(expected_checksum);
1454 free(legacy_expected_checksum);
1455 free(applied_checksum);
1456 free(accepted_legacy_checksums_json);
1465 missing_migrations_json =
1467 drifted_migrations_json =
1469 failed_seed_expectations_json =
1471 if (table_checks_json == NULL || seed_checks_json == NULL ||
1472 migration_checks_json == NULL || missing_tables_json == NULL ||
1473 missing_migrations_json == NULL || drifted_migrations_json == NULL ||
1474 failed_seed_expectations_json == NULL) {
1478 verified = database_present && ledger_table_present &&
1479 streq(missing_tables_json,
"[]") &&
1480 streq(missing_migrations_json,
"[]") &&
1481 streq(drifted_migrations_json,
"[]") &&
1482 streq(failed_seed_expectations_json,
"[]");
1483 verification_status = verified ?
"verified" :
"verification_failed";
1484 if (status_out != NULL) {
1497 needed = (target_id_json != NULL ? strlen(target_id_json) : 0) +
1498 (status_json != NULL ? strlen(status_json) : 0) +
1499 (preferred_backend_json != NULL ? strlen(preferred_backend_json) : 8) +
1500 (development_backend_json != NULL ? strlen(development_backend_json) : 8) +
1501 (testing_backend_json != NULL ? strlen(testing_backend_json) : 8) +
1502 (schema_version_json != NULL ? strlen(schema_version_json) : 1) +
1503 (required_tables_json != NULL ? strlen(required_tables_json) : 2) +
1504 (required_migration_ids_json != NULL
1505 ? strlen(required_migration_ids_json)
1507 (seed_expectations_json != NULL ? strlen(seed_expectations_json) : 2) +
1508 (verification_contract_json != NULL
1509 ? strlen(verification_contract_json)
1511 (sqlite_db_path_json != NULL ? strlen(sqlite_db_path_json) : 0) +
1512 (migration_fixture_json != NULL ? strlen(migration_fixture_json) : 0) +
1513 (entity_fixture_json != NULL ? strlen(entity_fixture_json) : 4) +
1514 (query_fixture_json != NULL ? strlen(query_fixture_json) : 4) +
1515 (db_config_json != NULL ? strlen(db_config_json) : 20) +
1516 (table_checks_json != NULL ? strlen(table_checks_json) : 2) +
1517 (missing_tables_json != NULL ? strlen(missing_tables_json) : 2) +
1518 (seed_checks_json != NULL ? strlen(seed_checks_json) : 2) +
1519 (failed_seed_expectations_json != NULL
1520 ? strlen(failed_seed_expectations_json)
1522 (migration_checks_json != NULL ? strlen(migration_checks_json) : 2) +
1523 (missing_migrations_json != NULL ? strlen(missing_migrations_json) : 2) +
1524 (drifted_migrations_json != NULL ? strlen(drifted_migrations_json) : 2) +
1526 result = (
char *)malloc(needed);
1527 if (result != NULL) {
1528 snprintf(result, needed,
1529 "{\"report_id\":\"pharos-migrate-verify-v1\","
1530 "\"target_kind\":\"app\",\"target_id\":%s,"
1531 "\"backend\":\"sqlite\",\"status\":%s,"
1532 "\"live_database_verified\":%s,"
1533 "\"database_present\":%s,\"ledger_table_present\":%s,"
1534 "\"db_path\":%s,\"schema_version\":%s,"
1535 "\"preferred_backend\":%s,\"development_backend\":%s,"
1536 "\"testing_backend\":%s,\"migration_fixture\":%s,"
1537 "\"entity_fixture\":%s,\"query_fixture\":%s,"
1538 "\"db_config\":%s,\"verification_contract\":%s,"
1539 "\"required_tables\":%s,\"required_migration_ids\":%s,"
1540 "\"seed_expectations\":%s,\"table_checks\":%s,"
1541 "\"missing_tables\":%s,\"seed_checks\":%s,"
1542 "\"failed_seed_expectations\":%s,\"migration_checks\":%s,"
1543 "\"missing_migrations\":%s,\"drifted_migrations\":%s}",
1545 status_json != NULL ? status_json :
"\"verification_failed\"",
1546 verified ?
"true" :
"false",
1547 database_present ?
"true" :
"false",
1548 ledger_table_present ?
"true" :
"false",
1549 sqlite_db_path_json != NULL ? sqlite_db_path_json :
"\"\"",
1550 schema_version_json != NULL ? schema_version_json :
"0",
1551 preferred_backend_json != NULL ? preferred_backend_json :
"\"sqlite\"",
1552 development_backend_json != NULL ? development_backend_json :
"\"sqlite\"",
1553 testing_backend_json != NULL ? testing_backend_json :
"\"sqlite\"",
1554 migration_fixture_json != NULL ? migration_fixture_json :
"\"\"",
1555 entity_fixture_json != NULL ? entity_fixture_json :
"null",
1556 query_fixture_json != NULL ? query_fixture_json :
"null",
1557 db_config_json != NULL ? db_config_json :
"{\"backend\":\"sqlite\"}",
1558 verification_contract_json != NULL ? verification_contract_json :
"{}",
1559 required_tables_json != NULL ? required_tables_json :
"[]",
1560 required_migration_ids_json != NULL ? required_migration_ids_json :
"[]",
1561 seed_expectations_json != NULL ? seed_expectations_json :
"[]",
1562 table_checks_json != NULL ? table_checks_json :
"[]",
1563 missing_tables_json != NULL ? missing_tables_json :
"[]",
1564 seed_checks_json != NULL ? seed_checks_json :
"[]",
1565 failed_seed_expectations_json != NULL ? failed_seed_expectations_json :
"[]",
1566 migration_checks_json != NULL ? migration_checks_json :
"[]",
1567 missing_migrations_json != NULL ? missing_migrations_json :
"[]",
1568 drifted_migrations_json != NULL ? drifted_migrations_json :
"[]");
1572 if (result == NULL) {
1573 char *failure_target_id_json = target_id_json != NULL
1578 char *failure_status_json =
1580 char *failure_db_path_json = sqlite_db_path_json != NULL
1585 char *failure_migration_fixture_json =
1586 migration_fixture_json != NULL
1589 char *failure_entity_fixture_json =
1591 char *failure_query_fixture_json =
1593 char *effective_target_id_json =
1594 target_id_json != NULL ? target_id_json : failure_target_id_json;
1595 char *effective_status_json =
1596 status_json != NULL ? status_json : failure_status_json;
1597 char *effective_db_path_json =
1598 sqlite_db_path_json != NULL ? sqlite_db_path_json : failure_db_path_json;
1599 char *effective_migration_fixture_json =
1600 migration_fixture_json != NULL ? migration_fixture_json : failure_migration_fixture_json;
1601 char *effective_entity_fixture_json =
1602 entity_fixture_json != NULL ? entity_fixture_json : failure_entity_fixture_json;
1603 char *effective_query_fixture_json =
1604 query_fixture_json != NULL ? query_fixture_json : failure_query_fixture_json;
1605 if (status_out != NULL && *status_out == NULL) {
1608 if (error_out != NULL && *error_out == NULL) {
1611 if (effective_target_id_json != NULL && effective_status_json != NULL &&
1612 effective_db_path_json != NULL && effective_migration_fixture_json != NULL &&
1613 effective_entity_fixture_json != NULL && effective_query_fixture_json != NULL) {
1614 size_t failure_needed = strlen(effective_target_id_json) +
1615 strlen(effective_status_json) +
1616 strlen(effective_db_path_json) +
1617 strlen(effective_migration_fixture_json) +
1618 strlen(effective_entity_fixture_json) +
1619 strlen(effective_query_fixture_json) + 2048;
1620 result = (
char *)malloc(failure_needed);
1621 if (result != NULL) {
1622 snprintf(result, failure_needed,
1623 "{\"report_id\":\"pharos-migrate-verify-v1\","
1624 "\"target_kind\":\"app\",\"target_id\":%s,"
1625 "\"backend\":\"sqlite\",\"status\":%s,"
1626 "\"live_database_verified\":false,"
1627 "\"database_present\":%s,\"ledger_table_present\":%s,"
1628 "\"db_path\":%s,\"schema_version\":0,"
1629 "\"preferred_backend\":\"sqlite\","
1630 "\"development_backend\":\"sqlite\","
1631 "\"testing_backend\":\"sqlite\","
1632 "\"migration_fixture\":%s,\"entity_fixture\":%s,"
1633 "\"query_fixture\":%s,\"db_config\":{\"backend\":\"sqlite\"},"
1634 "\"verification_contract\":{},\"required_tables\":[],"
1635 "\"required_migration_ids\":[],\"seed_expectations\":[],"
1636 "\"table_checks\":[],\"missing_tables\":[],"
1637 "\"seed_checks\":[],\"failed_seed_expectations\":[],"
1638 "\"migration_checks\":[],\"missing_migrations\":[],"
1639 "\"drifted_migrations\":[]}",
1640 effective_target_id_json, effective_status_json,
1641 database_present ?
"true" :
"false",
1642 ledger_table_present ?
"true" :
"false",
1643 effective_db_path_json, effective_migration_fixture_json,
1644 effective_entity_fixture_json, effective_query_fixture_json);
1653 free(manifest_path);
1654 free(migration_fixture_rel);
1655 free(entity_fixture_rel);
1656 free(query_fixture_rel);
1657 free(migration_fixture);
1658 free(entity_fixture);
1659 free(query_fixture);
1660 free(preferred_backend_json);
1661 free(development_backend_json);
1662 free(testing_backend_json);
1663 free(schema_version_json);
1664 free(required_tables_json);
1665 free(required_migration_ids_json);
1666 free(seed_expectations_json);
1667 free(verification_contract_json);
1668 free(sqlite_db_path);
1669 free(sqlite_db_path_json);
1670 free(target_id_json);
1671 free(migration_fixture_json);
1672 free(entity_fixture_json);
1673 free(query_fixture_json);
1674 free(db_config_json);
1677 if (table_checks_json != NULL && table_checks_json != table_checks.
data) {
1678 free(table_checks_json);
1680 if (seed_checks_json != NULL && seed_checks_json != seed_checks.
data) {
1681 free(seed_checks_json);
1683 if (migration_checks_json != NULL &&
1684 migration_checks_json != migration_checks.
data) {
1685 free(migration_checks_json);
1687 if (missing_tables_json != NULL && missing_tables_json != missing_tables.
data) {
1688 free(missing_tables_json);
1690 if (missing_migrations_json != NULL &&
1691 missing_migrations_json != missing_migrations.
data) {
1692 free(missing_migrations_json);
1694 if (drifted_migrations_json != NULL &&
1695 drifted_migrations_json != drifted_migrations.
data) {
1696 free(drifted_migrations_json);
1698 if (failed_seed_expectations_json != NULL &&
1699 failed_seed_expectations_json != failed_seed_expectations.
data) {
1700 free(failed_seed_expectations_json);