qof-sqlite.c

00001 /****************************************************************
00002  *            qof-sqlite.c
00003  *
00004  *  Sun Jan 15 12:52:46 2006
00005  *  Copyright  2006  Neil Williams
00006  *  linux@codehelp.co.uk
00007  ****************************************************************/
00008 /*
00009  *  This program is free software; you can redistribute it and/or modify
00010  *  it under the terms of the GNU General Public License as published by
00011  *  the Free Software Foundation; either version 2 of the License, or
00012  *  (at your option) any later version.
00013  *
00014  *  This program is distributed in the hope that it will be useful,
00015  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  *  GNU General Public License for more details.
00018  *
00019  *  You should have received a copy of the GNU General Public License
00020  *  along with this program; if not, write to the Free Software
00021  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00022  */
00023  
00024 #define _GNU_SOURCE
00025 #include "config.h"
00026 #include <glib/gstdio.h>
00027 #include <sqlite.h>
00028 #include <glib.h>
00029 #include "qof.h"
00030 
00031 #define QOF_MOD_SQLITE "qof-sqlite-module"
00032 #define ACCESS_METHOD "sqlite"
00033 
00034 /* Indicates an item with high priority.  */
00035 #define PRIORITY_HIGH       9
00036 /* Indicates an item with default priority. */
00037 #define PRIORITY_STANDARD   5
00038 /* Indicates a low priority item.  */
00039 #define PRIORITY_LOW        0
00040 /* Indicate an error to sqlite */
00041 #define QSQL_ERROR          -1
00042 
00043 #define END_DB_VERSION " dbversion int );"
00044 
00045 static QofLogModule log_module = QOF_MOD_SQLITE;
00046 
00047 typedef enum
00048 {
00049     SQL_NONE = 0,  /* no operation defined. init value. */
00050     SQL_CREATE,    /* Create a new database */
00051     SQL_LOAD,      /* Load all data from existing database. */
00052     SQL_WRITE,     /* Write / sync all data to the database. */
00053     SQL_INSERT,    /* Run a single INSERT statement. */
00054     SQL_DELETE,    /* Run a single DELETE statement. */
00055     SQL_UPDATE     /* Run a single UPDATE statement. */
00056 }qsql_statement_type;
00057 
00058 typedef struct
00059 {
00060     QofBackend be;
00061     sqlite *sqliteh;
00062     qsql_statement_type stm_type;
00063     gint dbversion;
00064     const gchar *fullpath;
00065     gchar *err;
00066     gchar *sql_str;
00067     gboolean error;
00068     QofIdType e_type;
00069     QofBook * book;
00070 } QSQLiteBackend;
00071 
00072 static gchar*
00073 qsql_param_to_sql(QofParam *param)
00074 {
00075     if(0 == safe_strcmp(param->param_type, QOF_TYPE_STRING))
00076         return g_strdup_printf(" %s mediumtext", param->param_name);
00077     if(0 == safe_strcmp(param->param_type, QOF_TYPE_BOOLEAN))
00078         return g_strdup_printf(" %s int", param->param_name);
00079     if(0 == safe_strcmp(param->param_type, QOF_TYPE_GUID))
00080         return g_strdup_printf(" %s char(32) PRIMARY KEY NOT NULL",
00081             param->param_name);
00082     if((0 == safe_strcmp(param->param_type, QOF_TYPE_NUMERIC))
00083         || (0 == safe_strcmp(param->param_type, QOF_TYPE_DOUBLE))
00084         || (0 == safe_strcmp(param->param_type, QOF_TYPE_DEBCRED)))
00085     {
00086         return g_strdup_printf(" %s double", param->param_name);
00087     }
00088     if(0 == safe_strcmp(param->param_type, QOF_TYPE_INT32))
00089         return g_strdup_printf(" %s int", param->param_name);
00090 #ifndef QOF_DISABLE_DEPRECATED
00091     if((0 == safe_strcmp(param->param_type, QOF_TYPE_DATE)) ||
00092         (0 == safe_strcmp(param->param_type, QOF_TYPE_TIME)))
00093 #else
00094     if(0 == safe_strcmp(param->param_type, QOF_TYPE_TIME))
00095 #endif
00096         return g_strdup_printf(" %s datetime", param->param_name);
00097     if(0 == safe_strcmp(param->param_type, QOF_TYPE_CHAR))
00098         return g_strdup_printf(" %s char(1)", param->param_name);
00099     if(0 == safe_strcmp(param->param_type, QOF_TYPE_KVP))
00100         return g_strdup_printf(" %s mediumtext", param->param_name);
00101     if(0 == safe_strcmp(param->param_type, QOF_TYPE_COLLECT))
00102         return g_strdup_printf(" %s char(32)", param->param_name);
00103     return g_strdup_printf(" %s char(32)", param->param_name);
00104 }
00105 
00106 struct qsql_builder
00107 {
00108     QSQLiteBackend *qsql_be;
00109     QofEntity *ent;
00110     gchar *sql_str;
00111 };
00112 
00113 static void
00114 create_param_list (QofParam *param, gpointer user_data)
00115 {
00116     struct qsql_builder *qb;
00117     qb = (struct qsql_builder*)user_data;
00118 
00119     if (!g_str_has_suffix (qb->sql_str, "("))
00120         qb->sql_str = g_strconcat (qb->sql_str, ", ", 
00121             param->param_name, NULL);
00122     else
00123         qb->sql_str = g_strconcat (qb->sql_str, 
00124             param->param_name, NULL);
00125 }
00126 
00127 static void
00128 create_each_param (QofParam *param, gpointer user_data)
00129 {
00130     gchar *value;
00131     struct qsql_builder *qb;
00132     qb = (struct qsql_builder*)user_data;
00133 
00135     value = qof_util_param_to_string (qb->ent, param);
00136     if (value)
00137         g_strescape (value, NULL);
00138     if (!value)
00139         value = g_strdup ("");
00140     if (!g_str_has_suffix (qb->sql_str, "("))
00141         qb->sql_str = g_strconcat (qb->sql_str, ", \"", 
00142             value, "\"", NULL);
00143     else
00144         qb->sql_str = g_strconcat (qb->sql_str, "\"",
00145             value, "\"", NULL);
00146 }
00147 
00148 /* need new-style event handlers for insert and update 
00149 insert runs after QOF_EVENT_CREATE
00150 delete runs before QOF_EVENT_DESTROY
00151 */
00152 static void 
00153 delete_event (QofEntity *ent, QofEventId event_type, 
00154               gpointer handler_data, gpointer event_data)
00155 {
00156     QofBackend *be;
00157     QSQLiteBackend *qsql_be;
00158     gchar gstr[GUID_ENCODING_LENGTH+1];
00159     gchar * sql_str;
00160 
00161     qsql_be = (QSQLiteBackend*)handler_data;
00162     be = (QofBackend*)qsql_be;
00163     if (!ent)
00164         return;
00165     if (0 == safe_strcmp (ent->e_type, QOF_ID_BOOK))
00166         return;
00167     ENTER (" %s", ent->e_type);
00168     switch (event_type)
00169     {
00170         case QOF_EVENT_DESTROY :
00171         {
00172             guid_to_string_buff (qof_entity_get_guid (ent), gstr);
00173             sql_str = g_strdup_printf ("DELETE from %s ", 
00174                 ent->e_type);
00175             sql_str = g_strconcat (sql_str, 
00176                 "WHERE ", QOF_TYPE_GUID, "='", gstr,
00177                 "';", NULL);
00178             DEBUG (" sql_str=%s", sql_str);
00179             if(sqlite_exec (qsql_be->sqliteh, sql_str, 
00180                 NULL, qsql_be, &qsql_be->err) !=
00181                 SQLITE_OK)
00182             {
00183                 qof_backend_set_error(be, ERR_BACKEND_SERVER_ERR);
00184                 qsql_be->error = TRUE;
00185                 PERR (" %s", qsql_be->err);
00186             }
00187             break;
00188         }
00189         default : break;
00190     }
00191     LEAVE (" ");    
00192 }
00193 
00194 static void 
00195 create_event (QofEntity *ent, QofEventId event_type, 
00196               gpointer handler_data, gpointer event_data)
00197 {
00198     QofBackend *be;
00199     struct qsql_builder qb;
00200     QSQLiteBackend *qsql_be;
00201 
00202     qsql_be = (QSQLiteBackend*)handler_data;
00203     be = (QofBackend*)qsql_be;
00204     if (!ent)
00205         return;
00206     if (0 == safe_strcmp (ent->e_type, QOF_ID_BOOK))
00207         return;
00208     ENTER (" %s", ent->e_type);
00209     switch (event_type)
00210     {
00211         case QOF_EVENT_CREATE :
00212         {
00213             qb.ent = ent;
00214             qb.sql_str = g_strdup_printf ("INSERT into %s (", 
00215                 ent->e_type);
00216             qof_class_param_foreach (ent->e_type, create_param_list, 
00217                 &qb);
00218             qb.sql_str = g_strconcat (qb.sql_str, ") VALUES (", NULL);
00219             qof_class_param_foreach (ent->e_type, 
00220                 create_each_param, &qb);
00221             qb.sql_str = g_strconcat (qb.sql_str, ");", NULL);
00222             DEBUG (" sql_str=%s", qb.sql_str);
00223             if(sqlite_exec (qsql_be->sqliteh, qb.sql_str, 
00224                 NULL, qsql_be, &qsql_be->err) !=
00225                 SQLITE_OK)
00226             {
00227                 qof_backend_set_error(be, ERR_BACKEND_SERVER_ERR);
00228                 qsql_be->error = TRUE;
00229                 PERR (" %s", qsql_be->err);
00230             }
00231             else
00232                 ((QofInstance*)ent)->dirty = FALSE;
00233             break;
00234         }
00235         default : break;
00236     }
00237     LEAVE (" ");
00238 }
00239 
00240 static void
00241 qsql_modify (QofBackend *be, QofInstance *inst)
00242 {
00243     struct qsql_builder qb;
00244     QSQLiteBackend *qsql_be;
00245     gchar gstr[GUID_ENCODING_LENGTH+1];
00246     gchar * param_str;
00247 
00248     qsql_be = (QSQLiteBackend*)be;
00249     if (!inst)
00250         return;
00251     if (!inst->param)
00252         return;
00253     ENTER (" ");
00254 
00255     guid_to_string_buff (qof_instance_get_guid (inst), gstr);
00256     qb.ent = (QofEntity*)inst;
00257     param_str = qof_util_param_to_string (qb.ent, inst->param);
00258     g_strescape (param_str, NULL);
00259     qb.sql_str = g_strdup_printf ("UPDATE %s SET %s=\"",
00260         qb.ent->e_type, inst->param->param_name);
00261     qb.sql_str = g_strconcat (qb.sql_str, param_str, 
00262         "\" WHERE ", QOF_TYPE_GUID, "='", gstr,
00263         "';", NULL);
00264     DEBUG (" sql_str=%s param_Str=%s", qb.sql_str, param_str);
00265     if(sqlite_exec (qsql_be->sqliteh, qb.sql_str, 
00266         NULL, qsql_be, &qsql_be->err) !=
00267         SQLITE_OK)
00268     {
00269         qof_backend_set_error(be, ERR_BACKEND_SERVER_ERR);
00270         qsql_be->error = TRUE;
00271         PERR (" %s", qsql_be->err);
00272     }
00273     else
00274         inst->dirty = FALSE;
00275     LEAVE (" ");
00276 }
00277 
00278 static gint 
00279 qsql_record_foreach(gpointer data, gint col_num, gchar **strings,
00280                     gchar **columnNames)
00281 {
00282     QSQLiteBackend *qsql_be;
00283     const QofParam * param;
00284     QofInstance * inst;
00285     gint i;
00286 
00287     g_return_val_if_fail(data, QSQL_ERROR);
00288     qsql_be = (QSQLiteBackend*)data;
00289     qof_event_suspend ();
00290     inst = (QofInstance*)qof_object_new_instance (qsql_be->e_type,
00291         qsql_be->book);
00292     ENTER (" loading %s", qsql_be->e_type);
00293     for(i = 0;i < col_num; i++)
00294     {
00295         /* get param and set as string */
00296         param = qof_class_get_parameter (qsql_be->e_type, 
00297             columnNames[i]);
00298         if (!param)
00299             continue;
00300         if (0 == safe_strcmp (columnNames[i], QOF_TYPE_GUID))
00301         {
00302             GUID * guid;
00303             guid = guid_malloc();
00304             if (!string_to_guid(strings[i], guid))
00305             {
00306                 DEBUG (" set guid failed:%s", strings[i]);
00307                 return QSQL_ERROR;
00308             }
00309             qof_entity_set_guid (&inst->entity, guid);
00310         }
00311         if (strings[1])
00312             qof_util_param_set_string (&inst->entity, param, strings[i]);
00313     }
00314     qof_event_resume ();
00315     LEAVE (" ");
00316     return SQLITE_OK;
00317 }
00318 
00319 static void
00320 qsql_param_foreach(QofParam *param, gpointer data)
00321 {
00322     QSQLiteBackend *qsql_be;
00323     gchar *p_str;
00324 
00325     qsql_be = (QSQLiteBackend*)data;
00326     p_str = qsql_param_to_sql(param);
00327     qsql_be->sql_str = g_strconcat(qsql_be->sql_str, 
00328         p_str, ",", NULL);
00329     g_free(p_str);
00330 }
00331 
00332 static gint 
00333 qsql_update_foreach (gpointer data, gint col_num, gchar **strings,
00334                     gchar **columnNames)
00335 {
00336     const QofParam * param;
00337     QofInstance * inst;
00338     struct qsql_builder * qb;
00339     QSQLiteBackend *qsql_be;
00340     QofBackend * be;
00341     gchar gstr[GUID_ENCODING_LENGTH+1];
00342     gchar * param_str;
00343     gint i;
00344 
00345     qb = (struct qsql_builder*) data;
00346     qsql_be = qb->qsql_be;
00347     be = (QofBackend*)qsql_be;
00348     inst = (QofInstance*) qb->ent;
00349     if (!inst->dirty)
00350         return SQLITE_OK;
00351     ENTER (" ");
00352     guid_to_string_buff (qof_entity_get_guid (qb->ent), gstr);
00353     for(i = 0;i < col_num; i++)
00354     {
00355         param = qof_class_get_parameter (qb->ent->e_type, 
00356             columnNames[i]);
00357         if (!param)
00358             continue;
00359         param_str = qof_util_param_to_string (qb->ent, param);
00360         g_strescape (param_str, NULL);
00361         qb->sql_str = g_strdup_printf ("UPDATE %s SET %s=\"",
00362             qb->ent->e_type, param->param_name);
00363         qb->sql_str = g_strconcat (qb->sql_str, param_str, 
00364             "\" WHERE ", QOF_TYPE_GUID, "='", gstr, "';", NULL);
00365         DEBUG (" sql_str=%s param_str=%s", qb->sql_str, param_str);
00366         if(sqlite_exec (qsql_be->sqliteh, qb->sql_str, 
00367             NULL, qsql_be, &qsql_be->err) != SQLITE_OK)
00368         {
00369             qof_backend_set_error(be, ERR_BACKEND_SERVER_ERR);
00370             qsql_be->error = TRUE;
00371             PERR (" %s", qsql_be->err);
00372         }
00373         else
00374             inst->dirty = FALSE;
00375     }
00376     LEAVE (" ");
00377     return SQLITE_OK;
00378 }
00379 
00380 static void
00381 check_state (QofEntity * ent, gpointer user_data)
00382 {
00383     gchar gstr[GUID_ENCODING_LENGTH+1];
00384     QSQLiteBackend *qsql_be;
00385     struct qsql_builder qb;
00386     QofBackend *be;
00387 
00388     qsql_be = (QSQLiteBackend*) user_data;
00389     be = (QofBackend*)qsql_be;
00390     /* check if this entity already exists */
00391     guid_to_string_buff (qof_entity_get_guid (ent), gstr);
00392     qsql_be->sql_str = g_strdup_printf(
00393         "SELECT * FROM %s where guid = \"%s\";", ent->e_type, gstr);
00394     PINFO (" write: %s", qsql_be->sql_str);
00395     qb.ent = ent;
00396     /* update each dirty instance */
00397     if(sqlite_exec (qsql_be->sqliteh, qsql_be->sql_str, 
00398         qsql_update_foreach, &qb, &qsql_be->err) !=
00399         SQLITE_OK)
00400     {
00401         qof_backend_set_error(be, ERR_BACKEND_SERVER_ERR);
00402         qsql_be->error = TRUE;
00403         PERR (" %s", qsql_be->err);
00404     }
00405     else
00406     {
00407         /* create new entity */
00408         g_free (qsql_be->sql_str);
00409         qb.sql_str = g_strdup_printf ("INSERT into %s (", 
00410             ent->e_type);
00411         qof_class_param_foreach (ent->e_type, 
00412             create_param_list, &qb);
00413         qb.sql_str = g_strconcat (qb.sql_str, ") VALUES (", NULL);
00414         qof_class_param_foreach (ent->e_type, 
00415             create_each_param, &qb);
00416         qb.sql_str = g_strconcat (qb.sql_str, ");", NULL);
00417         DEBUG (" sql_str= %s", qb.sql_str);
00418         if(sqlite_exec (qsql_be->sqliteh, qb.sql_str, 
00419             NULL, qsql_be, &qsql_be->err) != SQLITE_OK)
00420         {
00421             qof_backend_set_error(be, ERR_BACKEND_SERVER_ERR);
00422             qsql_be->error = TRUE;
00423             PERR (" %s", qsql_be->err);
00424         }
00425     }
00426 }
00427 
00428 static void
00429 qsql_class_foreach(QofObject *obj, gpointer data)
00430 {
00431     QSQLiteBackend *qsql_be;
00432     QofBackend *be;
00433 
00434     qsql_be = (QSQLiteBackend*)data;
00435     be = (QofBackend*)qsql_be;
00436     qsql_be->e_type = obj->e_type;
00437     ENTER (" obj_type=%s", qsql_be->e_type);
00438     switch (qsql_be->stm_type)
00439     {
00440         case SQL_NONE :
00441         case SQL_INSERT :
00442         case SQL_DELETE :
00443         case SQL_UPDATE :
00444         {
00445             break;
00446         }
00447         case SQL_CREATE :
00448         {
00449             qsql_be->sql_str = g_strdup_printf(
00450                 "CREATE TABLE %s (", obj->e_type);
00451             qof_class_param_foreach(obj->e_type, 
00452                 qsql_param_foreach, data);
00453             qsql_be->sql_str = g_strconcat(qsql_be->sql_str,
00454                 END_DB_VERSION, NULL);
00455             if(sqlite_exec (qsql_be->sqliteh, qsql_be->sql_str, 
00456                 NULL, NULL, &qsql_be->err) != SQLITE_OK)
00457             {
00458                 qof_backend_set_error(be, ERR_BACKEND_DATA_CORRUPT);
00459                 qsql_be->error = TRUE;
00460                 PERR (" %s", qsql_be->err);
00461             }
00462             g_free(qsql_be->sql_str);
00463             break;
00464         }
00465         case SQL_LOAD :
00466         {
00467             qsql_be->sql_str = g_strdup_printf(
00468                 "SELECT * FROM %s;", obj->e_type);
00469             PINFO (" sql=%s", qsql_be->sql_str);
00470             if(sqlite_exec(qsql_be->sqliteh, qsql_be->sql_str, 
00471                 qsql_record_foreach, qsql_be, &qsql_be->err) !=
00472                     SQLITE_OK)
00473             {
00474                 qof_backend_set_error(be, ERR_BACKEND_SERVER_ERR);
00475                 qsql_be->error = TRUE;
00476                 PERR (" %s", qsql_be->err);
00477             }
00478             break;
00479         }
00480         case SQL_WRITE : 
00481         {
00482             if (!qof_book_not_saved (qsql_be->book))
00483                 break;
00484             /* not all objects generate a create event
00485             when the entity is created. */
00486             qof_object_foreach (obj->e_type, qsql_be->book,
00487                 check_state, qsql_be);
00488             break;
00489         }
00490     }
00491     LEAVE (" ");
00492 }
00493 
00494 static void
00495 qsql_backend_createdb(QofBackend *be, QofSession *session)
00496 {
00497     QSQLiteBackend *qsql_be;
00498 
00499     g_return_if_fail(be || session);
00500     ENTER (" ");
00501     qsql_be = (QSQLiteBackend*)be;
00502     qsql_be->stm_type = SQL_CREATE;
00503     qsql_be->book = qof_session_get_book (session);
00504     qsql_be->sqliteh = sqlite_open (qsql_be->fullpath, 0, 
00505         &qsql_be->err);
00506     if(!qsql_be->sqliteh)
00507     {
00508         qof_backend_set_error(be, ERR_BACKEND_CANT_CONNECT);
00509         qsql_be->error = TRUE;
00510         PERR (" %s", qsql_be->err);
00511         LEAVE (" ");
00512         return;
00513     }
00514     qof_object_foreach_type(qsql_class_foreach, qsql_be);
00515     PINFO(" %s", qsql_be->sql_str);
00516     LEAVE (" ");
00517 }
00518 
00519 static void
00520 qsql_backend_opendb (QofBackend *be, QofSession *session)
00521 {
00522     QSQLiteBackend *qsql_be;
00523 
00524     g_return_if_fail(be || session);
00525     ENTER (" ");
00526     qsql_be = (QSQLiteBackend*)be;
00527     qsql_be->sqliteh = sqlite_open (qsql_be->fullpath, 0, 
00528         &qsql_be->err);
00529     if(!qsql_be->sqliteh)
00530     {
00531         qof_backend_set_error(be, ERR_BACKEND_CANT_CONNECT);
00532         qsql_be->error = TRUE;
00533         PERR (" %s", qsql_be->err);
00534     }
00535     LEAVE (" ");
00536 }
00537 
00538 static void
00539 qsqlite_session_begin(QofBackend *be, QofSession *session, const 
00540                       gchar *book_path, gboolean ignore_lock,
00541                       gboolean create_if_nonexistent)
00542 {
00543     QSQLiteBackend *qsql_be;
00544     gchar** pp;
00545     struct stat statinfo;
00546     gint stat_val;
00547 
00548     g_return_if_fail(be);
00549     ENTER (" book_path=%s", book_path);
00550     qsql_be = (QSQLiteBackend*)be;
00551     qsql_be->fullpath = NULL;
00552     be->fullpath = g_strdup (book_path);
00553     if(book_path == NULL)
00554     {
00555         qof_backend_set_error(be, ERR_BACKEND_BAD_URL);
00556         qsql_be->error = TRUE;
00557         LEAVE (" bad URL");
00558         return;
00559     }
00560     /* book_path => sqlite_file_name */
00561     pp = g_strsplit(book_path, ":", 2);
00562     if(0 == safe_strcmp(pp[0], ACCESS_METHOD))
00563     {
00564         qsql_be->fullpath = g_strdup(pp[1]);
00565         g_strfreev (pp);
00566     }
00567     stat_val = g_stat (qsql_be->fullpath, &statinfo);
00568     if (!S_ISREG (statinfo.st_mode) || statinfo.st_size == 0)
00569         qsql_backend_createdb (be, session);
00570     qsql_backend_opendb (be, session);
00571     if(qsql_be->error) 
00572     { 
00573         LEAVE(" open failed"); 
00574         return; 
00575     }
00576     qof_backend_set_error(be, ERR_BACKEND_NO_ERR);
00577     qof_event_register_handler (create_event, qsql_be);
00578     qof_event_register_handler (delete_event, qsql_be);
00579     LEAVE (" db=%s", qsql_be->fullpath);
00580 }
00581 
00582 static void
00583 qsqlite_db_load (QofBackend *be, QofBook *book)
00584 {
00585     QSQLiteBackend *qsql_be;
00586 
00587     g_return_if_fail(be);
00588     ENTER (" ");
00589     qsql_be = (QSQLiteBackend*)be;
00590     qsql_be->stm_type = SQL_LOAD;
00591     qsql_be->book = book;
00592     /* iterate over registered objects */
00593     qof_object_foreach_type(qsql_class_foreach, qsql_be);
00594     LEAVE (" ");
00595 }
00596 
00597 static void
00598 qsqlite_write_db (QofBackend *be, QofBook *book)
00599 {
00600     QSQLiteBackend *qsql_be;
00601 
00602     g_return_if_fail(be);
00603     qsql_be = (QSQLiteBackend*)be;
00604     qsql_be->stm_type = SQL_WRITE;
00605     qsql_be->book = book;
00606     /* update each record with current state */
00607     qof_object_foreach_type(qsql_class_foreach, qsql_be);
00608 }
00609 
00610 static gboolean
00611 qsql_determine_file_type (const gchar *path)
00612 {
00613     return TRUE;
00614 }
00615 
00616 static void
00617 qsqlite_session_end (QofBackend *be)
00618 {
00619     QSQLiteBackend *qsql_be;
00620 
00621     g_return_if_fail(be);
00622     qsql_be = (QSQLiteBackend*)be;
00623     if (qsql_be->sqliteh)
00624         sqlite_close (qsql_be->sqliteh);
00625 }
00626 
00627 static void
00628 qsqlite_destroy_backend (QofBackend *be)
00629 {
00630     g_free (be);
00631 }
00632 
00633 static void
00634 qsql_provider_free (QofBackendProvider *prov)
00635 {
00636     prov->provider_name = NULL;
00637     prov->access_method = NULL;
00638     g_free (prov);
00639 }
00640 
00641 static QofBackend*
00642 qsql_backend_new(void)
00643 {
00644     QSQLiteBackend *qsql_be;
00645     QofBackend *be;
00646 
00647     ENTER (" ");
00648     qsql_be = g_new0(QSQLiteBackend, 1);
00649     be = (QofBackend*) qsql_be;
00650     qof_backend_init(be);
00651     qsql_be->dbversion = QOF_OBJECT_VERSION;
00652     qsql_be->stm_type = SQL_NONE;
00653     be->session_begin = qsqlite_session_begin;
00654 
00655     be->session_end = qsqlite_session_end;
00656     be->destroy_backend = qsqlite_destroy_backend;
00657     be->load = qsqlite_db_load;
00658     be->save_may_clobber_data = NULL;
00659     be->begin = NULL;
00660     /* commit: write to sqlite, commit undo record. */
00661     be->commit = qsql_modify;
00662     be->rollback = NULL;
00663     /* would need a QofQuery back to QofSqlQuery conversion. */
00664     be->compile_query = NULL;
00665     /* unused */
00666     be->free_query = NULL;
00667     be->run_query = NULL;
00668     be->counter = NULL;
00669     /* The QOF SQLite backend is not multi-user - all QOF users are the same. */
00670     be->events_pending = NULL;
00671     be->process_events = NULL;
00672 
00673     be->sync = qsqlite_write_db;
00674     be->load_config = NULL;
00675     be->get_config = NULL;
00676     LEAVE (" ");
00677     return be;
00678 }
00679 
00680 void qof_sqlite_provider_init(void)
00681 {
00682     QofBackendProvider *prov;
00683 
00684     ENTER (" ");
00685     prov = g_new0 (QofBackendProvider, 1);
00686     prov->provider_name = "QOF SQLite Backend Version 0.1";
00687     prov->access_method = ACCESS_METHOD;
00688     prov->partial_book_supported = TRUE;
00689     prov->backend_new = qsql_backend_new;
00690     prov->check_data_type = qsql_determine_file_type;
00691     prov->provider_free = qsql_provider_free;
00692     qof_backend_register_provider (prov);
00693     LEAVE (" ");
00694 }
00695 
00696 /* ================= END OF FILE =================== */

Generated on Fri Sep 15 14:24:56 2006 for QOF by  doxygen 1.4.7