Support enum headers and other stuff

This commit is contained in:
2026-06-05 12:53:05 -04:00
parent 6bb451dd94
commit b656569fc0
7 changed files with 374 additions and 15 deletions
+13
View File
@@ -135,6 +135,13 @@ cppbessot_enable()
- default: empty
- target schema basename for `db_gen_migrations`
- `CPPBESSOT_GEN_MIGRATION_BACKENDS`
- default: `sqlite;pgsql`
- ODB backends for `db_gen_migrations`
- supported values: `sqlite`, `pgsql`
- `pgsql` writes artifacts under the historical `postgre` output directory
- compatibility alias: `CPPBESSOT_GEN_MIGRATIONS_BACKENDS`
- `DB_SCHEMA_CHANGES_ARE_ERROR`
- default: `OFF`
- used by schema-drift checking logic
@@ -303,6 +310,7 @@ Primary variables:
- `CPPBESSOT_WORKDIR`
- `DB_SCHEMA_DIR_MIGRATION_FROM`
- `DB_SCHEMA_DIR_MIGRATION_TO`
- `CPPBESSOT_GEN_MIGRATION_BACKENDS`
Output:
@@ -313,6 +321,11 @@ Notes:
- `from` and `to` must differ
- if either migration variable is empty, `db_gen_migrations` is still registered but intentionally fails with guidance
- enum-only generated C++ headers are skipped; only headers with ODB object pragmas produce migration SQL
- missing source-version changelog XML means the target-version model is treated as a new table and generated from an empty changelog baseline
- PostgreSQL migrations remain incremental when source-version changelog XML exists
- SQLite migrations remain incremental except when ODB reports SQLite's drop-column limitation; in that case only that model is regenerated from the empty changelog baseline with a warning
- for production upgrades, PostgreSQL migration SQL is the meaningful upgrade path; SQLite greenfield fallback artifacts are generated for tree completeness, not as a guaranteed runnable SQLite upgrade path
### `db_gen_orm_serdes_and_zod`
+14
View File
@@ -31,6 +31,19 @@ if(NOT DEFINED DB_SCHEMA_DIR_MIGRATION_TO)
"Optional target schema directory basename for migration generation")
endif()
if(NOT DEFINED CPPBESSOT_GEN_MIGRATION_BACKENDS)
if(DEFINED CPPBESSOT_GEN_MIGRATIONS_BACKENDS)
set(CPPBESSOT_GEN_MIGRATION_BACKENDS "${CPPBESSOT_GEN_MIGRATIONS_BACKENDS}")
else()
set(CPPBESSOT_GEN_MIGRATION_BACKENDS "sqlite;pgsql")
endif()
endif()
set(CPPBESSOT_GEN_MIGRATION_BACKENDS "${CPPBESSOT_GEN_MIGRATION_BACKENDS}" CACHE STRING
"ODB backends for db_gen_migrations; supported values: sqlite, pgsql")
set(CPPBESSOT_GEN_MIGRATIONS_BACKENDS "${CPPBESSOT_GEN_MIGRATION_BACKENDS}" CACHE STRING
"Compatibility alias for CPPBESSOT_GEN_MIGRATION_BACKENDS" FORCE)
if(NOT DEFINED DB_SCHEMA_CHANGES_ARE_ERROR)
option(DB_SCHEMA_CHANGES_ARE_ERROR "Treat dirty schema changes as hard CMake error" OFF)
endif()
@@ -249,6 +262,7 @@ function(cppbessot_enable)
# - DB_SCHEMA_DIR_TO_GENERATE
# - DB_SCHEMA_DIR_MIGRATION_FROM
# - DB_SCHEMA_DIR_MIGRATION_TO
# - CPPBESSOT_GEN_MIGRATION_BACKENDS
# - DB_SCHEMA_CHANGES_ARE_ERROR (optional behavior control)
# Outputs:
# - Custom targets:
+6 -4
View File
@@ -9,6 +9,7 @@ function(cppbessot_add_db_gen_migrations_target from_schema_dir to_schema_dir)
# - from_schema_dir: Source schema directory basename.
# - to_schema_dir: Target schema directory basename.
# - CPPBESSOT_ODB_EXECUTABLE: Path to `odb` compiler.
# - CPPBESSOT_GEN_MIGRATION_BACKENDS: List of ODB backends to generate.
# Outputs:
# - CMake target: `db_gen_migrations` (EXCLUDE_FROM_ALL).
# - Files under `migrations/<from>-<to>/{sqlite,postgre}`.
@@ -26,10 +27,11 @@ function(cppbessot_add_db_gen_migrations_target from_schema_dir to_schema_dir)
add_custom_target(db_gen_migrations
COMMAND "${CMAKE_COMMAND}"
-DCPPBESSOT_ODB_EXECUTABLE=${CPPBESSOT_ODB_EXECUTABLE}
-DCPPBESSOT_FROM_VERSION_DIR=${_from_dir}
-DCPPBESSOT_TO_VERSION_DIR=${_to_dir}
-DCPPBESSOT_MIGRATION_DIR=${_migration_dir}
"-DCPPBESSOT_ODB_EXECUTABLE=${CPPBESSOT_ODB_EXECUTABLE}"
"-DCPPBESSOT_FROM_VERSION_DIR=${_from_dir}"
"-DCPPBESSOT_TO_VERSION_DIR=${_to_dir}"
"-DCPPBESSOT_MIGRATION_DIR=${_migration_dir}"
"-DCPPBESSOT_GEN_MIGRATION_BACKENDS=${CPPBESSOT_GEN_MIGRATION_BACKENDS}"
-P "${_CPPBESSOT_DB_GEN_MIGRATIONS_DIR}/scripts/run_odb_migrations.cmake"
COMMENT "Generating DB migrations: ${from_schema_dir} -> ${to_schema_dir}"
VERBATIM
+129 -10
View File
@@ -13,36 +13,130 @@ if(NOT DEFINED CPPBESSOT_MIGRATION_DIR OR CPPBESSOT_MIGRATION_DIR STREQUAL "")
message(FATAL_ERROR "CPPBESSOT_MIGRATION_DIR is required")
endif()
function(cppbessot_migration_resolve_backends out_var)
if(NOT DEFINED CPPBESSOT_GEN_MIGRATION_BACKENDS OR CPPBESSOT_GEN_MIGRATION_BACKENDS STREQUAL "")
if(DEFINED CPPBESSOT_GEN_MIGRATIONS_BACKENDS AND NOT CPPBESSOT_GEN_MIGRATIONS_BACKENDS STREQUAL "")
set(_raw_backends "${CPPBESSOT_GEN_MIGRATIONS_BACKENDS}")
else()
set(_raw_backends "sqlite;pgsql")
endif()
else()
set(_raw_backends "${CPPBESSOT_GEN_MIGRATION_BACKENDS}")
endif()
set(_resolved_backends "")
foreach(_backend IN LISTS _raw_backends)
string(STRIP "${_backend}" _backend)
string(TOLOWER "${_backend}" _backend)
if(_backend STREQUAL "")
message(FATAL_ERROR "CPPBESSOT_GEN_MIGRATION_BACKENDS contains an empty backend name.")
endif()
if(NOT _backend STREQUAL "sqlite" AND NOT _backend STREQUAL "pgsql")
message(FATAL_ERROR
"Unsupported migration backend `${_backend}`. "
"CPPBESSOT_GEN_MIGRATION_BACKENDS supports sqlite and pgsql.")
endif()
if(NOT _backend IN_LIST _resolved_backends)
list(APPEND _resolved_backends "${_backend}")
endif()
endforeach()
if(NOT _resolved_backends)
message(FATAL_ERROR "CPPBESSOT_GEN_MIGRATION_BACKENDS must name at least one backend.")
endif()
set(${out_var} "${_resolved_backends}" PARENT_SCOPE)
endfunction()
function(cppbessot_migration_backend_metadata backend out_subdir out_odb_database out_database_attr)
if("${backend}" STREQUAL "sqlite")
set(${out_subdir} "sqlite" PARENT_SCOPE)
set(${out_odb_database} "sqlite" PARENT_SCOPE)
set(${out_database_attr} "sqlite" PARENT_SCOPE)
elseif("${backend}" STREQUAL "pgsql")
set(${out_subdir} "postgre" PARENT_SCOPE)
set(${out_odb_database} "pgsql" PARENT_SCOPE)
set(${out_database_attr} "pgsql" PARENT_SCOPE)
else()
message(FATAL_ERROR "Unsupported migration backend `${backend}`.")
endif()
endfunction()
function(cppbessot_migration_write_empty_changelog changelog_path database_attr)
if(NOT EXISTS "${changelog_path}")
file(WRITE "${changelog_path}"
"<changelog xmlns=\"http://www.codesynthesis.com/xmlns/odb/changelog\" database=\"${database_attr}\" version=\"1\">\n"
" <model version=\"1\">\n"
" </model>\n"
"</changelog>\n")
endif()
endfunction()
function(cppbessot_migration_should_retry_sqlite_from_empty out_var backend from_xml empty_changelog stdout stderr)
set(_should_retry FALSE)
if("${backend}" STREQUAL "sqlite" AND NOT "${from_xml}" STREQUAL "${empty_changelog}")
set(_diagnostics "${stdout}\n${stderr}")
if(_diagnostics MATCHES "SQLite does not support dropping of columns")
set(_should_retry TRUE)
endif()
endif()
set(${out_var} "${_should_retry}" PARENT_SCOPE)
endfunction()
cppbessot_migration_resolve_backends(_migration_backends)
set(_to_include_dir "${CPPBESSOT_TO_VERSION_DIR}/generated-cpp-source/include")
file(GLOB _to_headers "${_to_include_dir}/*/model/*.h")
if(NOT _to_headers)
message(FATAL_ERROR "No target-version headers found under ${_to_include_dir}")
endif()
foreach(_backend IN ITEMS sqlite pgsql)
if(_backend STREQUAL "sqlite")
set(_subdir sqlite)
else()
set(_subdir postgre)
set(_object_headers "")
foreach(_header IN LISTS _to_headers)
file(READ "${_header}" _header_contents)
if(_header_contents MATCHES "#pragma db object")
list(APPEND _object_headers "${_header}")
endif()
endforeach()
if(NOT _object_headers)
message(FATAL_ERROR "No ODB object headers found under ${_to_include_dir}")
endif()
set(_empty_changelog_dir "${CPPBESSOT_MIGRATION_DIR}/.empty-baseline")
file(MAKE_DIRECTORY "${_empty_changelog_dir}")
foreach(_backend IN LISTS _migration_backends)
cppbessot_migration_backend_metadata(
"${_backend}"
_subdir
_odb_database
_database_attr)
set(_empty_changelog "${_empty_changelog_dir}/${_subdir}-empty.xml")
cppbessot_migration_write_empty_changelog("${_empty_changelog}" "${_database_attr}")
set(_migration_backend_dir "${CPPBESSOT_MIGRATION_DIR}/${_subdir}")
file(MAKE_DIRECTORY "${_migration_backend_dir}")
foreach(_header IN LISTS _to_headers)
foreach(_header IN LISTS _object_headers)
get_filename_component(_name "${_header}" NAME_WE)
set(_in_xml "${CPPBESSOT_FROM_VERSION_DIR}/generated-odb-source/${_subdir}/${_name}.xml")
set(_out_xml "${CPPBESSOT_TO_VERSION_DIR}/generated-odb-source/${_subdir}/${_name}.xml")
if(NOT EXISTS "${_in_xml}")
message(FATAL_ERROR "Missing changelog input for `${_name}`: ${_in_xml}")
set(_from_xml "${_in_xml}")
if(NOT EXISTS "${_from_xml}")
set(_from_xml "${_empty_changelog}")
endif()
execute_process(
COMMAND "${CPPBESSOT_ODB_EXECUTABLE}" -I "${_to_include_dir}" --std c++11 -d "${_backend}"
COMMAND "${CPPBESSOT_ODB_EXECUTABLE}" -I "${_to_include_dir}" --std c++11 -d "${_odb_database}"
--generate-schema --schema-format sql -q
-o "${_migration_backend_dir}"
--changelog-in "${_in_xml}"
--changelog-in "${_from_xml}"
--changelog-out "${_out_xml}"
"${_header}"
RESULT_VARIABLE _result
@@ -50,6 +144,31 @@ foreach(_backend IN ITEMS sqlite pgsql)
ERROR_VARIABLE _stderr
)
cppbessot_migration_should_retry_sqlite_from_empty(
_retry_from_empty
"${_backend}"
"${_from_xml}"
"${_empty_changelog}"
"${_stdout}"
"${_stderr}")
if(NOT _result EQUAL 0 AND _retry_from_empty)
message(WARNING
"SQLite incremental migration failed for `${_name}`; retrying from empty baseline. "
"Generated SQLite migration SQL is a greenfield create for this model.")
execute_process(
COMMAND "${CPPBESSOT_ODB_EXECUTABLE}" -I "${_to_include_dir}" --std c++11 -d "${_odb_database}"
--generate-schema --schema-format sql -q
-o "${_migration_backend_dir}"
--changelog-in "${_empty_changelog}"
--changelog-out "${_out_xml}"
"${_header}"
RESULT_VARIABLE _result
OUTPUT_VARIABLE _stdout
ERROR_VARIABLE _stderr
)
endif()
if(NOT _result EQUAL 0)
message(FATAL_ERROR
"Migration generation failed for `${_name}` backend `${_backend}`.\n${_stdout}\n${_stderr}")
@@ -13,6 +13,12 @@
#include <nlohmann/json.hpp>
#include <odb/core.hxx>
{{#vars}}
{{#vendorExtensions.x-cppType}}
#include <cppbessot/model/{{vendorExtensions.x-cppType}}.h>
{{/vendorExtensions.x-cppType}}
{{/vars}}
namespace models {
{{#isEnum}}
@@ -41,7 +47,7 @@ public:
{{#vendorExtensions.x-odbAddedIn}}
// odbAddedIn: {{.}}
{{/vendorExtensions.x-odbAddedIn}}
{{#isString}}std::string{{/isString}}{{^isString}}{{#isDateTime}}std::string{{/isDateTime}}{{^isDateTime}}{{dataType}}{{/isDateTime}}{{/isString}} {{nameInCamelCase}}{};
{{#vendorExtensions.x-cppType}}{{vendorExtensions.x-cppType}}{{/vendorExtensions.x-cppType}}{{^vendorExtensions.x-cppType}}{{#isString}}std::string{{/isString}}{{^isString}}{{#isDateTime}}std::string{{/isDateTime}}{{^isDateTime}}{{#isBoolean}}bool{{/isBoolean}}{{^isBoolean}}{{#isInteger}}int32_t{{/isInteger}}{{^isInteger}}{{#isLong}}int64_t{{/isLong}}{{^isLong}}{{dataType}}{{/isLong}}{{/isInteger}}{{/isBoolean}}{{/isDateTime}}{{/isString}}{{/vendorExtensions.x-cppType}} {{nameInCamelCase}}{};
{{/vars}}
NLOHMANN_DEFINE_TYPE_INTRUSIVE({{classname}}{{#vars}}, {{nameInCamelCase}}{{/vars}})
+1
View File
@@ -68,6 +68,7 @@ cppbessot_add_db_action_test(cppbessot_db_action_pgsql_tests_createfrom_mock pgs
cppbessot_add_db_action_test(cppbessot_db_action_pgsql_migrate_order pgsql_migrate_order.cmake)
cppbessot_add_db_action_test(cppbessot_db_action_pgsql_stale_abort pgsql_stale_abort.cmake)
cppbessot_add_db_action_test(cppbessot_db_action_backfill_env_no_structural backfill_env_no_structural.cmake)
cppbessot_add_db_action_test(cppbessot_db_gen_migrations_policy migration_policy.cmake)
cppbessot_add_real_pgsql_db_action_test(
cppbessot_db_action_pgsql_createfrom_real
pgsql_createfrom_real.cmake
@@ -0,0 +1,204 @@
include("${CMAKE_CURRENT_LIST_DIR}/../cmake/TestCommon.cmake")
cppbessot_test_require_var(CPPBESSOT_TEST_BINARY_DIR)
cppbessot_test_require_var(CPPBESSOT_TEST_MODULE_SOURCE_DIR)
set(_script_under_test "${CPPBESSOT_TEST_MODULE_SOURCE_DIR}/cmake/scripts/run_odb_migrations.cmake")
function(_cppbessot_migration_policy_fixture out_root)
cppbessot_test_case_dir(_case_dir)
set(_root "${_case_dir}/${ARGV1}")
cppbessot_test_reset_dir("${_root}")
file(MAKE_DIRECTORY
"${_root}/from/generated-odb-source/sqlite"
"${_root}/from/generated-odb-source/postgre"
"${_root}/to/generated-cpp-source/include/cppbessot/model"
"${_root}/to/generated-odb-source/sqlite"
"${_root}/to/generated-odb-source/postgre"
"${_root}/migrations")
cppbessot_test_write_file(
"${_root}/to/generated-cpp-source/include/cppbessot/model/Agent.h"
"#pragma db object\n"
"class Agent {};\n")
cppbessot_test_write_file(
"${_root}/to/generated-cpp-source/include/cppbessot/model/AgentPasswordHashType.h"
"enum class AgentPasswordHashType { argon2id };\n")
set(${out_root} "${_root}" PARENT_SCOPE)
endfunction()
function(_cppbessot_migration_policy_run root odb_executable result_var stdout_var stderr_var)
set(_args
"-DCPPBESSOT_ODB_EXECUTABLE=${odb_executable}"
"-DCPPBESSOT_FROM_VERSION_DIR=${root}/from"
"-DCPPBESSOT_TO_VERSION_DIR=${root}/to"
"-DCPPBESSOT_MIGRATION_DIR=${root}/migrations")
foreach(_extra_arg IN LISTS ARGN)
list(APPEND _args "${_extra_arg}")
endforeach()
execute_process(
COMMAND "${CMAKE_COMMAND}" ${_args} -P "${_script_under_test}"
RESULT_VARIABLE _result
OUTPUT_VARIABLE _stdout
ERROR_VARIABLE _stderr)
set(${result_var} "${_result}" PARENT_SCOPE)
set(${stdout_var} "${_stdout}" PARENT_SCOPE)
set(${stderr_var} "${_stderr}" PARENT_SCOPE)
endfunction()
function(_cppbessot_migration_policy_true_tool out_tool log_path)
get_filename_component(_tool_dir "${log_path}" DIRECTORY)
cppbessot_test_write_shell_script(
"${_tool_dir}/odb-true.sh"
"#!/usr/bin/env bash\n"
"printf '%s\\n' \"$*\" >> \"${log_path}\"\n")
set(${out_tool} "${_tool_dir}/odb-true.sh" PARENT_SCOPE)
endfunction()
function(_cppbessot_migration_policy_retry_tool out_tool tool_dir)
cppbessot_test_write_shell_script(
"${tool_dir}/odb-retry.sh"
"#!/usr/bin/env bash\n"
"while [[ $# -gt 0 ]]; do\n"
" if [[ \"$1\" == \"--changelog-in\" ]]; then\n"
" changelog=\"$2\"\n"
" shift 2\n"
" else\n"
" shift\n"
" fi\n"
"done\n"
"if [[ \"$changelog\" == *\".empty-baseline\"* ]]; then\n"
" exit 0\n"
"fi\n"
"echo \"error: SQLite does not support dropping of columns\" >&2\n"
"exit 1\n")
set(${out_tool} "${tool_dir}/odb-retry.sh" PARENT_SCOPE)
endfunction()
function(_cppbessot_migration_policy_false_tool out_tool tool_dir)
cppbessot_test_write_shell_script(
"${tool_dir}/odb-false.sh"
"#!/usr/bin/env bash\n"
"echo \"error: unrelated ODB failure\" >&2\n"
"exit 1\n")
set(${out_tool} "${tool_dir}/odb-false.sh" PARENT_SCOPE)
endfunction()
cppbessot_test_case_dir(_case_dir)
set(_configure_root "${_case_dir}/configure-policy")
set(_configure_build "${_case_dir}/configure-policy-build")
cppbessot_test_reset_dir("${_configure_root}")
cppbessot_test_write_file(
"${_configure_root}/CMakeLists.txt"
"cmake_minimum_required(VERSION 3.20)\n"
"project(cppbessot_migration_policy_configure LANGUAGES CXX)\n"
"set(CPPBESSOT_AUTO_ENABLE OFF CACHE BOOL \"\")\n"
"include(\"${CPPBESSOT_TEST_MODULE_SOURCE_DIR}/cmake/CppBeSSOT.cmake\")\n")
execute_process(
COMMAND "${CMAKE_COMMAND}" -S "${_configure_root}" -B "${_configure_build}"
RESULT_VARIABLE _result
ERROR_VARIABLE _stderr)
cppbessot_test_assert_success("${_result}" "${_stderr}" "migration backend default configure")
file(READ "${_configure_build}/CMakeCache.txt" _cache_text)
cppbessot_test_assert_contains(
"${_cache_text}"
"CPPBESSOT_GEN_MIGRATION_BACKENDS:STRING=sqlite;pgsql"
"migration backend default cache")
cppbessot_test_assert_contains(
"${_cache_text}"
"CPPBESSOT_GEN_MIGRATIONS_BACKENDS:STRING=sqlite;pgsql"
"migration backend alias default cache")
execute_process(
COMMAND "${CMAKE_COMMAND}" -S "${_configure_root}" -B "${_configure_build}" -DCPPBESSOT_GEN_MIGRATION_BACKENDS=pgsql
RESULT_VARIABLE _result
ERROR_VARIABLE _stderr)
cppbessot_test_assert_success("${_result}" "${_stderr}" "migration backend override reconfigure")
file(READ "${_configure_build}/CMakeCache.txt" _cache_text)
cppbessot_test_assert_contains(
"${_cache_text}"
"CPPBESSOT_GEN_MIGRATION_BACKENDS:STRING=pgsql"
"migration backend override cache")
cppbessot_test_assert_contains(
"${_cache_text}"
"CPPBESSOT_GEN_MIGRATIONS_BACKENDS:STRING=pgsql"
"migration backend alias override cache")
_cppbessot_migration_policy_fixture(_default_root "default")
_cppbessot_migration_policy_true_tool(_true_tool "${_default_root}/odb.log")
_cppbessot_migration_policy_run("${_default_root}" "${_true_tool}" _result _stdout _stderr)
cppbessot_test_assert_success("${_result}" "${_stderr}" "default migration backend policy")
cppbessot_test_assert_file_exists("${_default_root}/migrations/sqlite")
cppbessot_test_assert_file_exists("${_default_root}/migrations/postgre")
file(READ "${_default_root}/odb.log" _default_log)
cppbessot_test_assert_contains("${_default_log}" "-d sqlite" "default backend log")
cppbessot_test_assert_contains("${_default_log}" "-d pgsql" "default backend log")
if(_default_log MATCHES "AgentPasswordHashType\\.h")
message(FATAL_ERROR "Enum-only headers must not be passed to ODB migration generation.")
endif()
_cppbessot_migration_policy_fixture(_pgsql_root "pgsql-only")
_cppbessot_migration_policy_true_tool(_true_tool "${_pgsql_root}/odb.log")
_cppbessot_migration_policy_run(
"${_pgsql_root}"
"${_true_tool}"
_result
_stdout
_stderr
"-DCPPBESSOT_GEN_MIGRATION_BACKENDS=pgsql")
cppbessot_test_assert_success("${_result}" "${_stderr}" "pgsql-only migration backend policy")
cppbessot_test_assert_file_exists("${_pgsql_root}/migrations/postgre")
if(EXISTS "${_pgsql_root}/migrations/sqlite")
message(FATAL_ERROR "pgsql-only backend selection unexpectedly created sqlite migration output.")
endif()
_cppbessot_migration_policy_fixture(_plural_root "plural-alias")
_cppbessot_migration_policy_true_tool(_true_tool "${_plural_root}/odb.log")
_cppbessot_migration_policy_run(
"${_plural_root}"
"${_true_tool}"
_result
_stdout
_stderr
"-DCPPBESSOT_GEN_MIGRATIONS_BACKENDS=sqlite")
cppbessot_test_assert_success("${_result}" "${_stderr}" "legacy plural backend alias policy")
cppbessot_test_assert_file_exists("${_plural_root}/migrations/sqlite")
if(EXISTS "${_plural_root}/migrations/postgre")
message(FATAL_ERROR "plural alias sqlite-only backend selection unexpectedly created postgre migration output.")
endif()
_cppbessot_migration_policy_fixture(_invalid_root "invalid")
_cppbessot_migration_policy_run(
"${_invalid_root}"
"/bin/true"
_result
_stdout
_stderr
"-DCPPBESSOT_GEN_MIGRATION_BACKENDS=mysql")
cppbessot_test_assert_failure_contains("${_result}" "${_stderr}" "Unsupported migration backend")
_cppbessot_migration_policy_fixture(_retry_root "sqlite-retry")
file(WRITE "${_retry_root}/from/generated-odb-source/sqlite/Agent.xml" "")
_cppbessot_migration_policy_retry_tool(_retry_tool "${_retry_root}")
_cppbessot_migration_policy_run(
"${_retry_root}"
"${_retry_tool}"
_result
_stdout
_stderr
"-DCPPBESSOT_GEN_MIGRATION_BACKENDS=sqlite")
cppbessot_test_assert_success("${_result}" "${_stderr}" "sqlite drop-column retry policy")
cppbessot_test_assert_contains("${_stderr}" "SQLite incremental migration failed" "sqlite retry warning")
_cppbessot_migration_policy_fixture(_failure_root "sqlite-unrelated-failure")
file(WRITE "${_failure_root}/from/generated-odb-source/sqlite/Agent.xml" "")
_cppbessot_migration_policy_false_tool(_false_tool "${_failure_root}")
_cppbessot_migration_policy_run(
"${_failure_root}"
"${_false_tool}"
_result
_stdout
_stderr
"-DCPPBESSOT_GEN_MIGRATION_BACKENDS=sqlite")
cppbessot_test_assert_failure_contains("${_result}" "${_stderr}" "Migration generation failed")