X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Futils%2Fdbi.c;h=261d3b249e5265b089db34f9e4c54e64de34d017;hb=2d39d666abde2d66a55ac4536da3f250d9513f48;hp=f89e46356a8d1b9c2d9ae4dbbcc6aa9141aa9c99;hpb=0e30e3dea2b303670cd7770e9607827a36f0cbfd;p=sysdb.git diff --git a/src/utils/dbi.c b/src/utils/dbi.c index f89e463..261d3b2 100644 --- a/src/utils/dbi.c +++ b/src/utils/dbi.c @@ -25,8 +25,12 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "utils/error.h" +#if HAVE_CONFIG_H +# include "config.h" +#endif /* HAVE_CONFIG_H */ + #include "utils/dbi.h" +#include "utils/error.h" #include @@ -37,6 +41,62 @@ #include #include +/* + * pre 0.9 DBI compat layer + */ + +#if LIBDBI_VERSION < 900 +#include + +typedef void *dbi_inst; + +static pthread_mutex_t dbi_lock = PTHREAD_MUTEX_INITIALIZER; +static int dbi_initialized = 0; + +static int +initialize_r(const char *driverdir, dbi_inst __attribute__((unused)) *pInst) +{ + int status = 0; + pthread_mutex_lock(&dbi_lock); + if (! dbi_initialized) + status = dbi_initialize(driverdir); + dbi_initialized = 1; + pthread_mutex_unlock(&dbi_lock); + return status; +} /* initialize_r */ + +static dbi_driver +driver_open_r(const char *name, dbi_inst __attribute__((unused)) Inst) +{ + dbi_driver driver; + pthread_mutex_lock(&dbi_lock); + driver = dbi_driver_open(name); + pthread_mutex_unlock(&dbi_lock); + return driver; +} /* driver_open_r */ + +static dbi_driver +driver_list_r(dbi_driver Current, dbi_inst __attribute__((unused)) Inst) +{ + dbi_driver driver; + pthread_mutex_lock(&dbi_lock); + driver = dbi_driver_list(Current); + pthread_mutex_unlock(&dbi_lock); + return driver; +} /* driver_list_r */ + +static void +shutdown_r(dbi_inst __attribute__((unused)) Inst) +{ + /* do nothing; we don't know if DBI is still in use */ +} /* shutdown_r */ + +#define dbi_initialize_r initialize_r +#define dbi_driver_open_r driver_open_r +#define dbi_driver_list_r driver_list_r +#define dbi_shutdown_r shutdown_r +#endif /* LIBDBI_VERSION < 900 */ + /* * private data types */ @@ -56,6 +116,7 @@ struct sdb_dbi_client { char *database; dbi_conn conn; + dbi_inst inst; sdb_dbi_options_t *options; }; @@ -84,7 +145,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 +157,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; } @@ -133,7 +194,7 @@ sdb_dbi_get_data(sdb_dbi_client_t *client, dbi_result res, sdb_dbi_strerror(client->conn)); return -1; } - types[i] = DBI_TYPE_TO_SC(types[i]); + types[i] = DBI_TYPE_TO_SDB(types[i]); } num_rows = dbi_result_get_numrows(res); @@ -141,6 +202,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 +215,11 @@ 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) + sdb_data_free_datum(&data[i]); + + if (status) continue; ++success; @@ -172,7 +239,7 @@ sdb_dbi_options_create(void) { sdb_dbi_options_t *options; - options = malloc(sizeof(options)); + options = malloc(sizeof(*options)); if (! options) return NULL; @@ -253,6 +320,11 @@ sdb_dbi_client_create(const char *driver, const char *database) client->conn = NULL; client->options = NULL; + if (dbi_initialize_r(/* driverdir = */ NULL, &client->inst) < 0) { + free(client); + return NULL; + } + client->driver = strdup(driver); client->database = strdup(database); if ((! client->driver) || (! client->database)) { @@ -284,18 +356,20 @@ sdb_dbi_client_connect(sdb_dbi_client_t *client) if ((! client) || (! client->driver) || (! client->database)) return -1; - if (client->conn) + if (client->conn) { dbi_conn_close(client->conn); + client->conn = NULL; + } - driver = dbi_driver_open(client->driver); + driver = dbi_driver_open_r(client->driver, client->inst); if (! driver) { sdb_error_set("dbi: failed to open DBI driver '%s'; " "possibly it's not installed.\n", client->driver); sdb_error_append("dbi: known drivers:\n"); - for (driver = dbi_driver_list(NULL); driver; - driver = dbi_driver_list(driver)) { + for (driver = dbi_driver_list_r(NULL, client->inst); driver; + driver = dbi_driver_list_r(driver, client->inst)) { sdb_error_append("\t- %s\n", dbi_driver_get_name(driver)); } sdb_error_chomp(); @@ -305,8 +379,7 @@ sdb_dbi_client_connect(sdb_dbi_client_t *client) client->conn = dbi_conn_open(driver); if (! client->conn) { - sdb_log(SDB_LOG_ERR, "dbi: failed to open connection " - "object."); + sdb_log(SDB_LOG_ERR, "dbi: failed to open connection object."); return -1; } @@ -332,6 +405,7 @@ sdb_dbi_client_connect(sdb_dbi_client_t *client) sdb_error_log(SDB_LOG_ERR); dbi_conn_close(client->conn); + client->conn = NULL; return -1; } } @@ -340,6 +414,7 @@ sdb_dbi_client_connect(sdb_dbi_client_t *client) sdb_log(SDB_LOG_ERR, "dbi: failed to set option 'dbname': %s", sdb_dbi_strerror(client->conn)); dbi_conn_close(client->conn); + client->conn = NULL; return -1; } @@ -347,6 +422,7 @@ sdb_dbi_client_connect(sdb_dbi_client_t *client) sdb_log(SDB_LOG_ERR, "dbi: failed to connect to database '%s': %s", client->database, sdb_dbi_strerror(client->conn)); dbi_conn_close(client->conn); + client->conn = NULL; return -1; } return 0; @@ -420,7 +496,7 @@ sdb_dbi_exec_query(sdb_dbi_client_t *client, const char *query, unsigned int type = va_arg(types, unsigned int); - field_type = DBI_TYPE_TO_SC(field_type); + field_type = DBI_TYPE_TO_SDB(field_type); /* column count starts at 1 */ if ((unsigned int)field_type != type) { @@ -467,6 +543,11 @@ sdb_dbi_client_destroy(sdb_dbi_client_t *client) if (client->conn) dbi_conn_close(client->conn); + client->conn = NULL; + + if (client->inst) + dbi_shutdown_r(client->inst); + client->inst = NULL; if (client->options) sdb_dbi_options_destroy(client->options);