27 "CREATE TABLE IF NOT EXISTS orbit_migrations ("
28 "id SERIAL PRIMARY KEY, "
29 "version VARCHAR(255) UNIQUE NOT NULL, "
30 "applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP);"
35 "SELECT version FROM orbit_migrations ORDER BY version ASC;"
38 std::vector<std::string> applied_versions;
39 for (
size_t i = 0; i < applied_res.
size(); ++i) {
40 applied_versions.push_back(applied_res[i].get(0).value_or(
""));
44 if (!std::filesystem::exists(migrations_dir)) {
45 std::cout <<
"[Migrations] Directory '" << migrations_dir <<
"' not found. Skipping migrations.\n";
50 std::vector<std::string> pending_files;
51 for (
const auto& entry : std::filesystem::directory_iterator(migrations_dir)) {
52 if (entry.path().extension() ==
".sql") {
53 pending_files.push_back(entry.path().string());
56 std::sort(pending_files.begin(), pending_files.end());
60 for (
const auto& filepath : pending_files) {
61 std::string filename = std::filesystem::path(filepath).filename().string();
63 if (std::find(applied_versions.begin(), applied_versions.end(), filename) == applied_versions.end()) {
64 std::cout <<
"[Migrations] Applying " << filename <<
"..." << std::endl;
66 std::ifstream ifs(filepath);
68 std::cerr <<
"[Migrations] Failed to open " << filepath << std::endl;
72 std::string sql((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
78 std::string insert_tracking =
"INSERT INTO orbit_migrations (version) VALUES ('" + filename +
"');";