Created a bunch of convenience functions in db_ (1 of 2)

This commit is contained in:
2020-10-08 12:32:07 +01:00
parent 83a9093d97
commit e0d0515188
6 changed files with 257 additions and 95 deletions

View File

@@ -1,4 +1,4 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
@@ -9,6 +9,7 @@
#include "strext.h" #include "strext.h"
// PRIVATE
size_t columnTypeToByteSize(e_column_type type) size_t columnTypeToByteSize(e_column_type type)
{ {
switch(type) { switch(type) {
@@ -52,7 +53,6 @@ size_t columnTypeToByteSize(e_column_type type)
} }
return sizeof(char *); return sizeof(char *);
} }
e_column_type simplifyFieldType(enum enum_field_types sql_type, int is_unsigned) e_column_type simplifyFieldType(enum enum_field_types sql_type, int is_unsigned)
{ {
switch(sql_type) { switch(sql_type) {
@@ -115,6 +115,7 @@ e_column_type simplifyFieldType(enum enum_field_types sql_type, int is_unsigned)
} }
// PUBLIC
struct column_data_t *initEmptyColumn(e_column_type type, int nullable, const char *name, struct column_data_t *initEmptyColumn(e_column_type type, int nullable, const char *name,
size_t name_len, const char *table, size_t table_len) size_t name_len, const char *table, size_t table_len)
{ {
@@ -150,8 +151,8 @@ struct column_data_t *initEmptyColumn(e_column_type type, int nullable, const ch
col->n_values = 0; col->n_values = 0;
col->hasPointers = col->type == TYPE_STRING col->hasPointers = col->type == TYPE_STRING
|| col->type == TYPE_BLOB || col->type == TYPE_BLOB
|| col->type == TYPE_RAW; || col->type == TYPE_RAW;
col->isUnsigned = col->type == TYPE_UINT8 col->isUnsigned = col->type == TYPE_UINT8
|| col->type == TYPE_UINT16 || col->type == TYPE_UINT16
|| col->type == TYPE_UINT32 || col->type == TYPE_UINT32
@@ -163,9 +164,8 @@ struct column_data_t *initEmptyColumn(e_column_type type, int nullable, const ch
return col; return col;
} }
struct column_data_t *createColumnFromResult(struct stored_conn_t *sconn, MYSQL_RES *result,
struct column_data_t *columnFromResult(struct stored_conn_t *sconn, MYSQL_RES *result, uint64_t num_rows)
uint64_t num_rows)
{ {
MYSQL_FIELD *field; MYSQL_FIELD *field;
struct column_data_t *col; struct column_data_t *col;
@@ -173,9 +173,9 @@ struct column_data_t *columnFromResult(struct stored_conn_t *sconn, MYSQL_RES *r
field = mysql_fetch_field(result); field = mysql_fetch_field(result);
if (field == NULL) { if (field == NULL) {
fprintf( fprintf(
stderr, "[%d]mysql_fetch_field: (%d) %s\n", stderr, "[%d]mysql_fetch_field: (%d) %s\n",
__LINE__, mysql_errno(SQCONN(sconn)), mysql_error(SQCONN(sconn)) __LINE__, mysql_errno(SQCONN(sconn)), mysql_error(SQCONN(sconn))
); );
return 0; return 0;
} }
@@ -290,8 +290,8 @@ void freeColumns(struct column_data_t **col_data, size_t n_cols)
free(col_data); free(col_data);
} }
int setColumnValueFromResult(struct column_data_t *col, uint64_t row,
int setColumnValue(struct column_data_t *col, uint64_t row, const char *value, size_t value_size) const char *value, size_t value_size)
{ {
if (value == NULL) { if (value == NULL) {
columnRowSetNull(col, row); columnRowSetNull(col, row);
@@ -401,7 +401,8 @@ int setColumnValue(struct column_data_t *col, uint64_t row, const char *value, s
return 0; return 0;
} }
struct column_data_t *findColumn(struct column_data_t **col_data, size_t n_cols, const char *name) struct column_data_t *findColumnByName(struct column_data_t **col_data, size_t n_cols,
const char *name)
{ {
struct column_data_t *col = 0; struct column_data_t *col = 0;
size_t idx = 0; size_t idx = 0;
@@ -418,25 +419,105 @@ struct column_data_t *findColumn(struct column_data_t **col_data, size_t n_cols,
return 0; return 0;
} }
char *createColumn(struct column_data_t *col, char **str, size_t *len)
int columnRowIsNull(struct column_data_t *col, uint64_t row)
{
return col->isNullable && (*(col->nulls + (row / 8)) & (1 << (row % 8))) > 0;
}
void columnRowSetNull(struct column_data_t *col, uint64_t row)
{
if (col->isNullable) {
*(col->nulls + (row / 8)) |= (1 << (row % 8));
}
}
void columnRowClearNull(struct column_data_t *col, uint64_t row)
{
if (col->isNullable) {
*(col->nulls + (row / 8)) &= ~(1 << (row % 8));
}
}
char *escapeColumnName(char **str, size_t *len,
const char *table, size_t table_len, const char *col, size_t col_len)
{ {
str_builder *sb; str_builder *sb;
if ((sb = strbld_create()) == 0) { if ((sb = strbld_create()) == 0) {
return 0; return 0;
} }
createColumn_sb(sb, col); escapeColumnName_sb(sb, table, table_len, col, col_len);
if (strbld_finalize_or_destroy(&sb, str, len) != 0) { if (strbld_finalize_or_destroy(&sb, str, len) != 0) {
return 0; return 0;
} }
return *str; return *str;
} }
void createColumn_sb(str_builder *sb, struct column_data_t *col) void escapeColumnName_sb(str_builder *sb,
const char *table, size_t table_len, const char *col, size_t col_len)
{ {
strbld_str(sb, ", `", 3); if (table != 0) {
strbld_str(sb, col->name, col->name_len); strbld_char(sb,'`');
strbld_str(sb, "` ", 2); strbld_str(sb, table, table_len);
strbld_char(sb,'`');
strbld_char(sb,'.');
}
strbld_char(sb,'`');
strbld_str(sb, col, col_len);
strbld_char(sb,'`');
}
char *escapeColumnNameAs(char **str, size_t *len, const char *tbl, size_t tbl_len,
const char *col, size_t col_len, const char *as, size_t as_len)
{
str_builder *sb;
if ((sb = strbld_create()) == 0) {
return 0;
}
escapeColumnNameAs_sb(sb, tbl, tbl_len, col, col_len, as, as_len);
if (strbld_finalize_or_destroy(&sb, str, len) != 0) {
return 0;
}
return *str;
}
void escapeColumnNameAs_sb(str_builder *sb, const char *tbl, size_t tbl_len,
const char *col, size_t col_len, const char *as, size_t as_len)
{
escapeColumnName_sb(sb, tbl, tbl_len, col, col_len);
strbld_str(sb, " AS ", 4);
escapeColumnName_sb(sb, 0, 0, as, as_len);
}
char *escapeTableName(char **str, size_t *len, const char *table, size_t table_len)
{
return escapeColumnName(str, len, 0, 0, table, table_len);
}
void escapeTableName_sb(str_builder *sb, const char *table, size_t table_len)
{
escapeColumnName_sb(sb, 0, 0, table, table_len);
}
char *columnCreateStr(char **str, size_t *len, struct column_data_t *col)
{
str_builder *sb;
if ((sb = strbld_create()) == 0) {
return 0;
}
columnCreateStr_sb(sb, col);
if (strbld_finalize_or_destroy(&sb, str, len) != 0) {
return 0;
}
return *str;
}
void columnCreateStr_sb(str_builder *sb, struct column_data_t *col)
{
escapeColumnName_sb(sb, 0, 0, col->name, col->name_len);
strbld_char(sb, ' ');
switch(col->type) { switch(col->type) {
case TYPE_RAW: case TYPE_RAW:
@@ -495,3 +576,79 @@ void createColumn_sb(str_builder *sb, struct column_data_t *col)
strbld_str(sb, " AUTO_INCREMENT", 0); strbld_str(sb, " AUTO_INCREMENT", 0);
} }
} }
char *columnSetValueStr(char **set, size_t *set_len,
const char *column, e_column_type type, uint32_t n_args, ...)
{
va_list args;
va_start(args, n_args);
columnSetValueStr_va(set, set_len, column, type, n_args, args);
va_end(args);
return *set;
}
char *columnSetValueStr_va(char **set, size_t *set_len,
const char *column, e_column_type type, uint32_t n_args, va_list args)
{
str_builder *sb;
if ((sb = strbld_create()) == 0) {
return 0;
}
columnSetValueStr_sbva(sb, column, type, n_args, args);
if (strbld_finalize_or_destroy(&sb, set, set_len) != 0) {
return 0;
}
return *set;
}
void columnSetValueStr_sb(str_builder *sb,
const char *column, e_column_type type, uint32_t n_args, ...)
{
va_list args;
va_start(args, n_args);
columnSetValueStr_sbva(sb, column, type, n_args, args);
va_end(args);
}
void columnSetValueStr_sbva(str_builder *sb,
const char *column, e_column_type type, uint32_t n_args, va_list args)
{
escapeColumnName_sb(sb, 0, 0, column, 0);
strbld_str(sb, " = ", 0);
db_value_sbva(sb, type, n_args, args);
}
char *joinStr(char **str, size_t *len,
const char *join_type, size_t join_type_len, int is_equals,
const char *tableA, size_t tableA_len, const char *colA, size_t colA_len,
const char *tableB, size_t tableB_len, const char *colB, size_t colB_len)
{
str_builder *sb;
if ((sb = strbld_create()) == 0) {
return 0;
}
joinStr_sb(sb, join_type, join_type_len, is_equals,
tableA, tableA_len, colA, colA_len,
tableB, tableB_len, colB, colB_len);
if (strbld_finalize_or_destroy(&sb, str, len) != 0) {
return 0;
}
return *str;
}
void joinStr_sb(str_builder *sb,
const char *join_type, size_t join_type_len, int is_equals,
const char *tableA, size_t tableA_len, const char *colA, size_t colA_len,
const char *tableB, size_t tableB_len, const char *colB, size_t colB_len)
{
strbld_str(sb, join_type, join_type_len);
strbld_str(sb, " JOIN ", 6);
escapeTableName_sb(sb, tableA, tableA_len);
strbld_str(sb, " ON ", 4);
escapeColumnName_sb(sb, tableA, tableA_len, colA, colA_len);
strbld_str(sb, (is_equals ? " = " : " != "), (is_equals ? 3 : 4));
escapeColumnName_sb(sb, tableB, tableB_len, colB, colB_len);
}

View File

@@ -76,39 +76,64 @@ struct column_data_t {
typedef struct column_data_t column_data; typedef struct column_data_t column_data;
// Null column value handling - maybe convert these to macros?
static inline int columnRowIsNull(struct column_data_t *col, uint64_t row)
{
return col->isNullable && (*(col->nulls + (row / 8)) & (1 << (row % 8))) > 0;
}
static inline void columnRowSetNull(struct column_data_t *col, uint64_t row)
{
if (col->isNullable) {
*(col->nulls + (row / 8)) |= (1 << (row % 8));
}
}
static inline void columnRowClearNull(struct column_data_t *col, uint64_t row)
{
if (col->isNullable) {
*(col->nulls + (row / 8)) &= ~(1 << (row % 8));
}
}
struct column_data_t *initEmptyColumn(e_column_type type, int nullable, const char *name, struct column_data_t *initEmptyColumn(e_column_type type, int nullable, const char *name,
size_t name_len, const char *table, size_t table_len); size_t name_len, const char *table, size_t table_len);
struct column_data_t *columnFromResult(struct stored_conn_t *sconn, MYSQL_RES *result, struct column_data_t *createColumnFromResult(struct stored_conn_t *sconn, MYSQL_RES *result,
uint64_t num_rows); uint64_t num_rows);
void freeColumn(struct column_data_t *col); void freeColumn(struct column_data_t *col);
void freeColumns(struct column_data_t **col_data, size_t n_cols); void freeColumns(struct column_data_t **col_data, size_t n_cols);
int setColumnValue(struct column_data_t *col, uint64_t row, const char *value, size_t value_size); int setColumnValueFromResult(struct column_data_t *col, uint64_t row,
const char *value, size_t value_size);
struct column_data_t *findColumn(struct column_data_t **col_data, size_t n_cols, struct column_data_t *findColumnByName(struct column_data_t **col_data, size_t n_cols,
const char *name); const char *name);
int columnRowIsNull(struct column_data_t *col, uint64_t row);
void columnRowSetNull(struct column_data_t *col, uint64_t row);
void columnRowClearNull(struct column_data_t *col, uint64_t row);
char *createColumn(struct column_data_t *col_data, char **str, size_t *len); char *escapeColumnName(char **str, size_t *len,
void createColumn_sb(str_builder *sb, struct column_data_t *col); const char *table, size_t table_len,
const char *column, size_t column_len);
void escapeColumnName_sb(str_builder *sb,
const char *table, size_t table_len,
const char *column, size_t column_len);
char *escapeColumnNameAs(char **str, size_t *len,
const char *table, size_t table_len,
const char *column, size_t column_len,
const char *as_column, size_t as_column_len);
void escapeColumnNameAs_sb(str_builder *sb,
const char *table, size_t table_len,
const char *column, size_t column_len,
const char *as_column, size_t as_column_len);
char *escapeTableName(char **str, size_t *len, const char *table, size_t table_len);
void escapeTableName_sb(str_builder *sb, const char *table, size_t table_len);
char *columnCreateStr(char **str, size_t *len, struct column_data_t *col);
void columnCreateStr_sb(str_builder *sb, struct column_data_t *col);
char *columnSetValueStr(char **set, size_t *set_len,
const char *column, e_column_type type, uint32_t n_args, ...);
char *columnSetValueStr_va(char **set, size_t *set_len,
const char *column, e_column_type type, uint32_t n_args, va_list args);
void columnSetValueStr_sb(str_builder *sb,
const char *column, e_column_type type, uint32_t n_args, ...);
void columnSetValueStr_sbva(str_builder *sb,
const char *column, e_column_type type, uint32_t n_args, va_list args);
char *joinStr(char **str, size_t *len,
const char *join_type, size_t join_type_len, int is_equals,
const char *tableA, size_t tableA_len, const char *colA, size_t colA_len,
const char *tableB, size_t tableB_len, const char *colB, size_t colB_len);
void joinStr_sb(str_builder *sb,
const char *join_type, size_t join_type_len, int is_equals,
const char *tableA, size_t tableA_len, const char *colA, size_t colA_len,
const char *tableB, size_t tableB_len, const char *colB, size_t colB_len);
#endif // H__DB_COLUMN__ #endif // H__DB_COLUMN__

View File

@@ -114,7 +114,7 @@ uint64_t tableQuery(struct stored_conn_t *sconn, const char *qry, size_t qry_len
for (unsigned int i = 0; i < *n_cols; i++) { for (unsigned int i = 0; i < *n_cols; i++) {
*(col_data + i) = columnFromResult(sconn, result, n_rows); *(col_data + i) = createColumnFromResult(sconn, result, n_rows);
if (*(col_data + i) == 0) { if (*(col_data + i) == 0) {
failed++; failed++;
@@ -146,7 +146,7 @@ uint64_t tableQuery(struct stored_conn_t *sconn, const char *qry, size_t qry_len
for (unsigned int c = 0; c < *n_cols; c++) { for (unsigned int c = 0; c < *n_cols; c++) {
struct column_data_t *col = (*(col_data + c)); struct column_data_t *col = (*(col_data + c));
if (setColumnValue(col, r, *(row + c), *(lens + c)) < 0) { if (setColumnValueFromResult(col, r, *(row + c), *(lens + c)) < 0) {
failed++; failed++;
} }
} }

View File

@@ -38,26 +38,8 @@ int compileWhereBuilder(where_builder *wb, char **str, size_t *str_len, int free
} }
void compileWhereBuilder_sb(where_builder *wb, str_builder *sb, int free_wb) void compileWhereBuilder_sb(where_builder *wb, str_builder *sb, int free_wb)
{ {
switch(wb->logic_type) { strbld_str(sb, " WHERE ", 7);
case CLAUSE: do_compileWhereBuilder_sb(wb, sb, free_wb);
{
compileWhere_sb((where_clause *)wb, sb);
break;
}
case OR:
case AND:
{
compileLogic_sb((where_logic *)wb, sb);
break;
}
default:
{
break;
}
}
if (free_wb) {
freeWhereBuilder(&wb);
}
} }
void freeWhereBuilder(where_builder **wb_ptr) void freeWhereBuilder(where_builder **wb_ptr)
{ {

View File

@@ -4,6 +4,29 @@
#include "db_where-builder_p.h" #include "db_where-builder_p.h"
void do_compileWhereBuilder_sb(where_builder *wb, str_builder *sb, int free_wb)
{
switch(wb->logic_type) {
case CLAUSE:
{
compileWhere_sb((where_clause *)wb, sb);
break;
}
case OR:
case AND:
{
compileLogic_sb((where_logic *)wb, sb);
break;
}
default:
{
break;
}
}
if (free_wb) {
freeWhereBuilder(&wb);
}
}
where_logic *createLogic(e_where_logic type, size_t initial_size) where_logic *createLogic(e_where_logic type, size_t initial_size)
{ {
@@ -32,18 +55,6 @@ where_logic *createLogic(e_where_logic type, size_t initial_size)
return logic; return logic;
} }
int compileLogic(where_logic *logic, char **str, size_t *str_len)
{
struct str_builder_t *sb;
if ((sb = strbld_create()) == 0) {
return -1;
}
compileLogic_sb(logic, sb);
return strbld_finalize_or_destroy(&sb, str, str_len);
}
void compileLogic_sb(where_logic *logic, str_builder *sb) void compileLogic_sb(where_logic *logic, str_builder *sb)
{ {
if (logic->n_clauses == 0) { if (logic->n_clauses == 0) {
@@ -52,7 +63,7 @@ void compileLogic_sb(where_logic *logic, str_builder *sb)
strbld_char(sb, '('); strbld_char(sb, '(');
for (size_t i = 0; i < logic->n_clauses; i++) { for (size_t i = 0; i < logic->n_clauses; i++) {
compileWhereBuilder_sb(logic->clauses[i], sb, 0); do_compileWhereBuilder_sb(logic->clauses[i], sb, 0);
if (i < (logic->n_clauses - 1)) { if (i < (logic->n_clauses - 1)) {
if (logic->logic_type == OR) { if (logic->logic_type == OR) {
strbld_str(sb, " OR ", 4); strbld_str(sb, " OR ", 4);
@@ -154,18 +165,6 @@ where_clause *createWhere(const char *tbl, const char *col, e_where_op op)
return clause; return clause;
} }
int compileWhere(where_clause *clause, char **str, size_t *str_len)
{
struct str_builder_t *sb;
if ((sb = strbld_create()) == 0) {
return -1;
}
compileWhere_sb(clause, sb);
return strbld_finalize_or_destroy(&sb, str, str_len);
}
void compileWhere_sb(where_clause *clause, str_builder *sb) void compileWhere_sb(where_clause *clause, str_builder *sb)
{ {
size_t idx; size_t idx;

View File

@@ -50,9 +50,10 @@ struct where_clause_t {
typedef struct where_clause_t where_clause; typedef struct where_clause_t where_clause;
DLL_LOCAL DLL_LOCAL
where_logic *createLogic(e_where_logic type, size_t initial_size); void do_compileWhereBuilder_sb(where_builder *wb, str_builder *sb, int free_wb);
DLL_LOCAL DLL_LOCAL
int compileLogic(where_logic *logic, char **str, size_t *str_len); where_logic *createLogic(e_where_logic type, size_t initial_size);
DLL_LOCAL DLL_LOCAL
void compileLogic_sb(where_logic *logic, str_builder *sb); void compileLogic_sb(where_logic *logic, str_builder *sb);
DLL_LOCAL DLL_LOCAL
@@ -64,8 +65,6 @@ where_builder *appendLogicClause(where_builder *wb, where_builder *wb_clause);
DLL_LOCAL DLL_LOCAL
where_clause *createWhere(const char *tbl, const char *col, e_where_op op); where_clause *createWhere(const char *tbl, const char *col, e_where_op op);
DLL_LOCAL DLL_LOCAL
int compileWhere(where_clause *clause, char **str, size_t *str_len);
DLL_LOCAL
void compileWhere_sb(where_clause *clause, str_builder *sb); void compileWhere_sb(where_clause *clause, str_builder *sb);
DLL_LOCAL DLL_LOCAL
void freeWhere(where_clause **where_ptr); void freeWhere(where_clause **where_ptr);