Skip to content
This repository has been archived by the owner on May 21, 2024. It is now read-only.

Commit

Permalink
split migrate to forward and backward
Browse files Browse the repository at this point in the history
Signed-off-by: Serhiy Stetskovych <[email protected]>
  • Loading branch information
patriotyk committed Jan 29, 2019
1 parent 1c96a36 commit 8bb6858
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 42 deletions.
2 changes: 1 addition & 1 deletion src/libaktualizr/storage/embed_schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def apend_migration(migration_path, header_file):
apend_migration(os.path.join(migration_folder, migration_list[-1]), header_file)
header_file.write("\"\n};\n")

header_file.write("extern const std::map<int, std::string> schema_rollback_migrations = {")
header_file.write("extern const std::map<int, std::string> {}_schema_rollback_migrations = {{".format(prefix))
for migration in rollback_migrations_list[:-1]:
version = int(migration.split(".")[1])
header_file.write("{%d, "%version)
Expand Down
3 changes: 2 additions & 1 deletion src/libaktualizr/storage/sqlstorage.cc
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ void SQLStorage::cleanMetaVersion(Uptane::RepositoryType repo, Uptane::Role role

SQLStorage::SQLStorage(const StorageConfig& config, bool readonly)
: SQLStorageBase(config.sqldb_path.get(config.path), readonly, libaktualizr_schema_migrations,
libaktualizr_current_schema, libaktualizr_current_schema_version),
libaktualizr_schema_rollback_migrations, libaktualizr_current_schema,
libaktualizr_current_schema_version),
INvStorage(config) {
try {
cleanMetaVersion(Uptane::RepositoryType::Director(), Uptane::Role::Root());
Expand Down
3 changes: 2 additions & 1 deletion src/libaktualizr/storage/sqlstorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@
#include "sqlstorage_base.h"

extern const std::vector<std::string> libaktualizr_schema_migrations;
extern const std::map<int, std::string> libaktualizr_schema_rollback_migrations;
extern const std::string libaktualizr_current_schema;
extern const int libaktualizr_current_schema_version;

class SQLStorage : public SQLStorageBase, public INvStorage {
public:
friend class SQLTargetWHandle;
friend class SQLTargetRHandle;
explicit SQLStorage(const StorageConfig& config, bool readonly, bool migrate = true);
explicit SQLStorage(const StorageConfig& config, bool readonly);
~SQLStorage() override = default;
void storePrimaryKeys(const std::string& public_key, const std::string& private_key) override;
bool loadPrimaryKeys(std::string* public_key, std::string* private_key) override;
Expand Down
88 changes: 51 additions & 37 deletions src/libaktualizr/storage/sqlstorage_base.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@
boost::filesystem::path SQLStorageBase::dbPath() const { return sqldb_path_; }

SQLStorageBase::SQLStorageBase(boost::filesystem::path sqldb_path, bool readonly,
std::vector<std::string> schema_migrations, std::string current_schema,
std::vector<std::string> schema_migrations,
std::map<int, std::string> schema_rollback_migrations, std::string current_schema,
int current_schema_version)
: sqldb_path_(std::move(sqldb_path)),
readonly_(readonly),
schema_migrations_(std::move(schema_migrations)),
schema_rollback_migrations_(std::move(schema_rollback_migrations)),
current_schema_(std::move(current_schema)),
current_schema_version_(current_schema_version) {
boost::filesystem::path db_parent_path = dbPath().parent_path();
Expand Down Expand Up @@ -61,6 +63,48 @@ std::string SQLStorageBase::getTableSchemaFromDb(const std::string& tablename) {
return schema.value() + ";";
}

bool SQLStorageBase::dbMigrateForward(int version_from) {
SQLite3Guard db = dbConnection();
for (int32_t k = version_from + 1; k <= current_schema_version_; k++) {
if (db.exec(schema_migrations_.at(static_cast<size_t>(k)), nullptr, nullptr) != SQLITE_OK) {
LOG_ERROR << "Can't migrate db from version " << (k - 1) << " to version " << k << ": " << db.errmsg();
return false;
}
if (schema_rollback_migrations_.count(k) != 0) {
auto statement =
db.prepareStatement("INSERT INTO migrations VALUES (?,?);", k, schema_rollback_migrations_.at(k));
if (statement.step() != SQLITE_DONE) {
LOG_ERROR << "Can't insert rollback migration script: " << db.errmsg();
return false;
}
}
}
return true;
}

bool SQLStorageBase::dbMigrateBackward(int version_from) {
SQLite3Guard db = dbConnection();
for (int ver = version_from; ver > current_schema_version_; --ver) {
auto statement = db.prepareStatement("SELECT migration FROM migrations WHERE version_from=?;", ver);
if (statement.step() != SQLITE_ROW) {
LOG_ERROR << "Can't extract migration script: " << db.errmsg();
return false;
}
auto migration = statement.get_result_col_str(0);
statement.step();
if (db.exec(*migration, nullptr, nullptr) != SQLITE_OK) {
LOG_ERROR << "Can't migrate db from version " << (ver) << " to version " << ver - 1 << ": " << db.errmsg();
return false;
}
if (db.exec(std::string("DELETE FROM migrations WHERE version_from=") + std::to_string(ver) + ";", nullptr,
nullptr) != SQLITE_OK) {
LOG_ERROR << "Can't clear old migration script: " << db.errmsg();
return false;
}
}
return true;
}

bool SQLStorageBase::dbMigrate() {
DbVersion schema_version = getVersion();

Expand All @@ -70,7 +114,7 @@ bool SQLStorageBase::dbMigrate() {
}

auto schema_num_version = static_cast<int32_t>(schema_version);
if (schema_num_version == current_schema_version) {
if (schema_num_version == current_schema_version_) {
return true;
}

Expand All @@ -79,46 +123,16 @@ bool SQLStorageBase::dbMigrate() {
return false;
}

SQLite3Guard db = dbConnection();
if (schema_version != DbVersion::kEmpty && schema_num_version > current_schema_version) {
for (int ver = schema_num_version; ver > current_schema_version; --ver) {
auto statement = db.prepareStatement("SELECT migration FROM migrations WHERE version_from=?;", ver);
if (statement.step() != SQLITE_ROW) {
LOG_ERROR << "Can't extract migration script: " << db.errmsg();
return false;
}
auto migration = statement.get_result_col_str(0);
statement.step();
if (db.exec(*migration, nullptr, nullptr) != SQLITE_OK) {
LOG_ERROR << "Can't migrate db from version " << (ver) << " to version " << ver - 1 << ": " << db.errmsg();
return false;
}
if (db.exec(std::string("DELETE FROM migrations WHERE version_from=") + std::to_string(ver) + ";", nullptr,
nullptr) != SQLITE_OK) {
LOG_ERROR << "Can't clear old migration script: " << db.errmsg();
return false;
}
}
if (schema_version != DbVersion::kEmpty && schema_num_version > current_schema_version_) {
dbMigrateBackward(schema_num_version);
} else {
for (int32_t k = schema_num_version + 1; k <= current_schema_version; k++) {
if (db.exec(schema_migrations.at(static_cast<size_t>(k)), nullptr, nullptr) != SQLITE_OK) {
LOG_ERROR << "Can't migrate db from version " << (k - 1) << " to version " << k << ": " << db.errmsg();
return false;
}
if (schema_rollback_migrations.count(k) != 0) {
auto statement =
db.prepareStatement("INSERT INTO migrations VALUES (?,?);", k, schema_rollback_migrations.at(k));
if (statement.step() != SQLITE_DONE) {
LOG_ERROR << "Can't insert rollback migration script: " << db.errmsg();
return false;
}
}
}
dbMigrateForward(schema_num_version);
}

return true;
}

DbVersion SQLStorage::getVersion() {
DbVersion SQLStorageBase::getVersion() {
SQLite3Guard db = dbConnection();

try {
Expand Down
6 changes: 5 additions & 1 deletion src/libaktualizr/storage/sqlstorage_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@ enum class DbVersion : int32_t { kEmpty = -1, kInvalid = -2 };
class SQLStorageBase {
public:
explicit SQLStorageBase(boost::filesystem::path sqldb_path, bool readonly, std::vector<std::string> schema_migrations,
std::string current_schema, int current_schema_version);
std::map<int, std::string> schema_rollback_migrations, std::string current_schema,
int current_schema_version);
~SQLStorageBase() = default;
std::string getTableSchemaFromDb(const std::string& tablename);
bool dbMigrateForward(int version_from);
bool dbMigrateBackward(int version_from);
bool dbMigrate();
DbVersion getVersion(); // non-negative integer on success or -1 on error
boost::filesystem::path dbPath() const;
Expand All @@ -23,6 +26,7 @@ class SQLStorageBase {
boost::filesystem::path sqldb_path_;
bool readonly_{false};
const std::vector<std::string> schema_migrations_;
std::map<int, std::string> schema_rollback_migrations_;
const std::string current_schema_;
const int current_schema_version_;
};
Expand Down
2 changes: 1 addition & 1 deletion src/libaktualizr/storage/sqlstorage_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ TEST(sqlstorage, migrate_back) {
StorageConfig config;
config.path = temp_dir.Path();

SQLStorage storage(config, false, true);
SQLStorage storage(config, false);

SQLite3Guard db(temp_dir / "sql.db");
auto ver = storage.getVersion();
Expand Down

0 comments on commit 8bb6858

Please sign in to comment.