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

Reply via email to