summaryrefslogtreecommitdiff
path: root/src/pke-at-storage-sql.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/pke-at-storage-sql.cpp')
-rw-r--r--src/pke-at-storage-sql.cpp220
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);
+}