|
|
|
|
@@ -3,52 +3,548 @@
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
|
|
|
|
#include "database.h"
|
|
|
|
|
#include "modb_metadata_ext.h"
|
|
|
|
|
#include "modb_p.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct metadata_ext_t *allocMetadataExt(void)
|
|
|
|
|
// ##### PRIVATE
|
|
|
|
|
int tableRowsToMetaExtList(column_data **col_data, size_t n_cols,
|
|
|
|
|
struct meta_ext_t ***ext_list, size_t *n_exts)
|
|
|
|
|
{
|
|
|
|
|
struct metadata_ext_t *metadata_ext;
|
|
|
|
|
column_data *col_id, *col;
|
|
|
|
|
size_t n_rows, r_idx, c_idx, v_idx;
|
|
|
|
|
struct meta_ext_t *ext;
|
|
|
|
|
struct meta_ext_value_t *ext_value;
|
|
|
|
|
size_t key_len;
|
|
|
|
|
|
|
|
|
|
metadata_ext = malloc(sizeof(struct metadata_ext_t));
|
|
|
|
|
n_rows = (*col_data)->n_values;
|
|
|
|
|
if (n_rows == 0) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
col_id = findColumnByName(col_data, n_cols, "mdo_id");
|
|
|
|
|
|
|
|
|
|
if ((*ext_list = allocMetaExtList(n_rows)) == 0) {
|
|
|
|
|
fprintf(stderr, "[%d]malloc: (%d) %s\n", __LINE__, errno, strerror(errno));
|
|
|
|
|
return -errno;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (r_idx = 0; r_idx < n_rows; r_idx++) {
|
|
|
|
|
if ((ext = allocMetaExt()) == 0) {
|
|
|
|
|
freeMetaExtList(ext_list, r_idx - 1);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
*((*ext_list) + r_idx) = ext;
|
|
|
|
|
|
|
|
|
|
ext->id = *(col_id->data.ptr_uint32 + r_idx);
|
|
|
|
|
|
|
|
|
|
if (n_cols > 0) {
|
|
|
|
|
if ((ext->values = allocMetaExtValues(n_cols - 1, 1)) == 0) {
|
|
|
|
|
freeMetaExtList(ext_list, r_idx);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
ext->n_values = n_cols - 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (c_idx = 0, v_idx = 0; c_idx < n_cols; c_idx++, v_idx++) {
|
|
|
|
|
col = *(col_data + c_idx);
|
|
|
|
|
if (col == col_id) {
|
|
|
|
|
v_idx--;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
ext_value = *(ext->values + v_idx);
|
|
|
|
|
|
|
|
|
|
if (strmemcpy(col->name, col->name_len, &ext_value->key, &key_len) != 0) {
|
|
|
|
|
freeMetaExtList(ext_list, r_idx);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
ext_value->key_c = ext_value->key;
|
|
|
|
|
|
|
|
|
|
switch(col->type) {
|
|
|
|
|
case TYPE_RAW:
|
|
|
|
|
ext_value->type = VTYPE_RAW;
|
|
|
|
|
if (!moveColumnBlobPointer(col, r_idx, 1, (char **)&ext_value->value.raw, &ext_value->value_len)) {
|
|
|
|
|
freeMetaExtList(ext_list, r_idx);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case TYPE_BOOL:
|
|
|
|
|
ext_value->type = VTYPE_BOOL;
|
|
|
|
|
ext_value->value.int32 = *(col->data.ptr_uint8 + r_idx);
|
|
|
|
|
break;
|
|
|
|
|
case TYPE_INT8:
|
|
|
|
|
ext_value->type = VTYPE_INT32;
|
|
|
|
|
ext_value->value.int32 = *(col->data.ptr_int8 + r_idx);
|
|
|
|
|
break;
|
|
|
|
|
case TYPE_UINT8:
|
|
|
|
|
ext_value->type = VTYPE_INT32;
|
|
|
|
|
ext_value->value.int32 = *(col->data.ptr_uint8 + r_idx);
|
|
|
|
|
break;
|
|
|
|
|
case TYPE_INT16:
|
|
|
|
|
ext_value->type = VTYPE_INT32;
|
|
|
|
|
ext_value->value.int32 = *(col->data.ptr_int16 + r_idx);
|
|
|
|
|
break;
|
|
|
|
|
case TYPE_UINT16:
|
|
|
|
|
ext_value->type = VTYPE_INT32;
|
|
|
|
|
ext_value->value.int32 = *(col->data.ptr_uint16 + r_idx);
|
|
|
|
|
break;
|
|
|
|
|
case TYPE_INT32:
|
|
|
|
|
ext_value->type = VTYPE_INT32;
|
|
|
|
|
ext_value->value.int32 = *(col->data.ptr_int32 + r_idx);
|
|
|
|
|
break;
|
|
|
|
|
case TYPE_UINT32:
|
|
|
|
|
ext_value->type = VTYPE_INT32;
|
|
|
|
|
ext_value->value.dbl = (double)*(col->data.ptr_uint32 + r_idx);
|
|
|
|
|
break;
|
|
|
|
|
case TYPE_INT64:
|
|
|
|
|
ext_value->type = VTYPE_INT32;
|
|
|
|
|
ext_value->value.dbl = (double)*(col->data.ptr_int64 + r_idx);
|
|
|
|
|
break;
|
|
|
|
|
case TYPE_UINT64:
|
|
|
|
|
ext_value->type = VTYPE_INT32;
|
|
|
|
|
ext_value->value.dbl = (double)*(col->data.ptr_uint64 + r_idx);
|
|
|
|
|
break;
|
|
|
|
|
case TYPE_FLOAT:
|
|
|
|
|
ext_value->type = VTYPE_INT32;
|
|
|
|
|
ext_value->value.dbl = (double)*(col->data.ptr_float + r_idx);
|
|
|
|
|
break;
|
|
|
|
|
case TYPE_DOUBLE:
|
|
|
|
|
ext_value->type = VTYPE_DOUBLE;
|
|
|
|
|
ext_value->value.dbl = *(col->data.ptr_double + r_idx);
|
|
|
|
|
break;
|
|
|
|
|
case TYPE_STRING:
|
|
|
|
|
ext_value->type = VTYPE_STRING;
|
|
|
|
|
if (!moveColumnStrPointer(col, r_idx, 1, &ext_value->value.str, &ext_value->value_len)) {
|
|
|
|
|
freeMetaExtList(ext_list, r_idx);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case TYPE_BLOB:
|
|
|
|
|
ext_value->type = VTYPE_RAW;
|
|
|
|
|
if (!moveColumnBlobPointer(col, r_idx, 1, (char **)&ext_value->value.raw, &ext_value->value_len)) {
|
|
|
|
|
freeMetaExtList(ext_list, r_idx);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case TYPE_TIMESTAMP:
|
|
|
|
|
ext_value->type = VTYPE_TIMESTAMP;
|
|
|
|
|
ext_value->value.ts = *(col->data.ptr_int64 + r_idx);
|
|
|
|
|
break;
|
|
|
|
|
case TYPE_ID:
|
|
|
|
|
ext_value->type = VTYPE_ID;
|
|
|
|
|
ext_value->value.id = *(col->data.ptr_uint32 + r_idx);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*n_exts = n_rows;
|
|
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
int doMetaExtListQuery(stored_conn *sconn, modb_ref *modb, where_builder *wb,
|
|
|
|
|
struct meta_ext_t ***ext_list, size_t *n_exts)
|
|
|
|
|
{
|
|
|
|
|
char *tbl_meta, *tbl_ext;
|
|
|
|
|
size_t len_meta, len_ext;
|
|
|
|
|
char *qry;
|
|
|
|
|
size_t qry_len;
|
|
|
|
|
uint64_t qry_ret;
|
|
|
|
|
int res;
|
|
|
|
|
|
|
|
|
|
str_builder *sb;
|
|
|
|
|
|
|
|
|
|
column_data **col_data;
|
|
|
|
|
size_t n_cols;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((sb = strbld_create()) == 0) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
modbTableName(&tbl_ext, &len_ext, modb, META_EXT_TABLE, strlen(META_EXT_TABLE));
|
|
|
|
|
modbTableName(&tbl_meta, &len_meta, modb, METADATA_TABLE, strlen(METADATA_TABLE));
|
|
|
|
|
|
|
|
|
|
strbld_str(sb, "SELECT ", 0);
|
|
|
|
|
escapeColumnName_sb(sb, tbl_ext, len_ext, "*", 0);
|
|
|
|
|
strbld_str(sb, " FROM ", 0);
|
|
|
|
|
escapeTableName_sb(sb, tbl_ext, len_ext);
|
|
|
|
|
joinStr_sb(sb, " LEFT", 5, 1, tbl_meta, len_meta, "mdo_id", 6, tbl_ext, len_ext, "mdo_id", 6);
|
|
|
|
|
if (wb != 0) {
|
|
|
|
|
compileWhereBuilder_sb(sb, wb, 0);
|
|
|
|
|
}
|
|
|
|
|
strbld_str(sb, " ORDER BY ", 0);
|
|
|
|
|
escapeColumnName_sb(sb, tbl_meta, len_meta, "updated", 0);
|
|
|
|
|
strbld_str(sb, " DESC, ", 0);
|
|
|
|
|
escapeColumnName_sb(sb, tbl_meta, len_meta, "updated", 0);
|
|
|
|
|
strbld_str(sb, " DESC", 0);
|
|
|
|
|
|
|
|
|
|
modbFreeTableName(&tbl_meta);
|
|
|
|
|
modbFreeTableName(&tbl_ext);
|
|
|
|
|
if (strbld_finalize_or_destroy(&sb, &qry, &qry_len) != 0) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
qry_ret = tableQuery(sconn, qry, qry_len, 0, &col_data, &n_cols);
|
|
|
|
|
free(qry);
|
|
|
|
|
|
|
|
|
|
// Query failed
|
|
|
|
|
if (qry_ret == (uint64_t)-1) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Zero row result
|
|
|
|
|
if (qry_ret == 0) {
|
|
|
|
|
freeColumns(col_data, n_cols);
|
|
|
|
|
*ext_list = 0;
|
|
|
|
|
*n_exts = 0;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
res = tableRowsToMetaExtList(col_data, n_cols, ext_list, n_exts);
|
|
|
|
|
freeColumns(col_data, n_cols);
|
|
|
|
|
|
|
|
|
|
if (res <= 0) {
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (int)qry_ret;
|
|
|
|
|
}
|
|
|
|
|
int doScalarMetaExtListQuery(stored_conn *sconn, modb_ref *modb,
|
|
|
|
|
where_builder *wb, struct meta_ext_t **meta_ext)
|
|
|
|
|
{
|
|
|
|
|
int res;
|
|
|
|
|
struct meta_ext_t **meta_ext_list;
|
|
|
|
|
size_t n_exts;
|
|
|
|
|
|
|
|
|
|
res = doMetaExtListQuery(sconn, modb, wb, &meta_ext_list, &n_exts);
|
|
|
|
|
if (res <= 0) {
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*meta_ext = *(meta_ext_list + 0);
|
|
|
|
|
*(meta_ext_list + 0) = 0;
|
|
|
|
|
freeMetaExtList(&meta_ext_list, n_exts);
|
|
|
|
|
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ##### PUBLIC
|
|
|
|
|
struct meta_ext_t *allocMetaExt(void)
|
|
|
|
|
{
|
|
|
|
|
struct meta_ext_t *metadata_ext;
|
|
|
|
|
|
|
|
|
|
metadata_ext = malloc(sizeof(struct meta_ext_t));
|
|
|
|
|
if (metadata_ext == 0) {
|
|
|
|
|
fprintf(stderr, "[%d]malloc: (%d) %s\n", __LINE__, errno, strerror(errno));
|
|
|
|
|
}
|
|
|
|
|
memset(metadata_ext, 0, sizeof(struct metadata_ext_t));
|
|
|
|
|
memset(metadata_ext, 0, sizeof(struct meta_ext_t));
|
|
|
|
|
|
|
|
|
|
return metadata_ext;
|
|
|
|
|
}
|
|
|
|
|
struct metadata_ext_t **allocMetadataExts(size_t n_metadata_exts)
|
|
|
|
|
void freeMetaExt(struct meta_ext_t **metadata_ext_ptr)
|
|
|
|
|
{
|
|
|
|
|
struct metadata_ext_t **metadata_exts;
|
|
|
|
|
struct meta_ext_t *metadata_ext = *metadata_ext_ptr;
|
|
|
|
|
|
|
|
|
|
metadata_exts = (struct metadata_ext_t **)malloc(sizeof(struct metadata_ext_t *) * n_metadata_exts);
|
|
|
|
|
if (metadata_exts == 0) {
|
|
|
|
|
fprintf(stderr, "[%d]malloc: (%d) %s\n", __LINE__, errno, strerror(errno));
|
|
|
|
|
return 0;
|
|
|
|
|
if (metadata_ext->values != 0) {
|
|
|
|
|
freeMetaExtValues(&metadata_ext->values, metadata_ext->n_values);
|
|
|
|
|
}
|
|
|
|
|
memset(metadata_exts, 0, sizeof(struct metadata_ext_t *) * n_metadata_exts);
|
|
|
|
|
|
|
|
|
|
return metadata_exts;
|
|
|
|
|
}
|
|
|
|
|
void freeMetadataExt(struct metadata_ext_t **metadata_ext_ptr)
|
|
|
|
|
{
|
|
|
|
|
struct metadata_ext_t *metadata_ext = *metadata_ext_ptr;
|
|
|
|
|
|
|
|
|
|
free(metadata_ext);
|
|
|
|
|
*metadata_ext_ptr = 0;
|
|
|
|
|
}
|
|
|
|
|
void freeMetadataExts(struct metadata_ext_t ***metadata_exts_ptr, size_t n_metadata_exts)
|
|
|
|
|
struct meta_ext_t **allocMetaExtList(size_t n_metadata_exts)
|
|
|
|
|
{
|
|
|
|
|
struct meta_ext_t **metadata_exts;
|
|
|
|
|
|
|
|
|
|
metadata_exts = (struct meta_ext_t **)malloc(sizeof(struct meta_ext_t *) * n_metadata_exts);
|
|
|
|
|
if (metadata_exts == 0) {
|
|
|
|
|
fprintf(stderr, "[%d]malloc: (%d) %s\n", __LINE__, errno, strerror(errno));
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
memset(metadata_exts, 0, sizeof(struct meta_ext_t *) * n_metadata_exts);
|
|
|
|
|
|
|
|
|
|
return metadata_exts;
|
|
|
|
|
}
|
|
|
|
|
void freeMetaExtList(struct meta_ext_t ***metadata_exts_ptr, size_t n_metadata_exts)
|
|
|
|
|
{
|
|
|
|
|
size_t idx;
|
|
|
|
|
struct metadata_ext_t **metadata_exts = *metadata_exts_ptr;
|
|
|
|
|
struct meta_ext_t **metadata_exts = *metadata_exts_ptr;
|
|
|
|
|
|
|
|
|
|
for (idx = 0; idx < n_metadata_exts; idx++) {
|
|
|
|
|
if (*(metadata_exts + idx) != 0) {
|
|
|
|
|
freeMetadataExt(metadata_exts + idx);
|
|
|
|
|
freeMetaExt(metadata_exts + idx);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free(metadata_exts);
|
|
|
|
|
*metadata_exts_ptr = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct meta_ext_value_t *allocMetaExtValue(void)
|
|
|
|
|
{
|
|
|
|
|
struct meta_ext_value_t *ext_value;
|
|
|
|
|
|
|
|
|
|
ext_value = malloc(sizeof(struct meta_ext_value_t));
|
|
|
|
|
if (ext_value == 0) {
|
|
|
|
|
fprintf(stderr, "[%d]malloc: (%d) %s\n", __LINE__, errno, strerror(errno));
|
|
|
|
|
}
|
|
|
|
|
memset(ext_value, 0, sizeof(struct meta_ext_value_t));
|
|
|
|
|
|
|
|
|
|
return ext_value;
|
|
|
|
|
}
|
|
|
|
|
void freeMetaExtValue(struct meta_ext_value_t **ext_value_ptr)
|
|
|
|
|
{
|
|
|
|
|
struct meta_ext_value_t *ext_value = *ext_value_ptr;
|
|
|
|
|
|
|
|
|
|
if (ext_value->key != 0) {
|
|
|
|
|
free(ext_value->key);
|
|
|
|
|
ext_value->key = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!ext_value->is_null && !ext_value->is_const) {
|
|
|
|
|
if (ext_value->type == VTYPE_RAW && ext_value->value.raw != 0) {
|
|
|
|
|
free(ext_value->value.raw);
|
|
|
|
|
ext_value->value.raw = 0;
|
|
|
|
|
}
|
|
|
|
|
if (ext_value->type == VTYPE_STRING && ext_value->value.str != 0) {
|
|
|
|
|
free(ext_value->value.str);
|
|
|
|
|
ext_value->value.str = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free(ext_value);
|
|
|
|
|
*ext_value_ptr = 0;
|
|
|
|
|
}
|
|
|
|
|
struct meta_ext_value_t **allocMetaExtValues(size_t n_values, int alloc_values)
|
|
|
|
|
{
|
|
|
|
|
struct meta_ext_value_t **ext_values;
|
|
|
|
|
size_t idx;
|
|
|
|
|
|
|
|
|
|
ext_values = (struct meta_ext_value_t **)malloc(sizeof(struct meta_ext_value_t *) * n_values);
|
|
|
|
|
if (ext_values == 0) {
|
|
|
|
|
fprintf(stderr, "[%d]malloc: (%d) %s\n", __LINE__, errno, strerror(errno));
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
memset(ext_values, 0, sizeof(struct meta_ext_value_t *) * n_values);
|
|
|
|
|
|
|
|
|
|
if (alloc_values) {
|
|
|
|
|
for (idx = 0; idx < n_values; idx++) {
|
|
|
|
|
if ((*(ext_values + idx) = allocMetaExtValue()) == 0) {
|
|
|
|
|
freeMetaExtValues(&ext_values, idx - 1);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ext_values;
|
|
|
|
|
}
|
|
|
|
|
void freeMetaExtValues(struct meta_ext_value_t ***ext_values_ptr, size_t n_values)
|
|
|
|
|
{
|
|
|
|
|
size_t idx;
|
|
|
|
|
struct meta_ext_value_t **ext_values = *ext_values_ptr;
|
|
|
|
|
|
|
|
|
|
for (idx = 0; idx < n_values; idx++) {
|
|
|
|
|
if (*(ext_values + idx) != 0) {
|
|
|
|
|
freeMetaExtValue(ext_values + idx);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free(ext_values);
|
|
|
|
|
*ext_values_ptr = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int modbMetaExtById(stored_conn *sconn, modb_ref *modb, unsigned int id,
|
|
|
|
|
struct meta_ext_t **meta_ext)
|
|
|
|
|
{
|
|
|
|
|
where_builder *wb = 0;
|
|
|
|
|
int res;
|
|
|
|
|
char *tbl_ext;
|
|
|
|
|
size_t len_ext;
|
|
|
|
|
|
|
|
|
|
modbTableName(&tbl_ext, &len_ext, modb, META_EXT_TABLE, strlen(META_EXT_TABLE));
|
|
|
|
|
wb = where(tbl_ext, "mdo_id", EQ, TYPE_UINT32, 1, id);
|
|
|
|
|
res = doScalarMetaExtListQuery(sconn, modb, wb, meta_ext);
|
|
|
|
|
freeWhereBuilder(&wb);
|
|
|
|
|
free(tbl_ext);
|
|
|
|
|
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int modbMetaExtList(stored_conn *sconn, modb_ref *modb, int with_deleted,
|
|
|
|
|
struct meta_ext_t ***meta_exts, size_t *n_meta_exts)
|
|
|
|
|
{
|
|
|
|
|
where_builder *wb = 0;
|
|
|
|
|
int res;
|
|
|
|
|
char *tbl_ext = 0;
|
|
|
|
|
size_t len_ext;
|
|
|
|
|
|
|
|
|
|
if (with_deleted == 0) {
|
|
|
|
|
modbTableName(&tbl_ext, &len_ext, modb, META_EXT_TABLE, strlen(META_EXT_TABLE));
|
|
|
|
|
wb = where(tbl_ext, "deleted", IS_NULL, TYPE_RAW, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
res = doMetaExtListQuery(sconn, modb, wb, meta_exts, n_meta_exts);
|
|
|
|
|
if (wb != 0) {
|
|
|
|
|
freeWhereBuilder(&wb);
|
|
|
|
|
free(tbl_ext);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int64_t modbMetaExtCreate(stored_conn *sconn, modb_ref *modb, struct meta_ext_t *meta_ext)
|
|
|
|
|
{
|
|
|
|
|
str_builder *sb;
|
|
|
|
|
char *table;
|
|
|
|
|
size_t table_len;
|
|
|
|
|
char *qry;
|
|
|
|
|
size_t qry_len;
|
|
|
|
|
uint64_t qry_ret;
|
|
|
|
|
size_t idx;
|
|
|
|
|
struct meta_ext_value_t *ext_value;
|
|
|
|
|
|
|
|
|
|
if ((sb = strbld_create()) == 0) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
modbTableName(&table, &table_len, modb, META_EXT_TABLE, strlen(META_EXT_TABLE));
|
|
|
|
|
|
|
|
|
|
strbld_str(sb, "INSERT INTO ", 0);
|
|
|
|
|
escapeTableName_sb(sb, table, table_len);
|
|
|
|
|
strbld_str(sb, " (`mdo_id`", 0);
|
|
|
|
|
for (idx = 0; idx < meta_ext->n_values; idx++) {
|
|
|
|
|
ext_value = (*(meta_ext->values + idx));
|
|
|
|
|
strbld_char(sb, ',');
|
|
|
|
|
escapeColumnName_sb(sb, 0, 0, ext_value->key_c, 0);
|
|
|
|
|
}
|
|
|
|
|
strbld_str(sb, ") VALUES (", 0);
|
|
|
|
|
db_value_sb(sb, TYPE_ID, 1, meta_ext->id);
|
|
|
|
|
for (idx = 0; idx < meta_ext->n_values; idx++) {
|
|
|
|
|
ext_value = *(meta_ext->values + idx);
|
|
|
|
|
strbld_char(sb, ',');
|
|
|
|
|
switch(ext_value->type) {
|
|
|
|
|
case VTYPE_RAW:
|
|
|
|
|
db_value_sb(sb, TYPE_RAW, 2, ext_value->value.raw, ext_value->value_len);
|
|
|
|
|
break;
|
|
|
|
|
case VTYPE_BOOL:
|
|
|
|
|
db_value_sb(sb, TYPE_BOOL, 1, ext_value->value.bool);
|
|
|
|
|
break;
|
|
|
|
|
case VTYPE_INT32:
|
|
|
|
|
db_value_sb(sb, TYPE_INT32, 1, ext_value->value.int32);
|
|
|
|
|
break;
|
|
|
|
|
case VTYPE_DOUBLE:
|
|
|
|
|
db_value_sb(sb, TYPE_DOUBLE, 1, ext_value->value.dbl);
|
|
|
|
|
break;
|
|
|
|
|
case VTYPE_STRING:
|
|
|
|
|
db_value_sb(sb, TYPE_STRING, 2, ext_value->value.str, ext_value->value_len);
|
|
|
|
|
break;
|
|
|
|
|
case VTYPE_TIMESTAMP:
|
|
|
|
|
db_value_sb(sb, TYPE_TIMESTAMP, 1, ext_value->value.ts);
|
|
|
|
|
break;
|
|
|
|
|
case VTYPE_ID:
|
|
|
|
|
db_value_sb(sb, TYPE_ID, 1, ext_value->value.id);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
strbld_char(sb, ')');
|
|
|
|
|
|
|
|
|
|
modbFreeTableName(&table);
|
|
|
|
|
if (strbld_finalize_or_destroy(&sb, &qry, &qry_len) != 0) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
qry_ret = simpleQuery(sconn, qry, qry_len);
|
|
|
|
|
free(qry);
|
|
|
|
|
|
|
|
|
|
return qry_ret == 0 ? meta_ext->id : 0;
|
|
|
|
|
}
|
|
|
|
|
int64_t modbMetaExtReplace(stored_conn *sconn, modb_ref *modb, unsigned int id,
|
|
|
|
|
struct meta_ext_t *meta_ext);
|
|
|
|
|
int64_t modbMetaExtUpdate(stored_conn *sconn, modb_ref *modb, unsigned int id,
|
|
|
|
|
struct meta_ext_t *meta_ext)
|
|
|
|
|
{
|
|
|
|
|
str_builder *sb;
|
|
|
|
|
char *table, *set;
|
|
|
|
|
size_t table_len, set_len;
|
|
|
|
|
int64_t qry_ret;
|
|
|
|
|
size_t idx;
|
|
|
|
|
struct meta_ext_value_t *ext_value;
|
|
|
|
|
|
|
|
|
|
if ((sb = strbld_create()) == 0) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
columnSetValueStr_sb(sb, "mdo_id", TYPE_ID, 1, id);
|
|
|
|
|
|
|
|
|
|
for (idx = 0; idx < meta_ext->n_values; idx++) {
|
|
|
|
|
ext_value = *(meta_ext->values + idx);
|
|
|
|
|
strbld_char(sb, ',');
|
|
|
|
|
switch(ext_value->type) {
|
|
|
|
|
case VTYPE_RAW:
|
|
|
|
|
columnSetValueStr_sb(
|
|
|
|
|
sb, ext_value->key_c, TYPE_RAW, 2, ext_value->value.raw, ext_value->value_len
|
|
|
|
|
);
|
|
|
|
|
break;
|
|
|
|
|
case VTYPE_BOOL:
|
|
|
|
|
columnSetValueStr_sb(sb, ext_value->key_c, TYPE_BOOL, 1, ext_value->value.bool);
|
|
|
|
|
break;
|
|
|
|
|
case VTYPE_INT32:
|
|
|
|
|
columnSetValueStr_sb(sb, ext_value->key_c, TYPE_INT32, 1, ext_value->value.int32);
|
|
|
|
|
break;
|
|
|
|
|
case VTYPE_DOUBLE:
|
|
|
|
|
columnSetValueStr_sb(sb, ext_value->key_c, TYPE_DOUBLE, 1, ext_value->value.dbl);
|
|
|
|
|
break;
|
|
|
|
|
case VTYPE_STRING:
|
|
|
|
|
columnSetValueStr_sb(
|
|
|
|
|
sb, ext_value->key_c, TYPE_STRING, 2, ext_value->value.str, ext_value->value_len
|
|
|
|
|
);
|
|
|
|
|
break;
|
|
|
|
|
case VTYPE_TIMESTAMP:
|
|
|
|
|
columnSetValueStr_sb(sb, ext_value->key_c, TYPE_TIMESTAMP, 1, ext_value->value.ts);
|
|
|
|
|
break;
|
|
|
|
|
case VTYPE_ID:
|
|
|
|
|
columnSetValueStr_sb(sb, ext_value->key_c, TYPE_ID, 1, ext_value->value.id);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (strbld_finalize_or_destroy(&sb, &set, &set_len) != 0) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
modbTableName(&table, &table_len, modb, META_EXT_TABLE, strlen(META_EXT_TABLE));
|
|
|
|
|
qry_ret = updateQuery(
|
|
|
|
|
sconn, table, table_len, set, set_len, where(0, "mdo_id", EQ, TYPE_ID, 1, id)
|
|
|
|
|
);
|
|
|
|
|
modbFreeTableName(&table);
|
|
|
|
|
|
|
|
|
|
free(set);
|
|
|
|
|
|
|
|
|
|
return qry_ret;
|
|
|
|
|
}
|
|
|
|
|
int modbMetaExtDelete(stored_conn *sconn, modb_ref *modb, unsigned int id)
|
|
|
|
|
{
|
|
|
|
|
char *table;
|
|
|
|
|
size_t table_len;
|
|
|
|
|
int64_t qry_ret;
|
|
|
|
|
|
|
|
|
|
modbTableName(&table, &table_len, modb, META_EXT_TABLE, STR_LEN(META_EXT_TABLE));
|
|
|
|
|
qry_ret = softDeleteByIdQuery(sconn, table, table_len, "mdo_id", id);
|
|
|
|
|
modbFreeTableName(&table);
|
|
|
|
|
|
|
|
|
|
return (int)qry_ret;
|
|
|
|
|
}
|
|
|
|
|
int modbMetaExtDestroy(stored_conn *sconn, modb_ref *modb, unsigned int id)
|
|
|
|
|
{
|
|
|
|
|
char *table;
|
|
|
|
|
size_t table_len;
|
|
|
|
|
int64_t qry_ret;
|
|
|
|
|
|
|
|
|
|
modbTableName(&table, &table_len, modb, META_EXT_TABLE, STR_LEN(META_EXT_TABLE));
|
|
|
|
|
qry_ret = deleteByIdQuery(sconn, table, table_len, "mdo_id", id);
|
|
|
|
|
modbFreeTableName(&table);
|
|
|
|
|
|
|
|
|
|
return (int)qry_ret;
|
|
|
|
|
}
|
|
|
|
|
|