Transaction Logging
[GnuCash Engine: Core, Non-GUI Accounting Functions]


Detailed Description

The transaction logging mechanism provides a very simple, low-level logging of user input to a file. The goal of the transaction logger is to provide mechanism of last resort for recovering lost user data in the event of a crash.

Ideally, the storage backends should provide a robust journaling, logging and crash-recovery mechanism. But just in case they don't, or it didn't work, this mechanism provides a "Plan B" by providing a low-tech, fool-proof, simple logging system that can be used to recover user input. There are some simple command-line tools that will read a log and replay it.


Files

file  TransLog.h
 API for the transaction logger.

Functions

void xaccOpenLog (void)
void xaccCloseLog (void)
void xaccReopenLog (void)
void xaccTransWriteLog (Transaction *trans, char flag)
void xaccLogEnable (void)
void xaccLogDisable (void)
void xaccLogSetBaseName (const char *)
gboolean xaccFileIsCurrentLog (const gchar *name)


Function Documentation

gboolean xaccFileIsCurrentLog ( const gchar *  name  ) 

Test a filename to see if it is the name of the current logfile

Definition at line 126 of file TransLog.c.

00127 {
00128   gchar *base;
00129   gint result;
00130 
00131   if (!name || !trans_log_name)
00132     return FALSE;
00133 
00134   base = g_path_get_basename(name);
00135   result = (strcmp(base, trans_log_name) == 0);
00136   g_free(base);
00137   return result;
00138 }

void xaccLogDisable ( void   ) 

document me

Definition at line 88 of file TransLog.c.

00088 { gen_logs = 0; }

void xaccLogEnable ( void   ) 

document me

Definition at line 89 of file TransLog.c.

00089 { gen_logs = 1; }

void xaccLogSetBaseName ( const char *   ) 

The xaccLogSetBaseName() method sets the base filepath and the root part of the journal file name. If the journal file is already open, it will close it and reopen it with the new base name.

Definition at line 105 of file TransLog.c.

00106 {
00107    if (!basepath) return;
00108 
00109    g_free (log_base_name);
00110    log_base_name = g_strdup (basepath);
00111 
00112    if (trans_log) {
00113       xaccCloseLog();
00114       xaccOpenLog();
00115    }
00116 }

void xaccTransWriteLog ( Transaction trans,
char  flag 
)

Parameters:
trans The transaction to write out to the log
flag The engine currently uses the log mechanism with flag char set as follows: 'B' for 'begin edit' (followed by the transaction as it looks before any changes, i.e. the 'old value') 'D' for delete (i.e. delete the previous B; echoes the data in the 'old B') 'C' for commit (i.e. accept a previous B; data that follows is the 'new value') 'R' for rollback (i.e. revert to previous B; data that follows should be identical to old B)

Definition at line 203 of file TransLog.c.

00204 {
00205    GList *node;
00206    char trans_guid_str[GUID_ENCODING_LENGTH+1];
00207    char split_guid_str[GUID_ENCODING_LENGTH+1];
00208    const char *trans_notes; 
00209    char dnow[100], dent[100], dpost[100], drecn[100]; 
00210    Timespec ts;
00211 
00212    if (!gen_logs) return;
00213    if (!trans_log) return;
00214 
00215    timespecFromTime_t(&ts,time(NULL));
00216    gnc_timespec_to_iso8601_buff (ts, dnow);
00217 
00218    timespecFromTime_t(&ts,trans->date_entered.tv_sec);
00219    gnc_timespec_to_iso8601_buff (ts, dent);
00220 
00221    timespecFromTime_t(&ts,trans->date_posted.tv_sec);
00222    gnc_timespec_to_iso8601_buff (ts, dpost);
00223 
00224    guid_to_string_buff (xaccTransGetGUID(trans), trans_guid_str);
00225    trans_notes = xaccTransGetNotes(trans);
00226    fprintf (trans_log, "===== START\n");
00227 
00228    for (node = trans->splits; node; node = node->next) 
00229    {
00230       Split *split = node->data;
00231       const char * accname = "";
00232       char acc_guid_str[GUID_ENCODING_LENGTH+1];
00233       gnc_numeric amt,val;
00234 
00235       if (xaccSplitGetAccount(split))
00236       {
00237         accname = xaccAccountGetName (xaccSplitGetAccount(split));
00238         guid_to_string_buff(xaccAccountGetGUID(xaccSplitGetAccount(split)),
00239                             acc_guid_str);
00240       } 
00241       else 
00242       {
00243         acc_guid_str[0] = '\0';
00244       }
00245       
00246       timespecFromTime_t(&ts,split->date_reconciled.tv_sec);
00247       gnc_timespec_to_iso8601_buff (ts, drecn);
00248 
00249       guid_to_string_buff (xaccSplitGetGUID(split), split_guid_str);
00250       amt = xaccSplitGetAmount (split);
00251       val = xaccSplitGetValue (split);
00252 
00253       /* use tab-separated fields */
00254       fprintf (trans_log,
00255                "%c\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t"
00256                "%s\t%s\t%s\t%s\t%c\t%" G_GINT64_FORMAT "/%" G_GINT64_FORMAT "\t%" G_GINT64_FORMAT "/%" G_GINT64_FORMAT "\t%s\n",
00257                flag,
00258                trans_guid_str, split_guid_str,  /* trans+split make up unique id */
00259                /* Note that the next three strings always exist,
00260                 * so we don't need to test them. */
00261                dnow,
00262                dent,
00263                dpost,
00264                acc_guid_str,
00265                accname ? accname : "",
00266                trans->num ? trans->num : "", 
00267                trans->description ? trans->description : "",
00268                trans_notes ? trans_notes : "",
00269                split->memo ? split->memo : "",
00270                split->action ? split->action : "",
00271                split->reconciled,
00272                gnc_numeric_num(amt), 
00273                gnc_numeric_denom(amt),
00274                gnc_numeric_num(val), 
00275                gnc_numeric_denom(val),
00276                /* The next string always exists. No need to test it. */
00277                drecn);
00278    }
00279 
00280    fprintf (trans_log, "===== END\n");
00281 
00282    /* get data out to the disk */
00283    fflush (trans_log);
00284 }


Generated on Tue Oct 14 05:05:17 2008 for GnuCash by  doxygen 1.5.2