Due to the problem of maintainence of dbmail with backends, I have begun
working with David Parker (author of libdbi, a portable native database
layer) on creating a backend for dbmail.  This would expand dbmail to the
following backends at this time:
          mysql
          pgsql
          msql
          firebird
          oracle
          sqlite
          
2/3s of the work required is done.  Places work needs to be done are marked
by XXX TODO.  Patch is attached.
Index: dbmail/libdbi/dblibdbi.c
===================================================================
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
+++ dbmail/libdbi/dblibdbi.c    2004-08-26 02:17:50.102957232 -0400
@@ -0,0 +1,273 @@
+
+/* Copyright (C) 2004 Dan Weber <[EMAIL PROTECTED]>
+ * Copyright (C) 2004 David Parker <[EMAIL PROTECTED]>
+ * $Id$
+ * /
+
+/*
+ *
+ * libdbi driver file.
+ * functions for connecting and talking to the libdbi layer
+ */
+ 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+ 
+#include "db.h"
+#include <dbi/dbi.h>
+#include "dbmail.h"
+#include "dbmailtypes.h"
+#include <string.h>
+ 
+db_param_t dbparams;
+dbi_conn conn;
+dbi_result result;
+dbi_result msgbuf_result;
+dbi_result stored_result;
+ 
+ 
+int db_connect() {
+        dbi_initialize(NULL);
+        conn = dbi_conn_new(dbparams.dbtype);
+ 
+        if (!conn) {
+                trace(TRACE_ERROR,"Connection to Database Failed at 
dbi_conn_new");
+                dbi_shutdown();
+                return -1;
+        }
+ 
+        /* Begin Setting Parameters */
+        if (dbparams.host)
+                dbi_conn_set_option(conn, "host", dbparams.host);
+        if (dbparams.user)
+                dbi_conn_set_option(conn, "username", dbparams.user);
+        if (dbparams.pass)
+                dbi_conn_set_option(conn, "password", dbparams.pass);
+        if (dbparams.db)
+                dbi_conn_set_option(conn, "dbname", dbparams.db);
+        if (dbparams.port)
+                dbi_conn_set_option(conn, "port", dbparams.port);
+        /* End Setting Parameters */
+ 
+        // Create Connection
+        if ((dbi_conn_connect(conn)) == -1) {
+                trace(TRACE_ERROR, "Connection failed at dbi_conn_connect");
+                dbi_shutdown();
+                return -1;
+        }
+}
+
+unsigned db_num_rows()
+{
+        /* mysql_store_result can return NULL. If this is
+         * true, res will be zero, and naturally num_rows
+         * should return 0 */
+        if (!result)
+                return 0;
+ 
+        return dbi_result_get_numrows(result);
+}
+
+unsigned db_num_fields()
+{
+        if (!result)
+                return 0;
+ 
+        return dbi_result_get_numfields(result);
+}
+
+void db_free_result()
+{
+        if (result)
+                dbi_result_free(result);
+        else
+                trace(TRACE_WARNING, "%s,%s: Trying to free result set "
+                      "that is already NULL!", __FILE__, __func__);
+        result = NULL;
+}
+
+const char *db_get_result(unsigned row, unsigned field)
+{
+               const char *fieldvalue = NULL;
+               
+        if (!result) {
+                trace(TRACE_WARNING, "%s,%s: result set is null\n",
+                      __FILE__, __func__);
+                return NULL;
+        }
+ 
+        if ((row >= db_num_rows()) || (field >= db_num_fields())) {
+                trace(TRACE_WARNING, "%s, %s: "
+                      "row = %u, field = %u, bigger than size of result set",
+                      __FILE__, __func__, row, field);
+                return NULL;
+        }
+ 
+        if (dbi_result_seek_row(result, row) < 1) {
+                trace(TRACE_WARNING, "%s,%s: row is NULL\n",
+                      __FILE__, __func__);
+                return NULL;
+        }
+ 
+        result = last_row[field];
+               fieldvalue = dbi_result_get_string_idx(result, field);
+        if (fieldvalue == NULL)
+                trace(TRACE_WARNING, "%s,%s: result is null\n",
+                      __FILE__, __func__);
+        return fieldvalue;
+}
+
+int db_disconnect()
+{
+        if (result)
+                db_free_result();
+               dbi_conn_close(conn);
+               // XXX dbi_shutdown() ??
+        return 0;
+}
+
+int db_check_connection()
+{
+               if (dbi_conn_ping(conn) == 0) {
+                trace(TRACE_DEBUG, "%s,%s: no database connection, trying "
+                      "to establish on.", __FILE__, __func__);
+                if (db_connect() < 0) {
+                        trace(TRACE_ERROR, "%s,%s: unable to connect to "
+                              "database.", __FILE__, __func__);
+                        return -1;
+                }
+        }
+        return 0;
+}
+
+u64_t db_insert_result(const char *sequence_identifier UNUSED)
+{
+               return dbi_conn_sequence_last(conn, UNUSED);
+}
+
+int db_query(const char *the_query)
+{
+        unsigned querysize = 0;
+        if (db_check_connection() < 0) {
+                trace(TRACE_ERROR, "%s,%s: no database connection",
+                      __FILE__, __func__);
+                return -1;
+        }
+        if (the_query != NULL) {
+                querysize = (unsigned) strlen(the_query);
+                if (querysize > 0) {
+                        trace(TRACE_DEBUG, "%s,%s: "
+                              "executing query [%s]",
+                              __FILE__, __func__, the_query);
+                                               result = dbi_conn_query(conn, 
the_query);
+                        if (result == NULL) {
+                                trace(TRACE_ERROR, "%s,%s: "
+                                      "query [%s] failed",
+                                      __FILE__, __func__, the_query);
+                               /* trace(TRACE_ERROR, "%s,%s: "
+                                      "mysql_real_query failed: %s",
+                                      __FILE__, __func__,
+                                      mysql_error(&conn)); // XXX TODO */
+                                return -1;
+                        }
+                } else {
+                        trace(TRACE_ERROR, "%s,%s: "
+                              "querysize is wrong: [%d]", __FILE__,
+                              __func__, querysize);
+                        return -1;
+                }
+        } else {
+                trace(TRACE_ERROR, "%s,%s: "
+                      "query buffer is NULL, this is not supposed to happen\n",
+                      __FILE__, __func__);
+                return -1;
+        }
+ 
+        //res = mysql_store_result(&conn);
+ 
+        return 0;
+}
+
+unsigned long db_escape_string(char *to,
+                               const char *from, unsigned long length)
+{
+       // XXX TODO
+       //      return dbi_driver_quote_string() or 
dbi_driver_quote_string_copy() ??
+        return mysql_real_escape_string(&conn, to, from, length);
+}
+ 
+int db_do_cleanup(const char **tables, int num)
+{
+       // XXX TODO
+        char the_query[DEF_QUERYSIZE];
+        int i;
+        int result = 0;
+ 
+        for (i = 0; i < num; i++) {
+                snprintf(the_query, DEF_QUERYSIZE, "OPTIMIZE TABLE %s",
+                         tables[i]);
+ 
+                if (db_query(the_query) == -1) {
+                        trace(TRACE_ERROR,
+                              "%s,%s: error optimizing table [%s]",
+                              __FILE__, __func__, tables[i]);
+                        result = -1;
+                }
+                db_free_result();
+        }
+        return result;
+}
+ 
+u64_t db_get_length(unsigned row, unsigned field)
+{
+       // XXX TODO
+        if (!res) {
+                trace(TRACE_WARNING, "%s,%s: result set is null\n",
+                      __FILE__, __func__);
+                return -1;
+        }
+ 
+        if ((row >= db_num_rows()) || (field >= db_num_fields())) {
+                trace(TRACE_ERROR, "%s, %s: "
+                      "row = %u, field = %u, bigger than size of result set",
+                      __FILE__, __func__, row, field);
+                return -1;
+        }
+ 
+        mysql_data_seek(res, row);
+        last_row = mysql_fetch_row(res);
+        if (last_row == NULL) {
+                trace(TRACE_ERROR, "%s,%s: last_row = NULL",
+                      __FILE__, __func__);
+                return (u64_t) 0;
+        }
+        return (u64_t) mysql_fetch_lengths(res)[field];
+}
+ 
+u64_t db_get_affected_rows()
+{
+       return dbi_result_get_numrows_affected(result);
+}
+ 
+void db_use_msgbuf_result()
+{
+        stored_result = result;
+        result = msgbuf_result;
+}
+ 
+void db_store_msgbuf_result()
+{
+        msgbuf_result = result;
+        result = stored_result;
+}
+ 
+void *db_get_result_set()
+{
+        return (void *) result;
+}
+ 
+void db_set_result_set(void *the_result_set)
+{
+        result = (dbi_result) the_result_set;
+}

Attachment: signature.asc
Description: Digital signature



Reply via email to