diff options
Diffstat (limited to 'src/pke-at-storage-sql.cpp')
| -rw-r--r-- | src/pke-at-storage-sql.cpp | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/src/pke-at-storage-sql.cpp b/src/pke-at-storage-sql.cpp new file mode 100644 index 0000000..e028ff5 --- /dev/null +++ b/src/pke-at-storage-sql.cpp @@ -0,0 +1,220 @@ + +#include "pke-at-storage-sql.hpp" +#include "pke/asset-types.h" + +#include <sqlite3.h> + +#define PASIS_RES(R) { .result_code = pke_at_storage_interface_result_code(R) } +#define PASIS_REST(R,V) { .result_code = pke_at_storage_interface_result_code(R), .value = V } + +constexpr unsigned long query_text_length = 1024; + +static struct pke_at_storage_sql_master { + sqlite3 *db = nullptr; + char query_text[query_text_length]; +} sql_mstr; + +void pke_at_storage_sql::init() const { + char *sql_err_string = nullptr; + int res, null_count; + AssetKey asset_key; + AssetHandle asset_handle; + struct db_version { + unsigned char maj = -1; + unsigned char min = -1; + } version; + const Asset *asset = nullptr; + db_version check_version; + assert(sql_mstr.db == nullptr); + res = sqlite3_open("pke-at.sqlite3", &sql_mstr.db); + if (res != SQLITE_OK) { + fprintf(stderr, "[pke_at_storage_sql::init] Failed to open database, sqlite err: %i, %s\n", res, sqlite3_errmsg(sql_mstr.db)); + goto cleanup; + } + + // check db version table exists + { + const char *query = "SELECT name from sqlite_schema WHERE type='table' AND name='db_version'"; + auto fn = [](void *user_data, int column_count, char **argv, char **colname) -> int { + (void)argv; + (void)colname; + db_version *version = reinterpret_cast<db_version*>(user_data); + if (column_count != 0) { + version->maj = 0; + } + return SQLITE_OK; + }; + res = sqlite3_exec(sql_mstr.db, query, fn, &version, &sql_err_string); + if (res != SQLITE_OK) { + fprintf(stderr, "[pke_at_storage_sql::init] Failed to query db schema, sqlite err: %i, %s\n", res, sql_err_string); + goto cleanup; + } + } + + // check db version + if (version.maj == 0) { + const char *query = "SELECT version_maj,version_min from [db_version] WHERE id='0'"; + auto fn = [](void *user_data, int column_count, char **argv, char **colname) -> int { + (void)colname; + PK_STN_RES stn_res; + db_version *version = reinterpret_cast<db_version*>(user_data); + for (int i = 0; i < column_count; ++i) { + if (i == 0) { + stn_res = pk_stn(&version->maj, argv[i], nullptr); + if (stn_res != PK_STN_RES_SUCCESS) { + fprintf(stderr, "[pke_at_storage_sql::init] err parsing database version maj.\n"); + return SQLITE_ERROR; + } + } + if (i == 1) { + stn_res = pk_stn(&version->min, argv[i], nullptr); + if (stn_res != PK_STN_RES_SUCCESS) { + fprintf(stderr, "[pke_at_storage_sql::init] err parsing database version min.\n"); + return SQLITE_ERROR; + } + } + } + return SQLITE_OK; + }; + res = sqlite3_exec(sql_mstr.db, query, fn, &version, &sql_err_string); + if (res != SQLITE_OK) { + fprintf(stderr, "[pke_at_storage_sql::init] Failed to query [db_version], sqlite err: %i, %s\n", res, sql_err_string); + goto cleanup; + } + } + + // dynamically update db + null_count = 0; + check_version = version; + check_version.min += 1; + while (true) { + snprintf(asset_key, AssetKeyLength, "sql_scm_%03i_%03i", check_version.maj, check_version.min); + asset_handle = AM_GetHandle(asset_key); + if (asset_handle == AssetHandle_MAX) { + null_count += 1; + check_version.maj += 1; + check_version.min = 0; + if (null_count > 1) break; + continue; + } + asset = AM_Get(asset_handle); + null_count = 0; + auto fn = [](void *user_data, int column_count, char **argv, char **colname) -> int { + (void)user_data; (void)column_count; (void)argv; (void)colname; + return SQLITE_OK; + }; + res = sqlite3_exec(sql_mstr.db, (char*)asset->ptr, fn, nullptr, &sql_err_string); + if (res != SQLITE_OK) { + fprintf(stderr, "[pke_at_storage_sql::init] failed updating database at step %03i_%03i: %i, %s\n", check_version.maj, check_version.min, res, sql_err_string); + goto cleanup; + } + check_version.min += 1; + } + +cleanup: + if (sql_mstr.db != nullptr) sqlite3_close(sql_mstr.db); + fflush(stderr); + if (res != SQLITE_OK) exit(1); +} + +void +pke_at_storage_sql::teardown() +const { + /* TODO */ +} + +pke_at_storage_interface_response +pke_at_storage_sql::pke_at_storage_interface_section_delete(pk_uuid uuid) +const { + (void)uuid; + /* TODO */ + return PASIS_RES(0); +} + +pke_at_storage_interface_response_t<pke_at_section_details> +pke_at_storage_sql::pke_at_storage_interface_section_get(pk_uuid uuid) +const { + (void)uuid; + /* TODO */ + return PASIS_REST(0, nullptr); +} + +pke_at_storage_interface_response +pke_at_storage_sql::pke_at_storage_interface_section_upsert(const pke_at_section_details &val) +const { + (void)val; + /* TODO */ + return PASIS_RES(0); +} + +pke_at_storage_interface_response +pke_at_storage_sql::pke_at_storage_interface_setlist_delete(pk_uuid uuid) +const { + (void)uuid; + /* TODO */ + return PASIS_RES(0); +} + +pke_at_storage_interface_response_t<pke_at_setlist_details> +pke_at_storage_sql::pke_at_storage_interface_setlist_get(pk_uuid uuid) +const { + (void)uuid; + /* TODO */ + return PASIS_REST(0, nullptr); +} + +pke_at_storage_interface_response +pke_at_storage_sql::pke_at_storage_interface_setlist_upsert(const pke_at_setlist_details &val) +const { + (void)val; + /* TODO */ + return PASIS_RES(0); +} + +pke_at_storage_interface_response +pke_at_storage_sql::pke_at_storage_interface_song_delete(pk_uuid uuid) +const { + (void)uuid; + /* TODO */ + return PASIS_RES(0); +} + +pke_at_storage_interface_response_t<pke_at_song_details> +pke_at_storage_sql::pke_at_storage_interface_song_get(pk_uuid uuid) +const { + (void)uuid; + /* TODO */ + return PASIS_REST(0, nullptr); +} + +pke_at_storage_interface_response +pke_at_storage_sql::pke_at_storage_interface_song_upsert(const pke_at_song_details &val) +const { + (void)val; + /* TODO */ + return PASIS_RES(0); +} + +pke_at_storage_interface_response +pke_at_storage_sql::pke_at_storage_interface_setlist_song_delete(pk_uuid uuid) +const { + (void)uuid; + /* TODO */ + return PASIS_RES(0); +} + +pke_at_storage_interface_response_t<pke_at_setlist_song_details> +pke_at_storage_sql::pke_at_storage_interface_setlist_song_get(pk_uuid uuid) +const { + (void)uuid; + /* TODO */ + return PASIS_REST(0, nullptr); +} + +pke_at_storage_interface_response +pke_at_storage_sql::pke_at_storage_interface_setlist_song_upsert(const pke_at_setlist_song_details &val) +const { + (void)val; + /* TODO */ + return PASIS_RES(0); +} |
