From d30bcf3ddf7b0cd84d9b6ccecf7380de2df3c667 Mon Sep 17 00:00:00 2001 From: avsdev-cw Date: Tue, 6 Oct 2020 17:47:27 +0100 Subject: [PATCH] Added some more convenience queries --- src/db_query.c | 205 +++++++++++++++++++++++++++++++++++++++++++++++++ src/db_query.h | 27 +++++++ 2 files changed, 232 insertions(+) diff --git a/src/db_query.c b/src/db_query.c index 436cc98..3719605 100644 --- a/src/db_query.c +++ b/src/db_query.c @@ -6,6 +6,8 @@ #include "db_connection.h" #include "db_column.h" +#include "db_value.h" +#include "db_where-builder.h" #include "strext.h" @@ -278,3 +280,206 @@ char *scalarString(struct stored_conn_t *sconn, const char *qry, size_t qry_len, return retval; } + + +int64_t countQuery(struct stored_conn_t *sconn, const char *table, where_builder *wb) +{ + char *qry; + size_t qry_len; + int qry_ret; + str_builder *sb; + + if ((sb = strbld_create()) == 0) { + return -1; + } + strbld_str(sb, "SELECT COUNT(*) AS `C` FROM `", 0); + strbld_str(sb, table, 0); + strbld_str(sb, "` WHERE ", 0); + compileWhereBuilder_sb(wb, sb); + if (strbld_finalize_or_destroy(&sb, &qry, &qry_len) != 0) { + free(wb); + return -1; + } + free(wb); + + qry_ret = scalarInt(sconn, qry, qry_len, 0); + free(qry); + + return qry_ret; +} + +int deleteQuery(struct stored_conn_t *sconn, const char *table, where_builder *wb) +{ + str_builder *sb; + char *qry; + size_t qry_len; + uint64_t qry_ret; + + if ((sb = strbld_create()) == 0) { + return -1; + } + strbld_str(sb, "DELETE FROM `", 0); + strbld_str(sb, table, 0); + strbld_str(sb, "` WHERE ", 0); + compileWhereBuilder_sb(wb, sb); + if (strbld_finalize_or_destroy(&sb, &qry, &qry_len) != 0) { + return -1; + } + + qry_ret = simpleQuery(sconn, qry, qry_len); + free(qry); + + if (qry_ret == (uint64_t)-1) { + return -1; + } + + return qry_ret == 0; +} + + + +int syncIdMap(struct stored_conn_t *sconn, const char *table, + const char *primary_col, const char *map_col, + unsigned int primary_id, size_t n_maps, unsigned int *map_ids) +{ + str_builder *sb; + where_builder *wb; + char *qry; + size_t qry_len; + int qry_ret; + size_t idx; + + wb = where(table, primary_col, EQ, TYPE_ID, 1, primary_id); + qry_ret = deleteQuery(sconn, table, wb); + free(wb); + + if (qry_ret != 0) { + return qry_ret; + } + + if ((sb = strbld_create()) == 0) { + return -1; + } + strbld_str(sb, "INSERT INTO `", 0); + strbld_str(sb, table, 0); + strbld_str(sb, "` (`", 0); + strbld_str(sb, primary_col, 0); + strbld_str(sb, "`, `", 0); + strbld_str(sb, map_col, 0); + strbld_str(sb, "`) VALUES ", 0); + for (idx = 0; idx < n_maps; idx++) { + strbld_char(sb, '('); + db_value_sb(sb, TYPE_ID, 1, primary_id); + strbld_char(sb, ','); + db_value_sb(sb, TYPE_ID, 1, *(map_ids + idx)); + strbld_char(sb, ')'); + if ((idx + 1) < n_maps) { + strbld_char(sb, ','); + } + } + if (strbld_finalize_or_destroy(&sb, &qry, &qry_len) != 0) { + return -1; + } + + if (simpleQuery(sconn, qry, qry_len) == (uint64_t)-1) { + return -1; + } + + return 1; +} +int syncIdMap_va(struct stored_conn_t *sconn, const char *table, + const char *primary_col, const char *map_col, + unsigned int primary_id, size_t n_maps, va_list args) +{ + unsigned int *map_ids; + size_t idx; + int ret_val; + + if ((map_ids = (unsigned int *)malloc(sizeof(unsigned int) * n_maps)) == 0) { + return -1; + } + for (idx = 0; idx < n_maps; idx++) { + *(map_ids + idx) = va_arg(args, unsigned int); + } + + ret_val = syncIdMap(sconn, table, primary_col, map_col, primary_id, n_maps, map_ids); + + free(map_ids); + + return ret_val; +} + + +int hasIdMap(struct stored_conn_t *sconn, const char *table, + const char *primary_col, const char *map_col, + unsigned int primary_id, unsigned int map_id) +{ + int64_t qry_ret; + where_builder *wb; + + wb = whereAnd( + where(table, primary_col, EQ, TYPE_ID, 1, primary_id), + where(table, map_col, EQ, TYPE_ID, 1, map_id) + ); + qry_ret = countQuery(sconn, table, wb); + free(wb); + + return qry_ret > 0; +} +int addIdMap(struct stored_conn_t *sconn, const char *table, + const char *primary_col, const char *map_col, + unsigned int primary_id, unsigned int map_id) +{ + str_builder *sb; + char *qry; + size_t qry_len; + uint64_t qry_ret; + + if ((sb = strbld_create()) == 0) { + return -1; + } + strbld_str(sb, "INSERT INTO `", 0); + strbld_str(sb, table, 0); + strbld_str(sb, "` (`", 0); + strbld_str(sb, primary_col, 0); + strbld_str(sb, "`, `", 0); + strbld_str(sb, map_col, 0); + strbld_str(sb, "`) VALUES ", 0); + strbld_char(sb, '('); + db_value_sb(sb, TYPE_ID, 1, primary_id); + strbld_char(sb, ','); + db_value_sb(sb, TYPE_ID, 1, map_id); + strbld_char(sb, ')'); + strbld_str(sb, "` ON DUPLICATE KEY UPDATE `", 0); + strbld_str(sb, primary_col, 0); + strbld_str(sb, "` = ", 0); + db_value_sb(sb, TYPE_ID, 1, primary_id); + if (strbld_finalize_or_destroy(&sb, &qry, &qry_len) != 0) { + return -1; + } + + qry_ret = simpleQuery(sconn, qry, qry_len); + free(qry); + + if (qry_ret == (uint64_t)-1) { + return -1; + } + + return 1; +} +int removeIdMap(struct stored_conn_t *sconn, const char *table, + const char *primary_col, const char *map_col, + unsigned int primary_id, unsigned int map_id) +{ + int qry_ret; + where_builder *wb; + + wb = whereAnd( + where(table, primary_col, EQ, TYPE_ID, 1, primary_id), + where(table, map_col, EQ, TYPE_ID, 1, map_id) + ); + qry_ret = deleteQuery(sconn, table, wb); + free(wb); + + return qry_ret; +} diff --git a/src/db_query.h b/src/db_query.h index 6f86bff..88dbaee 100644 --- a/src/db_query.h +++ b/src/db_query.h @@ -6,6 +6,7 @@ #include "db_connection.h" #include "db_column.h" +#include "db_where-builder.h" // Generic query methods uint64_t simpleQuery(struct stored_conn_t *sconn, const char *qry, size_t qry_len); @@ -14,6 +15,7 @@ uint64_t scalarQuery(struct stored_conn_t *sconn, const char *qry, size_t qry_le uint64_t tableQuery(struct stored_conn_t *sconn, const char *qry, size_t qry_len, int scalar_result, struct column_data_t ***col_data, size_t *n_cols); + // Scalar helpers int scalarInt(struct stored_conn_t *sconn, const char *qry, size_t qry_len, int default_value); unsigned int scalarUInt(struct stored_conn_t *sconn, const char *qry, size_t qry_len, @@ -24,4 +26,29 @@ char scalarChar(struct stored_conn_t *sconn, const char *qry, size_t qry_len, ch char *scalarString(struct stored_conn_t *sconn, const char *qry, size_t qry_len, char *default_value); + +// Where query methods +int64_t countQuery(struct stored_conn_t *sconn, const char *table, where_builder *wb); +uint64_t deleteQuery(struct stored_conn_t *sconn, const char *table, where_builder *wb); + + +// Map helpers +int syncIdMap(struct stored_conn_t *sconn, const char *table, + const char *primary_col, const char *map_col, + unsigned int primary_id, size_t n_maps, unsigned int *map_ids); +int syncIdMap_va(struct stored_conn_t *sconn, const char *table, + const char *primary_col, const char *map_col, + unsigned int primary_id, size_t n_maps, va_list args); + +int hasIdMap(struct stored_conn_t *sconn, const char *table, + const char *primary_col, const char *map_col, + unsigned int primary_id, unsigned int map_id); +int addIdMap(struct stored_conn_t *sconn, const char *table, + const char *primary_col, const char *map_col, + unsigned int primary_id, unsigned int map_id); +int removeIdMap(struct stored_conn_t *sconn, const char *table, + const char *primary_col, const char *map_col, + unsigned int primary_id, unsigned int map_id); + + #endif // H__DB_QUERY__