From 829d9560728c1fca688674ecf2faa977c53fd9a8 Mon Sep 17 00:00:00 2001 From: avsdev-cw Date: Wed, 23 Sep 2020 14:36:44 +0100 Subject: [PATCH] Refactored where builder with private file for some methods --- src/db_where-builder.c | 512 ++------------------------------------- src/db_where-builder.h | 11 +- src/db_where-builder_p.c | 448 ++++++++++++++++++++++++++++++++++ src/db_where-builder_p.h | 60 +++++ src/strext.h | 6 +- 5 files changed, 540 insertions(+), 497 deletions(-) create mode 100644 src/db_where-builder_p.c create mode 100644 src/db_where-builder_p.h diff --git a/src/db_where-builder.c b/src/db_where-builder.c index b550b78..3071fa4 100644 --- a/src/db_where-builder.c +++ b/src/db_where-builder.c @@ -4,346 +4,11 @@ #include #include "db_where-builder.h" +#include "db_where-builder_p.h" #include "db_connection.h" #include "db_value.h" #include "strext.h" - -struct where_logic_t { - where_builder *up; - e_where_logic logic_type; - - where_builder **constructs; - size_t n_constructs; - size_t n_alloc; -}; -typedef struct where_logic_t where_logic; - -struct where_clause_t { - where_builder *up; - e_where_logic logic_type; - - // Table - char *table; - size_t table_len; - - // Column - char *col; - size_t col_len; - - // Op - e_where_op op; - - // Values - char **values; - size_t *values_len; - size_t n_values; - size_t n_alloc; -}; -typedef struct where_clause_t where_clause; - - -// private: -void freeLogic(where_logic **logic_ptr) -{ - where_logic *logic; - where_builder *construct; - - logic = *logic_ptr; - while (logic->n_constructs > 0) { - construct = logic->constructs[logic->n_constructs - 1]; - construct->up = 0; - destroyWhereBuilder(&construct); - logic->n_constructs--; - } - if (logic->constructs != 0) { - free(logic->constructs); - logic->constructs = 0; - } - free(*logic_ptr); - *logic_ptr = 0; -} -where_logic *createLogic(e_where_logic type, size_t initial_size) -{ - where_logic *logic = (where_logic *)malloc(sizeof(where_logic)); - if (logic == 0) { - fprintf(stderr, "[%d]malloc: (%d) %s\n", __LINE__, errno, strerror(errno)); - return 0; - } - memset(logic, 0, sizeof(where_logic)); - - logic->logic_type = type; - - if (initial_size == 0) { - return logic; - } - - logic->constructs = (where_builder **)malloc(sizeof(where_builder *) * initial_size); - if (logic->constructs == 0) { - fprintf(stderr, "[%d]malloc: (%d) %s\n", __LINE__, errno, strerror(errno)); - freeLogic(&logic); - return 0; - } - memset(logic->constructs, 0, sizeof(where_builder *) * initial_size); - logic->n_constructs = 0; - logic->n_alloc = initial_size; - - return logic; -} -where_builder *appendClause(where_builder *wb, where_builder *wb_clause) -{ - where_logic *logic = (where_logic *)wb; - where_builder **old_ptr; - size_t new_size; - - if (wb_clause == 0) { - return wb; - } - - if (!(wb->logic_type == AND || wb->logic_type == OR)) { - fprintf(stderr, "[%d]appendClause: Where-builder stack corrupted!\n", __LINE__); - return wb; - } - - if (logic->n_constructs == logic->n_alloc) { - old_ptr = (where_builder **)logic->constructs; - new_size = sizeof(where_builder *) * (logic->n_alloc + 1); - logic->constructs = (where_builder **)realloc(logic->constructs, new_size); - if (logic->constructs == 0) { - fprintf(stderr, "[%d]realloc: (%d) %s\n", __LINE__, errno, strerror(errno)); - logic->constructs = old_ptr; - return wb; - } - logic->n_alloc++; - } - - logic->constructs[logic->n_constructs] = wb_clause; - logic->n_constructs++; - wb_clause->up = (where_builder *)logic; - - return wb; -} - -int ensureValueSize(where_clause *clause, size_t new_size) -{ - size_t *old_lens; - char **old_values; - - if (clause->n_alloc >= new_size) { - return 0; - } - - old_values = clause->values; - clause->values = (char **)realloc(clause->values, sizeof(char *) * new_size); - if (clause->values == 0) { - fprintf(stderr, "[%d]realloc: (%d) %s\n", __LINE__, errno, strerror(errno)); - clause->values = old_values; - return 1; - } - - old_lens = clause->values_len; - clause->values_len = (size_t *)realloc(clause->values_len, sizeof(size_t) * new_size); - if (clause->values_len == 0) { - fprintf(stderr, "[%d]realloc: (%d) %s\n", __LINE__, errno, strerror(errno)); - clause->values_len = old_lens; - return 1; - } - - (clause->n_alloc)++; - - return 0; -} - -where_clause *createWhere(const char *tbl, const char *col, e_where_op op) -{ - where_clause *clause; - - clause = (where_clause *)malloc(sizeof(where_clause)); - if (clause == 0) { - fprintf(stderr, "[%d]malloc: (%d) %s\n", __LINE__, errno, strerror(errno)); - return 0; - } - memset(clause, 0, sizeof(where_clause)); - - clause->logic_type = CLAUSE; - clause->op = op; - - if (tbl != 0) { - if (strmemcpy(tbl, strlen(tbl), &clause->table, &clause->table_len) != 0) { - freeWhere((where_builder **)&clause); - return 0; - } - } - if (strmemcpy(col, strlen(col), &clause->col, &clause->col_len) != 0) { - freeWhere((where_builder **)&clause); - return 0; - } - - clause->values = (char **)malloc(sizeof(char *)); - clause->values_len = (size_t *)malloc(sizeof(size_t)); - if (clause->values == 0 || clause->values_len == 0) { - fprintf(stderr, "[%d]malloc: (%d) %s\n", __LINE__, errno, strerror(errno)); - freeWhere((where_builder **)&clause); - return 0; - } - clause->n_alloc = 1; - - return clause; -} - -where_builder *where_And_Or(where_builder *wb, where_builder *wb_clause, e_where_logic and_or) -{ - where_logic *logic; - - if (wb == 0) { - wb = (where_builder *)createLogic(and_or, 2); - if (wb == 0) { - return wb_clause; - } - } - - switch(wb->logic_type) { - case UNK: - { - if ((logic = createLogic(and_or, 2)) == 0) { - destroyWhereBuilder(&wb_clause); - return wb; - } - free(wb); - if (wb_clause != 0) { - logic->constructs[0] = wb_clause; - logic->n_constructs++; - wb_clause->up = (where_builder *)logic; - } - wb = (where_builder *)logic; - break; - } - - case CLAUSE: - { - if ((logic = createLogic(and_or, 2)) == 0) { - destroyWhereBuilder(&wb_clause); - return wb; - } - logic->constructs[0] = wb; - logic->n_constructs++; - wb->up = (where_builder *)logic; - if (wb_clause != 0) { - logic->constructs[1] = wb_clause; - logic->n_constructs++; - wb_clause->up = (where_builder *)logic; - } - wb = (where_builder *)logic; - break; - } - - case OR: - { - if (and_or == AND) { - if ((logic = createLogic(AND, 2)) == 0) { - destroyWhereBuilder(&wb_clause); - return wb; - } - if (whereOr(wb, (where_builder *)logic) == 0) { - freeLogic(&logic); - destroyWhereBuilder(&wb_clause); - return wb; - } - wb = appendClause((where_builder *)logic, wb_clause); - } else { - wb = appendClause(wb, wb_clause); - } - break; - } - - case AND: - { - if (and_or == AND) { - wb = appendClause(wb, wb_clause); - } else { - if ((logic = createLogic(OR, 2)) == 0) { - destroyWhereBuilder(&wb_clause); - return wb; - } - if (whereAnd(wb, (where_builder *)logic) == 0) { - freeLogic(&logic); - destroyWhereBuilder(&wb_clause); - return wb; - } - wb = appendClause((where_builder *)logic, wb_clause); - } - break; - } - } - - return wb; -} - -where_builder *where_In_notIn_va(where_builder *wb, const char *tbl, const char *col, e_where_op op, - e_column_type type, uint32_t n_args, va_list args) -{ - where_clause *clause; - where_builder *wb_clause; - - if (wb == 0) { - return where_va(tbl, col, op, type, n_args, args); - } - - switch (wb->logic_type) { - case UNK: - { - free(wb); - return where_va(tbl, col, op, type, n_args, args); - } - case CLAUSE: - { - clause = (where_clause *)wb; - if (clause->op != op - || (tbl != 0 && clause->table == 0) - || (tbl != 0 && clause->table != 0 && strcmp(clause->table, tbl) != 0) - || (col != 0 && clause->col == 0) - || (col != 0 && clause->col != 0 && strcmp(clause->col, col) != 0)) { - if (wb->up == 0) { - fprintf(stderr, "[%d]whereIn_notIn: Where-builder stack corrupted!\n", __LINE__); - return wb; - } - return where_In_notIn_va(wb->up, tbl, col, op, type, n_args, args); - } - - return setWhereValue_va((where_builder *)clause, type, n_args, args); - } - case AND: - case OR: - { - if ((wb_clause = where_va(tbl, col, op, type, n_args, args)) == 0) { - return wb; - } - if (wb->logic_type == AND) { - whereAnd(wb, wb_clause); - } else { - whereOr(wb, wb_clause); - } - return wb_clause; - } - } - - return wb; -} -where_builder *where_In_notIn(where_builder *wb, const char *tbl, const char *col, e_where_op op, - e_column_type type, uint32_t n_args, ...) -{ - where_builder *ret; - va_list args; - - va_start(args, n_args); - ret = where_In_notIn_va(wb, tbl, col, op, type, n_args, args); - va_end(args); - - return ret; -} - - -// public: where_builder *createWhereBuilder(where_builder *initial_clause) { if (initial_clause != 0) { @@ -359,6 +24,25 @@ where_builder *createWhereBuilder(where_builder *initial_clause) return wb; } +int compileWhereBuilder(where_builder *wb, char **str, size_t *str_len) +{ + switch(wb->logic_type) { + case CLAUSE: + { + return compileWhere((where_clause *)wb, str, str_len); + } + case OR: + case AND: + { + return compileLogic((where_logic *)wb, str, str_len); + } + default: + { + return 0; + } + } +} + void destroyWhereBuilder(where_builder **wb_ptr) { where_builder *wb = finalizeWhere(*wb_ptr); @@ -370,7 +54,7 @@ void destroyWhereBuilder(where_builder **wb_ptr) switch(wb->logic_type) { case CLAUSE: { - freeWhere(&wb); + freeWhere((where_clause **)&wb); break; } case OR: @@ -413,41 +97,6 @@ where_builder *where_va(const char *tbl, const char *col, e_where_op op, e_colum return setWhereValue_va(wb_clause, type, n_args, args); } -void freeWhere(where_builder **wb_clause_ptr) -{ - where_clause *clause = (where_clause *)(*wb_clause_ptr); - - if (wb_clause_ptr == 0 || (*wb_clause_ptr)->logic_type != CLAUSE) { - fprintf(stderr, "[%d]freeWhere: Where-builder stack corrupted!\n", __LINE__); - return; - } - - while (clause->n_values > 0) { - free(clause->values[clause->n_values - 1]); - clause->n_values--; - } - if (clause->values != 0) { - free(clause->values); - clause->values = 0; - } - if (clause->values_len != 0) { - free(clause->values_len); - clause->values_len = 0; - } - - if (clause->col != 0) { - free(clause->col); - clause->col = 0; - } - - if (clause->table) { - free(clause->table); - clause->table = 0; - } - - free(clause); - *wb_clause_ptr = 0; -} where_builder *clearWhereValue(where_builder *wb_clause) @@ -520,8 +169,8 @@ where_builder *setWhereValue_va(where_builder *wb_clause, case IN: case NOT_IN: { - if (ensureValueSize(clause, clause->n_values + n_args) != 0) { - freeWhere(&wb_clause); + if (ensureWhereValueSize(clause, clause->n_values + n_args) != 0) { + freeWhere(&clause); return 0; } @@ -587,7 +236,7 @@ where_builder *whereNotIn_va(where_builder *wb, const char *tbl, const char *col return where_In_notIn_va(wb, tbl, col, NOT_IN, type, n_args, args); } -where_builder *whereNext(where_builder *wb) +where_builder *nextWhere(where_builder *wb) { if (wb->up == 0) { fprintf(stderr, "[%d]whereEnd: Where-builder stack corrupted!\n", __LINE__); @@ -604,116 +253,3 @@ where_builder *finalizeWhere(where_builder *wb) return wb; } - -int compileWhere(where_builder *wb, char **str, size_t *str_len) -{ - where_logic *logic; - where_clause *clause; - struct str_builder_t *sb; - char *tmp; - size_t tmp_len; - size_t idx; - - sb = strbld_create(); - if (sb == 0) { - return -1; - } - - switch(wb->logic_type) { - case UNK: - strbld_destroy(&sb); - return -1; - case CLAUSE: - { - clause = (where_clause *)wb; - - // Column - if (clause->table != 0) { - strbld_char(sb, '`'); - strbld_str(sb, clause->table, clause->table_len); - strbld_char(sb, '`'); - strbld_char(sb, '.'); - } - strbld_char(sb, '`'); - strbld_str(sb, clause->col, clause->col_len); - strbld_char(sb, '`'); - strbld_char(sb, ' '); - - // Op - switch(clause->op) { - case EQ: - strbld_char(sb, '='); - break; - case NEQ: - strbld_char(sb, '!'); - strbld_char(sb, '='); - break; - case GT: - strbld_char(sb, '>'); - break; - case GTE: - strbld_char(sb, '>'); - strbld_char(sb, '='); - break; - case LT: - strbld_char(sb, '<'); - break; - case LTE: - strbld_char(sb, '<'); - strbld_char(sb, '='); - break; - case IS_NULL: - strbld_str(sb, "IS NULL", 7); - break; - case NOT_NULL: - strbld_str(sb, "IS NOT NULL", 11); - break; - case IN: - strbld_str(sb, "IN(", 3); - break; - case NOT_IN: - strbld_str(sb, "NOT IN(", 7); - break; - } - - // Value - for (idx = 0; idx < clause->n_values; idx++) { - strbld_char(sb, ' '); - strbld_str(sb, clause->values[idx], clause->values_len[idx]); - if (idx < clause->n_values - 1 && (clause->op == IN || clause->op == NOT_IN)) { - strbld_char(sb, ','); - } - } - - if (clause->op == IN || clause->op == NOT_IN) { - strbld_char(sb, ' '); - strbld_char(sb, ')'); - } - } - break; - case OR: - case AND: - { - logic = (where_logic *)wb; - - if (logic->n_constructs == 0) { - break; - } - - strbld_char(sb, '('); - for (size_t i = 0; i < logic->n_constructs; i++) { - if (compileWhere(logic->constructs[i], &tmp, &tmp_len) == 0) { - strbld_str(sb, tmp, tmp_len); - free(tmp); - } - if (i < (logic->n_constructs - 1)) { - strbld_str(sb, (wb->logic_type == OR ? " OR " : " AND "), (wb->logic_type == OR ? 4 : 5)); - } - } - strbld_char(sb, ')'); - break; - } - } - - return strbld_finalize_or_destroy(&sb, str, str_len); -} diff --git a/src/db_where-builder.h b/src/db_where-builder.h index db84327..66dfdfd 100644 --- a/src/db_where-builder.h +++ b/src/db_where-builder.h @@ -1,5 +1,5 @@ -#ifndef DB_WHEREBUILDER_H -#define DB_WHEREBUILDER_H +#ifndef H__DB_WHERE_BUILDER__ +#define H__DB_WHERE_BUILDER__ #include #include "db_column.h" @@ -35,6 +35,7 @@ typedef struct where_builder_t where_builder; where_builder *createWhereBuilder(where_builder *initial_clause); +int compileWhereBuilder(where_builder *wb, char **str, size_t *str_len); void destroyWhereBuilder(where_builder **wb_ptr); @@ -42,7 +43,6 @@ where_builder *where(const char *tbl, const char *col, e_where_op op, e_column_t uint32_t n_args, ...); where_builder *where_va(const char *tbl, const char *col, e_where_op op, e_column_type type, uint32_t n_args, va_list args); -void freeWhere(where_builder **wb_clause_ptr); where_builder *clearWhereValue(where_builder *wb_clause); @@ -63,10 +63,9 @@ where_builder *whereNotIn(where_builder *wb, const char *tbl, const char *col, where_builder *whereNotIn_va(where_builder *wb, const char *tbl, const char *col, e_column_type type, uint32_t n_args, va_list args); -where_builder *whereNext(where_builder *wb); +where_builder *nextWhere(where_builder *wb); where_builder *finalizeWhere(where_builder *wb); -int compileWhere(where_builder *wb, char **str, size_t *str_len); -#endif // DB_WHEREBUILDER_H +#endif // H__DB_WHERE_BUILDER__ diff --git a/src/db_where-builder_p.c b/src/db_where-builder_p.c new file mode 100644 index 0000000..37f3238 --- /dev/null +++ b/src/db_where-builder_p.c @@ -0,0 +1,448 @@ +#include "stdio.h" +#include "errno.h" +#include "string.h" + +#include "db_where-builder_p.h" +#include "strext.h" + + +where_logic *createLogic(e_where_logic type, size_t initial_size) +{ + where_logic *logic = (where_logic *)malloc(sizeof(where_logic)); + if (logic == 0) { + fprintf(stderr, "[%d]malloc: (%d) %s\n", __LINE__, errno, strerror(errno)); + return 0; + } + memset(logic, 0, sizeof(where_logic)); + + logic->logic_type = type; + + if (initial_size == 0) { + return logic; + } + + logic->clauses = (where_builder **)malloc(sizeof(where_builder *) * initial_size); + if (logic->clauses == 0) { + fprintf(stderr, "[%d]malloc: (%d) %s\n", __LINE__, errno, strerror(errno)); + freeLogic(&logic); + return 0; + } + memset(logic->clauses, 0, sizeof(where_builder *) * initial_size); + logic->n_clauses = 0; + logic->n_alloc = initial_size; + + return logic; +} +int compileLogic(where_logic *logic, char **str, size_t *str_len) +{ + struct str_builder_t *sb; + char *tmp; + size_t tmp_len; + + sb = strbld_create(); + if (sb == 0) { + *str = 0; + *str_len = 0; + return -1; + } + + if (logic->n_clauses == 0) { + return strbld_finalize_or_destroy(&sb, str, str_len); + } + + strbld_char(sb, '('); + for (size_t i = 0; i < logic->n_clauses; i++) { + if (compileWhereBuilder(logic->clauses[i], &tmp, &tmp_len) == 0) { + strbld_str(sb, tmp, tmp_len); + free(tmp); + } + if (i < (logic->n_clauses - 1)) { + if (logic->logic_type == OR) { + strbld_str(sb, " OR ", 4); + } else { + strbld_str(sb, " AND ", 5); + } + } + } + strbld_char(sb, ')'); + + return strbld_finalize_or_destroy(&sb, str, str_len); +} +void freeLogic(where_logic **logic_ptr) +{ + where_logic *logic; + where_builder *construct; + + logic = *logic_ptr; + while (logic->n_clauses > 0) { + construct = logic->clauses[logic->n_clauses - 1]; + construct->up = 0; + destroyWhereBuilder(&construct); + logic->n_clauses--; + } + if (logic->clauses != 0) { + free(logic->clauses); + logic->clauses = 0; + } + free(*logic_ptr); + *logic_ptr = 0; +} + +where_builder *appendLogicClause(where_builder *wb, where_builder *wb_clause) +{ + where_logic *logic = (where_logic *)wb; + where_builder **old_ptr; + size_t new_size; + + if (wb_clause == 0) { + return wb; + } + + if (!(wb->logic_type == AND || wb->logic_type == OR)) { + fprintf(stderr, "[%d]appendClause: Where-builder stack corrupted!\n", __LINE__); + return wb; + } + + if (logic->n_clauses == logic->n_alloc) { + old_ptr = (where_builder **)logic->clauses; + new_size = sizeof(where_builder *) * (logic->n_alloc + 1); + logic->clauses = (where_builder **)realloc(logic->clauses, new_size); + if (logic->clauses == 0) { + fprintf(stderr, "[%d]realloc: (%d) %s\n", __LINE__, errno, strerror(errno)); + logic->clauses = old_ptr; + return wb; + } + logic->n_alloc++; + } + + logic->clauses[logic->n_clauses] = wb_clause; + logic->n_clauses++; + wb_clause->up = (where_builder *)logic; + + return wb; +} + + +where_clause *createWhere(const char *tbl, const char *col, e_where_op op) +{ + where_clause *clause; + + clause = (where_clause *)malloc(sizeof(where_clause)); + if (clause == 0) { + fprintf(stderr, "[%d]malloc: (%d) %s\n", __LINE__, errno, strerror(errno)); + return 0; + } + memset(clause, 0, sizeof(where_clause)); + + clause->logic_type = CLAUSE; + clause->op = op; + + if (tbl != 0) { + if (strmemcpy(tbl, strlen(tbl), &clause->table, &clause->table_len) != 0) { + freeWhere(&clause); + return 0; + } + } + if (strmemcpy(col, strlen(col), &clause->col, &clause->col_len) != 0) { + freeWhere(&clause); + return 0; + } + + clause->values = (char **)malloc(sizeof(char *)); + clause->values_len = (size_t *)malloc(sizeof(size_t)); + if (clause->values == 0 || clause->values_len == 0) { + fprintf(stderr, "[%d]malloc: (%d) %s\n", __LINE__, errno, strerror(errno)); + freeWhere(&clause); + return 0; + } + clause->n_alloc = 1; + + return clause; +} +int compileWhere(where_clause *clause, char **str, size_t *str_len) +{ + struct str_builder_t *sb; + size_t idx; + + sb = strbld_create(); + if (sb == 0) { + return -1; + } + + // Column + if (clause->table != 0) { + strbld_char(sb, '`'); + strbld_str(sb, clause->table, clause->table_len); + strbld_char(sb, '`'); + strbld_char(sb, '.'); + } + strbld_char(sb, '`'); + strbld_str(sb, clause->col, clause->col_len); + strbld_char(sb, '`'); + strbld_char(sb, ' '); + + // Op + switch(clause->op) { + case EQ: + strbld_char(sb, '='); + break; + case NEQ: + strbld_char(sb, '!'); + strbld_char(sb, '='); + break; + case GT: + strbld_char(sb, '>'); + break; + case GTE: + strbld_char(sb, '>'); + strbld_char(sb, '='); + break; + case LT: + strbld_char(sb, '<'); + break; + case LTE: + strbld_char(sb, '<'); + strbld_char(sb, '='); + break; + case IS_NULL: + strbld_str(sb, "IS NULL", 7); + break; + case NOT_NULL: + strbld_str(sb, "IS NOT NULL", 11); + break; + case IN: + strbld_str(sb, "IN(", 3); + break; + case NOT_IN: + strbld_str(sb, "NOT IN(", 7); + break; + } + + // Value + for (idx = 0; idx < clause->n_values; idx++) { + strbld_char(sb, ' '); + strbld_str(sb, clause->values[idx], clause->values_len[idx]); + if (idx < clause->n_values - 1 && (clause->op == IN || clause->op == NOT_IN)) { + strbld_char(sb, ','); + } + } + + if (clause->op == IN || clause->op == NOT_IN) { + strbld_char(sb, ' '); + strbld_char(sb, ')'); + } + + return strbld_finalize_or_destroy(&sb, str, str_len); +} +void freeWhere(where_clause **where_ptr) +{ + where_clause *clause = *where_ptr; + + while (clause->n_values > 0) { + free(clause->values[clause->n_values - 1]); + clause->n_values--; + } + if (clause->values != 0) { + free(clause->values); + clause->values = 0; + } + if (clause->values_len != 0) { + free(clause->values_len); + clause->values_len = 0; + } + + if (clause->col != 0) { + free(clause->col); + clause->col = 0; + } + + if (clause->table) { + free(clause->table); + clause->table = 0; + } + + free(clause); + *where_ptr = 0; +} + +int ensureWhereValueSize(where_clause *clause, size_t new_size) +{ + size_t *old_lens; + char **old_values; + + if (clause->n_alloc >= new_size) { + return 0; + } + + old_values = clause->values; + clause->values = (char **)realloc(clause->values, sizeof(char *) * new_size); + if (clause->values == 0) { + fprintf(stderr, "[%d]realloc: (%d) %s\n", __LINE__, errno, strerror(errno)); + clause->values = old_values; + return 1; + } + + old_lens = clause->values_len; + clause->values_len = (size_t *)realloc(clause->values_len, sizeof(size_t) * new_size); + if (clause->values_len == 0) { + fprintf(stderr, "[%d]realloc: (%d) %s\n", __LINE__, errno, strerror(errno)); + clause->values_len = old_lens; + return 1; + } + + (clause->n_alloc)++; + + return 0; +} + + +where_builder *where_And_Or(where_builder *wb, where_builder *wb_clause, e_where_logic and_or) +{ + where_logic *logic; + + if (wb == 0) { + wb = (where_builder *)createLogic(and_or, 2); + if (wb == 0) { + return wb_clause; + } + } + + switch(wb->logic_type) { + case UNK: + { + if ((logic = createLogic(and_or, 2)) == 0) { + destroyWhereBuilder(&wb_clause); + return wb; + } + free(wb); + if (wb_clause != 0) { + logic->clauses[0] = wb_clause; + logic->n_clauses++; + wb_clause->up = (where_builder *)logic; + } + wb = (where_builder *)logic; + break; + } + + case CLAUSE: + { + if ((logic = createLogic(and_or, 2)) == 0) { + destroyWhereBuilder(&wb_clause); + return wb; + } + logic->clauses[0] = wb; + logic->n_clauses++; + wb->up = (where_builder *)logic; + if (wb_clause != 0) { + logic->clauses[1] = wb_clause; + logic->n_clauses++; + wb_clause->up = (where_builder *)logic; + } + wb = (where_builder *)logic; + break; + } + + case OR: + { + if (and_or == AND) { + if ((logic = createLogic(AND, 2)) == 0) { + destroyWhereBuilder(&wb_clause); + return wb; + } + if (whereOr(wb, (where_builder *)logic) == 0) { + freeLogic(&logic); + destroyWhereBuilder(&wb_clause); + return wb; + } + wb = appendLogicClause((where_builder *)logic, wb_clause); + } else { + wb = appendLogicClause(wb, wb_clause); + } + break; + } + + case AND: + { + if (and_or == AND) { + wb = appendLogicClause(wb, wb_clause); + } else { + if ((logic = createLogic(OR, 2)) == 0) { + destroyWhereBuilder(&wb_clause); + return wb; + } + if (whereAnd(wb, (where_builder *)logic) == 0) { + freeLogic(&logic); + destroyWhereBuilder(&wb_clause); + return wb; + } + wb = appendLogicClause((where_builder *)logic, wb_clause); + } + break; + } + } + + return wb; +} +where_builder *where_In_notIn(where_builder *wb, const char *tbl, const char *col, e_where_op op, + e_column_type type, uint32_t n_args, ...) +{ + where_builder *ret; + va_list args; + + va_start(args, n_args); + ret = where_In_notIn_va(wb, tbl, col, op, type, n_args, args); + va_end(args); + + return ret; +} +where_builder *where_In_notIn_va(where_builder *wb, const char *tbl, const char *col, e_where_op op, + e_column_type type, uint32_t n_args, va_list args) +{ + where_clause *clause; + where_builder *wb_clause; + + if (wb == 0) { + return where_va(tbl, col, op, type, n_args, args); + } + + switch (wb->logic_type) { + case UNK: + { + free(wb); + return where_va(tbl, col, op, type, n_args, args); + } + case CLAUSE: + { + clause = (where_clause *)wb; + if (clause->op != op + || (tbl != 0 && clause->table == 0) + || (tbl != 0 && clause->table != 0 && strcmp(clause->table, tbl) != 0) + || (col != 0 && clause->col == 0) + || (col != 0 && clause->col != 0 && strcmp(clause->col, col) != 0)) { + if (wb->up == 0) { + fprintf(stderr, "[%d]whereIn_notIn: Where-builder stack corrupted!\n", __LINE__); + return wb; + } + return where_In_notIn_va(wb->up, tbl, col, op, type, n_args, args); + } + + return setWhereValue_va((where_builder *)clause, type, n_args, args); + } + case AND: + case OR: + { + if ((wb_clause = where_va(tbl, col, op, type, n_args, args)) == 0) { + return wb; + } + if (wb->logic_type == AND) { + whereAnd(wb, wb_clause); + } else { + whereOr(wb, wb_clause); + } + return wb_clause; + } + } + + return wb; +} + diff --git a/src/db_where-builder_p.h b/src/db_where-builder_p.h new file mode 100644 index 0000000..c85d689 --- /dev/null +++ b/src/db_where-builder_p.h @@ -0,0 +1,60 @@ +#ifndef H__DB_WHERE_BUILDER_P__ +#define H__DB_WHERE_BUILDER_P__ + +#include "db_where-builder.h" + +struct where_logic_t { + where_builder *up; + e_where_logic logic_type; + + where_builder **clauses; + size_t n_clauses; + size_t n_alloc; +}; +typedef struct where_logic_t where_logic; + +struct where_clause_t { + where_builder *up; + e_where_logic logic_type; + + // Table + char *table; + size_t table_len; + + // Column + char *col; + size_t col_len; + + // Op + e_where_op op; + + // Values + char **values; + size_t *values_len; + size_t n_values; + size_t n_alloc; +}; +typedef struct where_clause_t where_clause; + + +where_logic *createLogic(e_where_logic type, size_t initial_size); +int compileLogic(where_logic *logic, char **str, size_t *str_len); +void freeLogic(where_logic **logic_ptr); + +where_builder *appendLogicClause(where_builder *wb, where_builder *wb_clause); + + +where_clause *createWhere(const char *tbl, const char *col, e_where_op op); +int compileWhere(where_clause *clause, char **str, size_t *str_len); +void freeWhere(where_clause **where_ptr); + +int ensureWhereValueSize(where_clause *clause, size_t new_size); + + +where_builder *where_And_Or(where_builder *wb, where_builder *wb_clause, e_where_logic and_or); +where_builder *where_In_notIn(where_builder *wb, const char *tbl, const char *col, e_where_op op, + e_column_type type, uint32_t n_args, ...); +where_builder *where_In_notIn_va(where_builder *wb, const char *tbl, const char *col, e_where_op op, + e_column_type type, uint32_t n_args, va_list args); + +#endif // H__DB_WHERE_BUILDER_P__ diff --git a/src/strext.h b/src/strext.h index 57493c9..c8e9b02 100644 --- a/src/strext.h +++ b/src/strext.h @@ -1,5 +1,5 @@ -#ifndef H__STRCMB__ -#define H__STRCMB__ +#ifndef H__STREXT__ +#define H__STREXT__ #include @@ -29,4 +29,4 @@ int strbld_ensure_len(str_builder *sb, size_t len, int absolute); int strbld_str(str_builder *sb, const char *str, size_t len); int strbld_char(str_builder *sb, const char c); -#endif // H__STRCMB__ +#endif // H__STREXT__