[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