GnuCash 2.3.0
Files | Functions
Transaction Logging
GnuCash Engine: Core, Non-GUI Accounting Functions

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)

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.


Function Documentation

gboolean xaccFileIsCurrentLog ( const gchar *  name)

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

Definition at line 137 of file TransLog.c.

{
    gchar *base;
    gint result;

    if (!name || !trans_log_name)
        return FALSE;

    base = g_path_get_basename(name);
    result = (strcmp(base, trans_log_name) == 0);
    g_free(base);
    return result;
}
void xaccLogDisable ( void  )

document me

Definition at line 91 of file TransLog.c.

{
    gen_logs = 0;
}
void xaccLogEnable ( void  )

document me

Definition at line 95 of file TransLog.c.

{
    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 115 of file TransLog.c.

{
    if (!basepath) return;

    g_free (log_base_name);
    log_base_name = g_strdup (basepath);

    if (trans_log)
    {
        xaccCloseLog();
        xaccOpenLog();
    }
}
void xaccTransWriteLog ( Transaction trans,
char  flag 
)
Parameters:
transThe transaction to write out to the log
flagThe 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 215 of file TransLog.c.

{
    GList *node;
    char trans_guid_str[GUID_ENCODING_LENGTH + 1];
    char split_guid_str[GUID_ENCODING_LENGTH + 1];
    const char *trans_notes;
    char dnow[100], dent[100], dpost[100], drecn[100];
    Timespec ts;

    if (!gen_logs) return;
    if (!trans_log) return;

    timespecFromTime_t(&ts, time(NULL));
    gnc_timespec_to_iso8601_buff (ts, dnow);

    timespecFromTime_t(&ts, trans->date_entered.tv_sec);
    gnc_timespec_to_iso8601_buff (ts, dent);

    timespecFromTime_t(&ts, trans->date_posted.tv_sec);
    gnc_timespec_to_iso8601_buff (ts, dpost);

    guid_to_string_buff (xaccTransGetGUID(trans), trans_guid_str);
    trans_notes = xaccTransGetNotes(trans);
    fprintf (trans_log, "===== START\n");

    for (node = trans->splits; node; node = node->next)
    {
        Split *split = node->data;
        const char * accname = "";
        char acc_guid_str[GUID_ENCODING_LENGTH + 1];
        gnc_numeric amt, val;

        if (xaccSplitGetAccount(split))
        {
            accname = xaccAccountGetName (xaccSplitGetAccount(split));
            guid_to_string_buff(xaccAccountGetGUID(xaccSplitGetAccount(split)),
                                acc_guid_str);
        }
        else
        {
            acc_guid_str[0] = '\0';
        }

        timespecFromTime_t(&ts, split->date_reconciled.tv_sec);
        gnc_timespec_to_iso8601_buff (ts, drecn);

        guid_to_string_buff (xaccSplitGetGUID(split), split_guid_str);
        amt = xaccSplitGetAmount (split);
        val = xaccSplitGetValue (split);

        /* use tab-separated fields */
        fprintf (trans_log,
                 "%c\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t"
                 "%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",
                 flag,
                 trans_guid_str, split_guid_str,  /* trans+split make up unique id */
                 /* Note that the next three strings always exist,
                                * so we don't need to test them. */
                 dnow,
                 dent,
                 dpost,
                 acc_guid_str,
                 accname ? accname : "",
                 trans->num ? trans->num : "",
                 trans->description ? trans->description : "",
                 trans_notes ? trans_notes : "",
                 split->memo ? split->memo : "",
                 split->action ? split->action : "",
                 split->reconciled,
                 gnc_numeric_num(amt),
                 gnc_numeric_denom(amt),
                 gnc_numeric_num(val),
                 gnc_numeric_denom(val),
                 /* The next string always exists. No need to test it. */
                 drecn);
    }

    fprintf (trans_log, "===== END\n");

    /* get data out to the disk */
    fflush (trans_log);
}
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines