[Gnucash-changes] minor cleanup/restructure of how backends are
located and loaded.
Linas Vepstas
linas at cvs.gnucash.org
Sun Jun 13 12:58:06 EDT 2004
Log Message:
-----------
minor cleanup/restructure of how backends are located and loaded.
This infrastructure is not currently used by GnuCash.
Modified Files:
--------------
gnucash/src/engine:
qofbackend-p.h
qofbackend.h
qofsession.c
Revision Data
-------------
Index: qofsession.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofsession.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -Lsrc/engine/qofsession.c -Lsrc/engine/qofsession.c -u -r1.9 -r1.10
--- src/engine/qofsession.c
+++ src/engine/qofsession.c
@@ -28,7 +28,7 @@
*
* HISTORY:
* Created by Linas Vepstas December 1998
- * Copyright (c) 1998-2003 Linas Vepstas <linas at linas.org>
+ * Copyright (c) 1998-2004 Linas Vepstas <linas at linas.org>
* Copyright (c) 2000 Dave Peticolas
*/
@@ -70,6 +70,15 @@
static QofSession * current_session = NULL;
static short module = MOD_BACKEND;
+static GSList *provider_list = NULL;
+
+/* ====================================================================== */
+
+void
+qof_backend_register_provider (QofBackendProvider *prov)
+{
+ provider_list = g_slist_prepend (provider_list, prov);
+}
/* ====================================================================== */
/* error handling routines */
@@ -268,6 +277,8 @@
/* ====================================================================== */
+#ifdef GNUCASH
+
static void
qof_session_int_backend_load_error(QofSession *session,
char *message, char *dll_err)
@@ -286,9 +297,6 @@
qof_session_push_error (session, ERR_BACKEND_NO_BACKEND, NULL);
}
-
-#ifdef GNUCASH
-
/* Gnucash uses its module system to load a backend; other users
* use traditional dlopen calls.
*/
@@ -342,10 +350,35 @@
#else /* GNUCASH */
static void
-qof_session_load_backend(QofSession * session, char * backend_name)
+qof_session_load_backend(QofSession * session, char * access_method)
{
- ENTER (" ");
- LEAVE (" ");
+ GSList *p;
+ ENTER (" ");
+ for (p = provider_list; p; p=p->next)
+ {
+ QofBackendProvider *prov = p->data;
+
+ /* Does this provider handle the desired access method? */
+ if (0 == strcasecmp (access_method, prov->access_method))
+ {
+ if (NULL == prov->backend_new) continue;
+
+ /* Use the providers creation callback */
+ session->backend = (*(prov->backend_new))();
+
+ /* Tell the books about the backend that they'll be using. */
+ GList *node;
+ for (node=session->books; node; node=node->next)
+ {
+ QofBook *book = node->data;
+ qof_book_set_backend (book, session->backend);
+ }
+ return;
+ }
+ }
+
+ qof_session_push_error (session, ERR_BACKEND_NO_HANDLER, NULL);
+ LEAVE (" ");
}
#endif /* GNUCASH */
@@ -435,27 +468,39 @@
{
qof_session_load_backend(session, "file" );
}
-#if 0
- /* load different backend based on URL. We should probably
- * dynamically load these based on some config file ... */
- else if ((!g_strncasecmp(book_id, "http://", 7)) ||
- (!g_strncasecmp(book_id, "https://", 8)))
- {
- /* create the backend */
- session->backend = xmlendNew();
- }
-#endif
- else if (!g_strncasecmp(book_id, "postgres://", 11))
+ else
{
- qof_session_load_backend(session, "postgres");
+ /* Look for somthing of the form of "http://" or
+ * "postgres://". Everything before the colon is the access
+ * method. Load the first backend found for that access method.
+ */
+ char * p = strchr (book_id, ':');
+ if (p)
+ {
+ char * access_method = g_strdup (book_id);
+ p = strchr (access_method, ':');
+ *p = 0;
+ qof_session_load_backend(session, access_method);
+ g_free (access_method);
+ }
+ else
+ {
+ /* If no colon found, assume it must be a file-path */
+ qof_session_load_backend(session, "file");
+ }
}
- else if (!g_strncasecmp(book_id, "rpc://", 6))
+
+ /* No backend was found. That's bad. */
+ if (NULL == session->backend)
{
- qof_session_load_backend(session, "rpc");
+ qof_session_push_error (session, ERR_BACKEND_BAD_URL, NULL);
+ LEAVE (" BAD: no backend: sess=%p book-id=%s",
+ session, book_id ? book_id : "(null)");
+ return;
}
/* If there's a begin method, call that. */
- if (session->backend && session->backend->session_begin)
+ if (session->backend->session_begin)
{
int err;
char * msg;
@@ -485,11 +530,6 @@
}
}
- /* No backend was found. That's bad. */
- if (NULL == session->backend)
- {
- qof_session_push_error (session, ERR_BACKEND_BAD_URL, NULL);
- }
LEAVE (" sess=%p book-id=%s",
session, book_id ? book_id : "(null)");
}
Index: qofbackend-p.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofbackend-p.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -Lsrc/engine/qofbackend-p.h -Lsrc/engine/qofbackend-p.h -u -r1.4 -r1.5
--- src/engine/qofbackend-p.h
+++ src/engine/qofbackend-p.h
@@ -109,11 +109,11 @@
* to ERR_BACKEND_MOD_DESTROY from this routine, so that the
* engine can properly clean up.
*
- * The compile_query() method compiles a QOF query object into
+ * The compile_query() method compiles a Gnucash query object into
* a backend-specific data structure and returns the compiled
* query. For an SQL backend, the contents of the query object
- * are typically turned into a corresponding SQL query statement,
- * and sent to the database for evaluation.
+ * need to be turned into a corresponding SQL query statement, and
+ * sent to the database for evaluation.
*
* The free_query() method frees the data structure returned from
* compile_query()
@@ -223,8 +223,26 @@
*
*/
-struct _QofBackend
+struct QofBackendProvider_s
{
+ /** Some arbitrary name given for this particular backend provider */
+ const char * provider_name;
+
+ /** The access method that this provider provides, for example,
+ * http:// or postgres:// or rpc://, but without the :// at the end
+ */
+ const char * access_method;
+
+ /** Return a new, initialized backend backend. */
+ QofBackend * (*backend_new) (void);
+
+ /** Free this structure, unregister this backend handler. */
+ void (*provider_free) (QofBackendProvider *);
+};
+
+struct QofBackend_s
+{
+
void (*session_begin) (QofBackend *be,
QofSession *session,
const char *book_id,
@@ -272,6 +290,15 @@
void (*export) (QofBackend *, QofBook *);
};
+/** Let the ssytem know about a new provider of backends. This function
+ * is typically called by the provider library at library load time.
+ * This function allows the backend library to tell the QOF infrastructure
+ * that it can handle URL's of a certain type. Note that a single
+ * backend library may register more than one provider, if it is
+ * capable of handling more than one URL access method.
+ */
+void qof_backend_register_provider (QofBackendProvider *);
+
/**
* The qof_backend_set_error() routine pushes an error code onto the error
* stack. (FIXME: the stack is 1 deep in current implementation).
Index: qofbackend.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofbackend.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -Lsrc/engine/qofbackend.h -Lsrc/engine/qofbackend.h -u -r1.7 -r1.8
--- src/engine/qofbackend.h
+++ src/engine/qofbackend.h
@@ -46,8 +46,8 @@
*/
typedef enum {
ERR_BACKEND_NO_ERR = 0,
- ERR_BACKEND_NO_BACKEND, /**< Backend * pointer was null the err routine
- or no backend handler (ENOSYS) */
+ ERR_BACKEND_NO_HANDLER, /**< no backend handler found for this access method (ENOSYS) */
+ ERR_BACKEND_NO_BACKEND, /**< Backend * pointer was unexpectedly null */
ERR_BACKEND_BAD_URL, /**< Can't parse url */
ERR_BACKEND_NO_SUCH_DB, /**< the named database doesn't exist */
ERR_BACKEND_CANT_CONNECT, /**< bad dbname/login/passwd or network failure */
@@ -96,6 +96,14 @@
ERR_RPC_NOT_ADDED, /**< object not added */
} QofBackendError;
+/**
+ * A structure that declares backend services that can be gotten.
+ * The Provider specifies a URL access method, and specifies the
+ * function to create a backend that can handle that URL access
+ * function.
+ */
+typedef struct QofBackendProvider_s QofBackendProvider;
+
/** \brief Pseudo-object providing an interface between the
* engine and a persistant data store (e.g. a server, a database,
* or a file).
@@ -104,7 +112,7 @@
* engine. The backend can, however, report errors to the GUI & other
* front-end users.
*/
-typedef struct _QofBackend QofBackend;
+typedef struct QofBackend_s QofBackend;
/** \brief DOCUMENT ME! */
typedef void (*QofBePercentageFunc) (const char *message, double percent);
More information about the gnucash-changes
mailing list