QOF  0.8.0
qoferror.c
00001 /*****************************************************************
00002  *            qoferror.c
00003  *
00004  *  Sun Sep 10 19:55:08 2006
00005  *  Copyright  2006-2008  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 #include "config.h"
00025 #include "qof.h"
00026 #include "qoferror-p.h"
00027 #include "qofsession-p.h"
00028 
00029 struct QofError_s
00030 {
00031     QofErrorId id;
00032     gchar * message;
00033     const gchar * filename;
00034     gboolean use_file;
00035     QofTime * qt;
00036 };
00037 
00038 /* All registered errors - hashed only once per session. */
00039 static GHashTable * error_table = NULL;
00040 static gint32 count = 0;
00041 static QofLogModule log_module = QOF_MOD_ERROR;
00042 
00043 void
00044 qof_error_init (void)
00045 {
00046     error_table = g_hash_table_new (g_direct_hash, g_direct_equal);
00047 }
00048 
00049 static void
00050 qof_error_free (QofError * error)
00051 {
00052     if (error->qt)
00053         qof_time_free (error->qt);
00054     g_free (error->message);
00055     g_free (error);
00056 }
00057 
00058 /* clear the table of registered error values */
00059 static void
00060 clear_table (gpointer key, gpointer value, gpointer user_data)
00061 {
00062     qof_error_free ((QofError*)value);
00063 }
00064 
00065 void
00066 qof_error_close (void)
00067 {
00068     g_hash_table_foreach (error_table, clear_table, NULL);
00069     g_hash_table_destroy (error_table);
00070 }
00071 
00072 QofErrorId
00073 qof_error_register (const gchar * err_message, gboolean use_file)
00074 {
00075     QofError * qerr;
00076 
00077     ENTER (" ");
00078     qerr = g_new0 (QofError, 1);
00079     count++;
00080     qerr->id = count;
00081     if (use_file)
00082     {
00083         gchar * spec;
00084 
00085         spec = g_strrstr (err_message, "%s");
00086         use_file = (spec) ? TRUE : FALSE;
00087     }
00088     qerr->use_file = use_file;
00089     qerr->message = g_strdup (err_message);
00090     g_hash_table_insert (error_table, GINT_TO_POINTER(qerr->id), qerr);
00091     LEAVE (" ");
00092     return qerr->id;
00093 }
00094 
00095 void
00096 qof_error_unregister (QofErrorId id)
00097 {
00098     QofError * qerr;
00099     gboolean result;
00100 
00101     ENTER (" ");
00102     qerr = g_hash_table_lookup (error_table, GINT_TO_POINTER(id));
00103     qof_error_free (qerr);
00104     result = g_hash_table_remove (error_table, 
00105         GINT_TO_POINTER(id));
00106     if (!result)
00107         LEAVE ("unable to remove registered error.");
00108     LEAVE (" ok.");
00109 }
00110 
00111 void
00112 qof_error_set (QofSession * session, QofErrorId error)
00113 {
00114     QofError * qerr, * set;
00115 
00116     g_return_if_fail (session);
00117     if (error == QOF_SUCCESS)
00118     {
00119         DEBUG (" passed success, not error.");
00120         return;
00121     }
00122     qerr = g_hash_table_lookup (error_table, GINT_TO_POINTER(error));
00123     if (!qerr)
00124     {
00125         DEBUG (" failed hash table lookup");
00126         return;
00127     }
00128     session->last_err = error;
00129     if (session->error_message)
00130         g_free (session->error_message);
00131     if (qerr->use_file)
00132         session->error_message = g_strdup_printf (qerr->message,
00133             qof_session_get_url (session));
00134     else
00135         session->error_message = g_strdup (qerr->message);
00136     if (!session->backend)
00137         return;
00138     /* create a new error for the list */
00139     set = g_new0 (QofError, 1);
00140     if (qerr->use_file)
00141         set->message = g_strdup_printf (qerr->message,
00142             qof_session_get_file_path (session));
00143     else
00144         set->message = g_strdup (qerr->message);
00145     set->id = error;
00146     set->qt = qof_time_get_current ();
00147     session->backend->error_stack = 
00148         g_list_prepend (session->backend->error_stack, set);
00149 }
00150 
00151 void
00152 qof_error_set_be (QofBackend * be, QofErrorId error)
00153 {
00154     QofError * qerr, * set;
00155 
00156     g_return_if_fail (be);
00157     if (error == QOF_SUCCESS)
00158         return;
00159     qerr = g_hash_table_lookup (error_table, GINT_TO_POINTER(error));
00160     if (!qerr)
00161         return;
00162     /* create a new error for the list */
00163     set = g_new0 (QofError, 1);
00164     if (qerr->use_file)
00165         set->message = g_strdup_printf (qerr->message, be->fullpath);
00166     else
00167         set->message = g_strdup (qerr->message);
00168     set->id = error;
00169     set->qt = qof_time_get_current ();
00170     be->error_stack = g_list_prepend (be->error_stack,
00171         set);
00172 }
00173 
00174 /* clear the list of actual errors */
00175 static void
00176 clear_list (gpointer value, gpointer user_data)
00177 {
00178     qof_error_free ((QofError*)value);
00179 }
00180 
00181 void
00182 qof_error_clear (QofSession * session)
00183 {
00184     g_return_if_fail (session);
00185     if (!session->backend)
00186         return;
00187     g_list_foreach (session->backend->error_stack, clear_list, NULL);
00188     g_list_free (session->backend->error_stack);
00189     session->backend->error_stack = NULL;
00190     if (session->error_message)
00191         g_free (session->error_message);
00192     session->error_message = NULL;
00193     session->last_err = QOF_SUCCESS;
00194 }
00195 
00196 QofErrorId
00197 qof_error_check (QofSession * session)
00198 {
00199     g_return_val_if_fail (session, QOF_FATAL);
00200     return qof_error_check_be (session->backend);
00201 }
00202 
00203 QofErrorId
00204 qof_error_check_be (QofBackend * be)
00205 {
00206     QofError * qerr;
00207     GList * first;
00208 
00209     if (!be)
00210         return QOF_FATAL;
00211     if (g_list_length (be->error_stack) == 0)
00212         return QOF_SUCCESS;
00213     first = g_list_first (be->error_stack);
00214     qerr = (QofError*)first->data;
00215     if (!qerr)
00216         return QOF_FATAL;
00217     return qerr->id;
00218 }
00219 
00220 QofTime *
00221 qof_error_get_time_be (QofBackend * be)
00222 {
00223     QofError * qerr;
00224     GList * first;
00225 
00226     if (g_list_length(be->error_stack) == 0)
00227         return NULL;
00228     first = g_list_first (be->error_stack);
00229     qerr = (QofError*)first->data;
00230     return qerr->qt;
00231 }
00232 
00233 QofTime *
00234 qof_error_get_time (QofSession * session)
00235 {
00236     return qof_error_get_time_be (session->backend);
00237 }
00238 
00239 QofErrorId
00240 qof_error_get_id (QofSession * session)
00241 {
00242     QofErrorId id;
00243 
00244     g_return_val_if_fail (session, QOF_FATAL);
00245     id = QOF_SUCCESS;
00246     id = qof_error_get_id_be (session->backend);
00247     {
00248         QofError * qerr;
00249 
00250         qerr = g_hash_table_lookup (error_table, 
00251             GINT_TO_POINTER(id));
00252         if (!qerr)
00253         {
00254             DEBUG (" empty QofError value");
00255             return QOF_FATAL;
00256         }
00257         if (session->error_message)
00258             g_free (session->error_message);
00259         session->error_message = qerr->message;
00260         session->last_err = id;
00261     }
00262     return id;
00263 }
00264 
00265 QofErrorId
00266 qof_error_get_id_be (QofBackend * be)
00267 {
00268     QofError * qerr;
00269     GList * first;
00270 
00271     if (!be)
00272         return QOF_FATAL;
00273     if (g_list_length (be->error_stack) == 0)
00274         return QOF_SUCCESS;
00275     first = g_list_first (be->error_stack);
00276     qerr = (QofError*)first->data;
00277     if (!qerr)
00278         return QOF_FATAL;
00279     be->error_stack = 
00280         g_list_remove (be->error_stack, qerr);
00281     return qerr->id;
00282 }
00283 
00284 const gchar *
00285 qof_error_get_message (QofSession * session)
00286 {
00287     const gchar * msg;
00288 
00289     g_return_val_if_fail (session, NULL);
00290     if (!session->backend)
00291         return session->error_message;
00292     msg = qof_error_get_message_be (session->backend);
00293     DEBUG (" msg_1=%s", msg);
00294     return msg;
00295 }
00296 
00297 const gchar *
00298 qof_error_get_message_be (QofBackend * be)
00299 {
00300     QofError * qerr;
00301     GList * first;
00302 
00303     g_return_val_if_fail (be, NULL);
00304     if (g_list_length (be->error_stack) == 0)
00305     {
00306         DEBUG (" empty error stack");
00307         return NULL;
00308     }
00309     first = g_list_first (be->error_stack);
00310     qerr = (QofError*)first->data;
00311     if (!qerr)
00312     {
00313         DEBUG (" empty QofError value");
00314         return NULL;
00315     }
00316     DEBUG (" qerr->message=%s", qerr->message);
00317     be->error_stack = 
00318         g_list_remove (be->error_stack, qerr);
00319     return qerr->message;
00320 }