As discussed on the -user mailing list, I have created a small patch to
support calling libdbi from plugins (where several plugins may call into
dbi_initialize() not knowing about each other).
I have used the _r naming conventions for the changed functions. Please
note that I needed to change a bit more code as rootconn was also
affected by the requirement.
I have tried to keep as consistent with the libdbi interface as
possible. However, in dbi_initialize_r(), I have slightly different
calling conventions. I now needed to pass a second output parameter (the
instance pointer). Fully in line with existing calling conventions would
be to make dbi_initialize_r() return the dbi_inst handle. However, that
would have required to introduce a new function to query the loaded
driver count. I think this would be more intrusive and probably
confusing to existing code. So I decided to go for a output param.
Please review the patch, comments are of course welcome.
Rainer
diff -ru -x '*.Log' -x '*.log' -x Entries -x '*.sh' -x configure libdbi/include/dbi/dbi-dev.h libdbi.new/include/dbi/dbi-dev.h
--- libdbi/include/dbi/dbi-dev.h 2008-01-15 01:21:25.000000000 +0100
+++ libdbi.new/include/dbi/dbi-dev.h 2008-02-15 19:26:24.000000000 +0100
@@ -35,6 +35,7 @@
/* to fool the compiler into letting us use the following structs before they're actually defined: */
typedef struct dbi_driver_s *dbi_driver_t_pointer;
+typedef struct dbi_inst_s *dbi_inst_t_pointer;
typedef struct dbi_conn_s *dbi_conn_t_pointer;
typedef struct _field_binding_s *_field_binding_t_pointer;
@@ -147,6 +148,7 @@
dbi_custom_function_t *custom_functions;
const char **reserved_words;
_capability_t *caps;
+ dbi_inst_t_pointer dbi_inst; /* engine instance we are called from */
struct dbi_driver_s *next;
} dbi_driver_t;
@@ -180,6 +182,16 @@
int _get_field_flag(dbi_row_t *row, unsigned int fieldidx, unsigned char flag);
+/******************************
+ * DBI INSTANCE RELATED TYPES *
+ ******************************/
+typedef struct dbi_inst_s {
+ dbi_driver_t *rootdriver;
+ dbi_conn_t *rootconn;
+ int dbi_verbosity;
+} dbi_inst_t;
+
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff -ru -x '*.Log' -x '*.log' -x Entries -x '*.sh' -x configure libdbi/include/dbi/dbi.h libdbi.new/include/dbi/dbi.h
--- libdbi/include/dbi/dbi.h 2008-02-15 20:11:03.000000000 +0100
+++ libdbi.new/include/dbi/dbi.h 2008-02-16 13:10:19.000000000 +0100
@@ -41,6 +41,7 @@
#endif
/* opaque type definitions */
+typedef void * dbi_inst;
typedef void * dbi_driver;
typedef void * dbi_conn;
typedef void * dbi_result;
@@ -159,13 +160,18 @@
/* needed by get_engine_version functions */
#define VERSIONSTRING_LENGTH 32
-int dbi_initialize(const char *driverdir);
-void dbi_shutdown();
+int dbi_initialize_r(const char *driverdir, dbi_inst **Inst);
+int LIBDBI_API_DEPRECATED dbi_initialize(const char *driverdir);
+void dbi_shutdown_r(dbi_inst Inst);
+void LIBDBI_API_DEPRECATED dbi_shutdown();
const char *dbi_version();
-int dbi_set_verbosity(int verbosity);
+int dbi_set_verbosity_r(int verbosity, dbi_inst Inst);
+int LIBDBI_API_DEPRECATED dbi_set_verbosity(int verbosity);
-dbi_driver dbi_driver_list(dbi_driver Current); /* returns next driver. if current is NULL, return first driver. */
-dbi_driver dbi_driver_open(const char *name); /* goes thru linked list until it finds the right one */
+dbi_driver dbi_driver_list_r(dbi_driver Current, dbi_inst Inst);
+dbi_driver LIBDBI_API_DEPRECATED dbi_driver_list(dbi_driver Current); /* returns next driver. if current is NULL, return first driver. */
+dbi_driver dbi_driver_open_r(const char *name, dbi_inst Inst);
+dbi_driver LIBDBI_API_DEPRECATED dbi_driver_open(const char *name); /* goes thru linked list until it finds the right one */
int dbi_driver_is_reserved_word(dbi_driver Driver, const char *word);
void *dbi_driver_specific_function(dbi_driver Driver, const char *name);
size_t LIBDBI_API_DEPRECATED dbi_driver_quote_string_copy(dbi_driver Driver, const char *orig, char **newstr);
@@ -182,7 +188,8 @@
const char *dbi_driver_get_version(dbi_driver Driver);
const char *dbi_driver_get_date_compiled(dbi_driver Driver);
-dbi_conn dbi_conn_new(const char *name); /* shortcut for dbi_conn_open(dbi_driver_open("foo")) */
+dbi_conn dbi_conn_new_r(const char *name, dbi_inst Inst);
+dbi_conn LIBDBI_API_DEPRECATED dbi_conn_new(const char *name); /* shortcut for dbi_conn_open(dbi_driver_open("foo")) */
dbi_conn dbi_conn_open(dbi_driver Driver); /* returns an actual instance of the conn */
dbi_driver dbi_conn_get_driver(dbi_conn Conn);
int dbi_conn_set_option(dbi_conn Conn, const char *key, const char *value); /* if value is NULL, remove option from list */
diff -ru -x '*.Log' -x '*.log' -x Entries -x '*.sh' -x configure libdbi/src/dbi_main.c libdbi.new/src/dbi_main.c
--- libdbi/src/dbi_main.c 2008-02-06 17:21:29.000000000 +0100
+++ libdbi.new/src/dbi_main.c 2008-02-16 13:13:35.000000000 +0100
@@ -113,7 +113,7 @@
#endif
/* declarations for internal functions -- anything declared as static won't be accessible by name from client programs */
-static dbi_driver_t *_get_driver(const char *filename);
+static dbi_driver_t *_get_driver(const char *filename, dbi_inst_t *inst);
static void _free_custom_functions(dbi_driver_t *driver);
static dbi_option_t *_find_or_create_option_node(dbi_conn Conn, const char *key);
static int _update_internal_conn_list(dbi_conn_t *conn, int operation);
@@ -131,13 +131,12 @@
/* must not be called "ERROR" due to a name clash on Windoze */
static const char *my_ERROR = "ERROR";
-static dbi_driver_t *rootdriver;
-static dbi_conn_t *rootconn;
-int dbi_verbosity = 1;
+static dbi_inst_t dbi_inst_legacy;
/* XXX DBI CORE FUNCTIONS XXX */
-int dbi_initialize(const char *driverdir) {
+int dbi_initialize_r(const char *driverdir, dbi_inst **Inst) {
+ dbi_inst_t *inst;
DIR *dir;
struct dirent *driver_dirent = NULL;
struct stat statbuf;
@@ -150,7 +149,16 @@
#if HAVE_LTDL_H
(void)lt_dlinit();
#endif
- rootdriver = NULL;
+ /* init the instance */
+ inst = malloc(sizeof(dbi_inst_t));
+ if (!inst) {
+ return -1;
+ }
+ *Inst = (void*) inst;
+ inst->rootdriver = NULL;
+ inst->rootconn = NULL;
+ inst->dbi_verbosity = 1; /* TODO: is this really the right default? */
+ /* end instance init */
effective_driverdir = (driverdir ? (char *)driverdir : DBI_DRIVER_DIR);
dir = opendir(effective_driverdir);
@@ -163,10 +171,10 @@
snprintf(fullpath, FILENAME_MAX, "%s%s%s", effective_driverdir, DBI_PATH_SEPARATOR, driver_dirent->d_name);
if ((stat(fullpath, &statbuf) == 0) && S_ISREG(statbuf.st_mode) && strrchr(driver_dirent->d_name, '.') && (!strcmp(strrchr(driver_dirent->d_name, '.'), DRIVER_EXT))) {
/* file is a stat'able regular file that ends in .so (or appropriate dynamic library extension) */
- driver = _get_driver(fullpath);
+ driver = _get_driver(fullpath, inst);
if (driver && (driver->functions->initialize(driver) != -1)) {
- if (!rootdriver) {
- rootdriver = driver;
+ if (!inst->rootdriver) {
+ inst->rootdriver = driver;
}
if (prevdriver) {
prevdriver->next = driver;
@@ -179,7 +187,7 @@
if (driver && driver->functions) free(driver->functions);
if (driver) free(driver);
driver = NULL; /* don't include in linked list */
- if (dbi_verbosity) fprintf(stderr, "libdbi: Failed to load driver: %s\n", fullpath);
+ if (inst->dbi_verbosity) fprintf(stderr, "libdbi: Failed to load driver: %s\n", fullpath);
}
}
}
@@ -189,11 +197,16 @@
return num_loaded;
}
-void dbi_shutdown() {
- dbi_conn_t *curconn = rootconn;
+int dbi_initialize(const char *driverdir) {
+ dbi_initialize_r(driverdir, (dbi_inst) &dbi_inst_legacy);
+}
+
+void dbi_shutdown_r(dbi_inst Inst) {
+ dbi_inst_t *inst = (dbi_inst_t*) Inst;
+ dbi_conn_t *curconn = inst->rootconn;
dbi_conn_t *nextconn;
- dbi_driver_t *curdriver = rootdriver;
+ dbi_driver_t *curdriver = inst->rootdriver;
dbi_driver_t *nextdriver;
while (curconn) {
@@ -215,37 +228,50 @@
#if HAVE_LTDL_H
(void)lt_dlexit();
#endif
- rootdriver = NULL;
+ free(inst);
+}
+
+void dbi_shutdown() {
+ dbi_shutdown_r((dbi_inst) &dbi_inst_legacy);
}
const char *dbi_version() {
return "libdbi v" VERSION;
}
-int dbi_set_verbosity(int verbosity) {
+int dbi_set_verbosity_r(int verbosity, dbi_inst Inst) {
+ dbi_inst_t *inst = (dbi_inst_t*) Inst;
/* whether or not to spew stderr messages when something bad happens (and
* isn't handled through the normal connection-oriented DBI error
* mechanisms) */
- int prev = dbi_verbosity;
- dbi_verbosity = verbosity;
+ int prev = inst->dbi_verbosity;
+ inst->dbi_verbosity = verbosity;
return prev;
}
+int dbi_set_verbosity(int verbosity) {
+ return dbi_set_verbosity_r(verbosity, (dbi_inst) &dbi_inst_legacy);
+}
/* XXX DRIVER FUNCTIONS XXX */
-dbi_driver dbi_driver_list(dbi_driver Current) {
+dbi_driver dbi_driver_list_r(dbi_driver Current, dbi_inst Inst) {
+ dbi_inst_t *inst = (dbi_inst_t*) Inst;
dbi_driver_t *current = Current;
if (current == NULL) {
- return (dbi_driver)rootdriver;
+ return (dbi_driver)inst->rootdriver;
}
return (dbi_driver)current->next;
}
+dbi_driver dbi_driver_list(dbi_driver Current) {
+ return dbi_driver_list_r(Current, (dbi_inst) &dbi_inst_legacy);
+}
-dbi_driver dbi_driver_open(const char *name) {
- dbi_driver_t *driver = rootdriver;
+dbi_driver dbi_driver_open_r(const char *name, dbi_inst Inst) {
+ dbi_inst_t *inst = (dbi_inst_t*) Inst;
+ dbi_driver_t *driver = inst->rootdriver;
while (driver && strcasecmp(name, driver->info->name)) {
driver = driver->next;
@@ -253,6 +279,9 @@
return driver;
}
+dbi_driver dbi_driver_open(const char *name) {
+ return dbi_driver_open_r(name, (dbi_inst) &dbi_inst_legacy);
+}
int dbi_driver_is_reserved_word(dbi_driver Driver, const char *word) {
unsigned int idx = 0;
@@ -445,15 +474,18 @@
/* XXX DRIVER FUNCTIONS XXX */
-dbi_conn dbi_conn_new(const char *name) {
+dbi_conn dbi_conn_new_r(const char *name, dbi_inst Inst) {
dbi_driver driver;
dbi_conn conn;
- driver = dbi_driver_open(name);
+ driver = dbi_driver_open_r(name, Inst);
conn = dbi_conn_open(driver);
return conn;
}
+dbi_conn dbi_conn_new(const char *name) {
+ dbi_conn_new_r(name, (dbi_inst) &dbi_inst_legacy);
+}
dbi_conn dbi_conn_open(dbi_driver Driver) {
dbi_driver_t *driver = Driver;
@@ -1162,7 +1194,7 @@
/* XXX INTERNAL PRIVATE IMPLEMENTATION FUNCTIONS XXX */
-static dbi_driver_t *_get_driver(const char *filename) {
+static dbi_driver_t *_get_driver(const char *filename, dbi_inst_t *inst) {
dbi_driver_t *driver;
void *dlhandle;
const char **custom_functions_list;
@@ -1183,6 +1215,7 @@
driver->dlhandle = dlhandle;
driver->filename = strdup(filename);
+ driver->dbi_inst = inst;
driver->next = NULL;
driver->caps = NULL;
driver->functions = malloc(sizeof(dbi_functions_t));
@@ -1289,7 +1322,7 @@
* operation = -1: remove conn
* = 0: just look for conn (return 1 if found, -1 if not)
* = 1: add conn */
- dbi_conn_t *curconn = rootconn;
+ dbi_conn_t *curconn = conn->driver->dbi_inst->rootconn;
dbi_conn_t *prevconn = NULL;
if ((operation == -1) || (operation == 0)) {
@@ -1301,7 +1334,7 @@
if (operation == 0) return 1;
else if (operation == -1) {
if (prevconn) prevconn->next = curconn->next;
- else rootconn = NULL;
+ else conn->driver->dbi_inst->rootconn = NULL;
return 0;
}
}
@@ -1313,7 +1346,7 @@
curconn->next = conn;
}
else {
- rootconn = conn;
+ conn->driver->dbi_inst->rootconn = conn;
}
conn->next = NULL;
return 0;
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
libdbi-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/libdbi-devel