From 8c9f16283fc6aa4a324c8c11624b9d1d6ed6c511 Mon Sep 17 00:00:00 2001 From: Sebastian Harl Date: Tue, 28 Jan 2014 20:12:22 +0100 Subject: [PATCH] core/data: Make string and binary data not constant. This will allow for more flexibility. However, it also requires to create a copy of data queried using libdbi. --- src/include/core/data.h | 4 ++-- src/utils/dbi.c | 17 ++++++++++++++--- src/utils/unixsock.c | 2 +- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/include/core/data.h b/src/include/core/data.h index 4a4dd2d..b657486 100644 --- a/src/include/core/data.h +++ b/src/include/core/data.h @@ -58,11 +58,11 @@ typedef struct { union { int64_t integer; /* SDB_TYPE_INTEGER */ double decimal; /* SDB_TYPE_DECIMAL */ - const char *string; /* SDB_TYPE_STRING */ + char *string; /* SDB_TYPE_STRING */ sdb_time_t datetime; /* SDB_TYPE_DATETIME */ struct { size_t length; - const unsigned char *datum; + unsigned char *datum; } binary; /* SDB_TYPE_BINARY */ } data; } sdb_data_t; diff --git a/src/utils/dbi.c b/src/utils/dbi.c index 1de2f1a..c8eb816 100644 --- a/src/utils/dbi.c +++ b/src/utils/dbi.c @@ -84,7 +84,7 @@ sdb_dbi_get_field(dbi_result res, unsigned int i, data->data.decimal = dbi_result_get_double_idx(res, i); break; case SDB_TYPE_STRING: - data->data.string = dbi_result_get_string_idx(res, i); + data->data.string = dbi_result_get_string_copy_idx(res, i); break; case SDB_TYPE_DATETIME: { @@ -96,7 +96,7 @@ sdb_dbi_get_field(dbi_result res, unsigned int i, case SDB_TYPE_BINARY: { size_t length = dbi_result_get_field_length_idx(res, i); - const unsigned char *datum = dbi_result_get_binary_idx(res, i); + unsigned char *datum = dbi_result_get_binary_copy_idx(res, i); data->data.binary.length = length; data->data.binary.datum = datum; } @@ -141,6 +141,8 @@ sdb_dbi_get_data(sdb_dbi_client_t *client, dbi_result res, return -1; for (n = 0; n < num_rows; ++n) { + int status; + if (! dbi_result_seek_row(res, n + 1)) { sdb_log(SDB_LOG_ERR, "dbi: Failed to retrieve row %llu: %s", n, sdb_dbi_strerror(client->conn)); @@ -152,7 +154,16 @@ sdb_dbi_get_data(sdb_dbi_client_t *client, dbi_result res, types[i], &data[i])) continue; - if (callback(client, num_fields, data, user_data)) + status = callback(client, num_fields, data, user_data); + for (i = 0; i < num_fields; ++i) { + if ((data[i].type == SDB_TYPE_STRING) && (data[i].data.string)) + free(data[i].data.string); + else if ((data[i].type == SDB_TYPE_BINARY) + && (data[i].data.binary.datum)) + free(data[i].data.binary.datum); + } + + if (status) continue; ++success; diff --git a/src/utils/unixsock.c b/src/utils/unixsock.c index 62b6f45..9a5c3fa 100644 --- a/src/utils/unixsock.c +++ b/src/utils/unixsock.c @@ -113,7 +113,7 @@ sdb_unixsock_parse_cell(char *string, int type, sdb_data_t *data) case SDB_TYPE_BINARY: /* we don't support any binary information containing 0-bytes */ data->data.binary.length = strlen(string); - data->data.binary.datum = (const unsigned char *)string; + data->data.binary.datum = (unsigned char *)string; break; default: sdb_log(SDB_LOG_ERR, "unixsock: Unexpected type %i while " -- 2.30.2