#include #include #include #include #include sqlite3 *global_database; static int in_transaction; void database_init() { int rc = sqlite3_open(global_config.database, &global_database); if(rc) { LOGGER_CRIT("can't open database: %s\n", sqlite3_errmsg(global_database)); exit(1); } if(database_migrate()) { exit(1); } sqlite3_exec(global_database, "PRAGMA foreign_keys = ON", 0, 0, 0); in_transaction = 0; } void database_free() { sqlite3_close(global_database); } int database_migrate() { uint16_t version_num = 0; int s, rc; sqlite3_stmt *stmt; sqlite3_prepare_v2(global_database, "SELECT version_num FROM meta LIMIT 1;", -1, &stmt, NULL); s = sqlite3_step(stmt); if (s == SQLITE_ROW) { version_num = sqlite3_column_int(stmt, 0); } else { version_num = 0; } uint16_t new_version_num = version_num; char* err_msg; sqlite3_finalize(stmt); switch(version_num) { case 0: LOGGER_INFO("migrating LEVEL 0\n"); rc = sqlite3_exec(global_database, (const char *)sql_migration_0_sql, NULL, NULL, &err_msg); if(rc) { LOGGER_CRIT("couldn't migrate LEVEL 0 (%s)\n", err_msg); break; } new_version_num = 1; default: break; } if(version_num == 0) { sqlite3_prepare_v2(global_database, "INSERT INTO meta (version_num) VALUES (?1);", -1, &stmt, NULL); } else { sqlite3_prepare_v2(global_database, "UPDATE meta SET version_num=?1;", -1, &stmt, NULL); } sqlite3_bind_int(stmt, 1, new_version_num); rc = sqlite3_step(stmt); if (rc != SQLITE_DONE) { LOGGER_CRIT("couldn't write new schema version\n"); } sqlite3_finalize(stmt); return rc != SQLITE_DONE; } int database_transaction_begin() { if(!in_transaction) { LOGGER_DEBUG("beginning transaction\n"); sqlite3_exec(global_database, "BEGIN TRANSACTION;", NULL, NULL, NULL); in_transaction = 1; return 1; } return 0; } void database_transaction_commit() { LOGGER_DEBUG("commiting transaction\n"); sqlite3_exec(global_database, "COMMIT TRANSACTION;", NULL, NULL, NULL); in_transaction = 0; } void database_transaction_rollback() { LOGGER_DEBUG("rolling back transaction\n"); sqlite3_exec(global_database, "ROLLBACK TRANSACTION;", NULL, NULL, NULL); in_transaction = 0; }