pilot-qof  0.2.3
Data Structures | Files | Defines | Typedefs | Enumerations | Functions | Variables
Using QOF as a framework around pilot-link
Query Object Framework

Data Structures

struct  PilotPack_s
 Packing function wrapper. More...
struct  PQExp_s
struct  PQContext_s
 The pilot-qof context struct, extends qof_main_context. More...

Files

file  pilot-qof.c
 

Executable interface to the QOF external framework.


file  pilot-qof.h
 

Executable interface to the QOF external framework.


Defines

#define _GNU_SOURCE
#define ARGUMENT_BAD_OPTION   17227
#define EXCLUDE_REPEATER_SQL
#define ENUM_LIST_Q(_)
#define PQ_MOD_PILOT   "pilotqof-objects"
#define PQ_MOD_PILOT   "pilotqof-objects"
#define PILOT_QOF_LOG   "pilot-qof.trace"
#define PQ_MOD_CLI   "pilotqof-cli"
#define PQ_DLP_CARD   0
#define PQ_DLP_OFFSET   0
#define PQ_DLP_RECORD   0
#define PQ_DLP_NEW_REC   0
#define PQ_DLP_SET_ID   0
#define PQ_DLP_APPREAD   -1
#define PQ_DLP_APPREAD   -1
#define PQ_DLP_REC_ATTR   0
#define PQ_DEF_BUFSZ   0xffff
#define PILOT_LINK_SUPPORT   "0.12"
#define PQ_PREF_USE_BACKUP   1
#define PQ_PREF_USE_SIZE   0
#define PQ_PREF_VERSION   0

Typedefs

typedef struct PQExp_s PQExpensePref
typedef struct PQContext_s PQContext
 The pilot-qof context struct, extends qof_main_context.

Enumerations

enum  qof_op_type {
  qof_op_noop = 0, qof_op_offline, qof_op_list, qof_op_hotsync,
  qof_op_empty, qof_op_category, qof_op_database, qof_op_time,
  qof_op_exclude, qof_op_sql, qof_op_sql_file, qof_op_write,
  qof_op_upload, qof_op_explain, qof_op_vers, qof_op_compress,
  qof_op_debug, qof_op_inv_city, qof_op_inv_vendor, qof_op_use_locale
}
enum  plu_findcategory_flags_t {
  PLU_CAT_NOFLAGS = 0, PLU_CAT_CASE_INSENSITIVE = 0x0001, PLU_CAT_DEFAULT_UNFILED = 0x0002, PLU_CAT_MATCH_NUMBERS = 0x0004,
  PLU_CAT_WARN_UNKNOWN = 0x0008
}

Functions

static PQContextpilot_qof_create (void)
PQContextpilot_qof_init (void)
 Register all QOF objects.
static gint plu_connect (gchar *plu_port, gint plu_quiet)
static gint pq_findcategory (PQContext *context, const gchar *name, gint flags)
static void pilot_entity_free (QofEntity *ent, gpointer user_data)
static void pilot_object_free (QofObject *obj, gpointer user_data)
static void pilot_qof_free (PQContext *data)
static void write_ent_cb (QofEntity *ent, gpointer user_data)
static void pilot_database_open (QofObject *obj, gpointer user_data)
static void pilot_error (PQContext *context, const gchar *message)
static void find_invoice_contact (QofEntity *ent, gpointer data)
static void check_invoice_handler (PQContext *context)
void qof_cmd_hotsync (PQContext *context)
 Activate/HotSync and query the Palm, ignoring the offline storage.
static void pq_invoice_xmlfile (PQContext *context)
int main (int argc, const char *argv[])
void pilot_qof_close (void)
 Shutdown the QOF framework.

Variables

static QofLogModule log_module = "pilotqof-cli"
static GList * pilot_modules = NULL
static const gchar * env_pilotport = "PILOTPORT"

Packing, unpacking and freeing wrapped objects.

QOF is wrapped around existing pilot-link structs. These objects have their own methods for writing to and reading from the Palm databases. Objects are packed before being written to the Palm, and unpacked to create new objects when the database is read.

Packing and unpacking are only used when connecting to the Palm.

The free_ent_func routines are used whenever any QofBook created from this framework is closed.

typedef gint(* QofPack )(QofEntity *ent, gpointer user_data)
 Packing function pointer type.
typedef struct PilotPack_s PQPack
 Packing function wrapper.
void pilot_qof_pack (QofEntity *ent, gpointer user_data)
 Pack this object.
void pilot_qof_unpack (QofEntity *ent, gpointer user_data)
 Unpack this object.
void pilot_app_unpack (QofIdTypeConst e_type, gpointer user_data)
 Unpack the database information.
void pilot_entity_finaliser (QofBook *book, gpointer key, gpointer data)
 Free the wrapped object.
gboolean pilot_qof_pack_register (const PQPack *p)
 Shamelessly copied from QOF.
const PQPackpilot_qof_pack_lookup (QofIdTypeConst object_type)
 provide for looking up an object

Detailed Description

pilot-qof provides the executable interface to the QOF external framework. It supports writing the QSF XML offline storage and SQL-type queries.

The types of SQL queries that are allowed at this point are a little limited. In general, only the following types of queries are supported:
SELECT * FROM SomeObj WHERE (param_a < 10.0) AND (param_b = "asdf") SORT BY param_c DESC;
INSERT INTO SomeObj (param_a, param_b, param_c) VALUES ("value_a", true, "0/1");

Joins are not supported directly.
SELECT * FROM ObjA,ObjB WHERE (ObjA.param_id = ObjB.param_other_id);
The problem with the above is that the search requires a nested search loop, aka a 'join', which is not currently supported in the underlying QofQuery code.

However, by repeating queries and adding the entities to a new session using ::qof_entity_copy_list, a series of queries can be added to a single book. e.g. You can insert multiple entities and save out as a QSF XML file or use multiple SELECT queries to build a precise list - this can be used to replicate most of the functionality of a SQL join.

SELECT * from ObjA where param_id = value; SELECT * from ObjB where param_other_id = value;

Equivalent to:
SELECT * from ObjA,ObjB where param_id = param_other_id and param_id = value;

When combined with a foreach callback on the value of param_id for each entity in the QofBook, you can produce the effect of a join from running the two SELECT queries for each value of param_id held in 'value'.

See ::QofEntityForeachCB and ::qof_object_foreach.

SELECT a,b,c FROM ...

Used to convert QOF objects between applications by using the returned parameter values to create a second object. One application using QOF could register objects from two applications and convert data from one to the other by using
SELECT a,b,c FROM ObjA; SELECT d,f,k FROM ObjB; qof_object_new_instance(); ObjC_set_a(value_c); ObjC_set_b(value_k) etc.

What's needed is for the SELECT to return a complete object that only contains the parameters selected.

Unsupported: UPDATE, DELETE.

It will not be possible to support CREATE, AMEND or DROP for understandable reasons.

Todo:
Link with libpisync and do a fast-sync with the offline storage.

Define Documentation

#define ENUM_LIST_Q (   _)
Value:
_(qof_op_noop, = 0)   \
    _(qof_op_offline, )   \
    _(qof_op_list,)       \
    _(qof_op_hotsync,)    \
    _(qof_op_empty,)      \
    _(qof_op_category,)   \
    _(qof_op_database,)   \
    _(qof_op_time,)       \
    _(qof_op_exclude,)    \
    _(qof_op_sql,)        \
    _(qof_op_sql_file,)   \
    _(qof_op_write, )     \
    _(qof_op_upload, )    \
    _(qof_op_explain,)    \
    _(qof_op_vers,)       \
    _(qof_op_compress,)   \
    _(qof_op_debug,)      \
    _(qof_op_inv_city,)   \
    _(qof_op_inv_vendor,) \
    _(qof_op_use_locale,)

Definition at line 75 of file pilot-qof.c.

#define EXCLUDE_REPEATER_SQL
Value:
"SELECT * from pilot_datebook " \
"where DATEBOOK_REPEATER == TRUE;"

Definition at line 72 of file pilot-qof.c.

#define PILOT_LINK_SUPPORT   "0.12"

This is the 0.1.x series of pilot-qof

Definition at line 143 of file pilot-qof.h.

Referenced by main().

#define PILOT_QOF_LOG   "pilot-qof.trace"

the debug log file.

Definition at line 102 of file pilot-qof.h.

Referenced by main().

#define PQ_DEF_BUFSZ   0xffff

Default pi_buffer size

Definition at line 140 of file pilot-qof.h.

Referenced by pilot_qof_pack().

#define PQ_DLP_APPREAD   -1

The number of bytes to read from the AppBlock.

Specify negative one for all available bytes.

Definition at line 131 of file pilot-qof.h.

#define PQ_DLP_APPREAD   -1

The number of bytes to read from the AppBlock.

Specify negative one for all available bytes.

Definition at line 131 of file pilot-qof.h.

#define PQ_DLP_CARD   0

The DLP Card Number reference

Definition at line 108 of file pilot-qof.h.

#define PQ_DLP_NEW_REC   0

The DLP Record ID - 0 for a new record

Definition at line 117 of file pilot-qof.h.

Referenced by pilot_qof_pack().

#define PQ_DLP_OFFSET   0

The DLP Offset

Definition at line 111 of file pilot-qof.h.

#define PQ_DLP_REC_ATTR   0

The DLP Record attributes - not currently used.

See dlpRecAttributes in pilot-link, includes/pi-dlp.h

Definition at line 137 of file pilot-qof.h.

Referenced by pilot_qof_pack().

#define PQ_DLP_RECORD   0

The DLP Record Index

Definition at line 114 of file pilot-qof.h.

#define PQ_DLP_SET_ID   0

The DLP Record ID value, after writing - currently ignored.

Definition at line 120 of file pilot-qof.h.

Referenced by pilot_qof_pack().

#define PQ_MOD_CLI   "pilotqof-cli"

debug module identifier

Definition at line 105 of file pilot-qof.h.

Referenced by main().

#define PQ_MOD_PILOT   "pilotqof-objects"

default log module for objects

Definition at line 99 of file pilot-qof.h.

Referenced by main().

#define PQ_MOD_PILOT   "pilotqof-objects"

default log module for objects

Definition at line 99 of file pilot-qof.h.

#define PQ_PREF_USE_BACKUP   1

If set, read from backup preferences

(see Palm OS documentation). This flag is ignored on Palm OS 1.x.

Definition at line 149 of file pilot-qof.h.

#define PQ_PREF_USE_SIZE   0

Preference read datasize.

If not NULL, on return contains the size of the preference data block.

Definition at line 155 of file pilot-qof.h.

#define PQ_PREF_VERSION   0

Preferences version if not NULL.

Definition at line 158 of file pilot-qof.h.


Typedef Documentation

typedef struct PilotPack_s PQPack

Packing function wrapper.

The pack routines are linked to the QOF object using the qof_pack function pointer and the pilot_pack wrapper. The wrapper also includes the name of the database as held on the Palm.

The e_type must be the same as the e_type of the QofObject, as defined in the object_def definition.

typedef gint(* QofPack)(QofEntity *ent, gpointer user_data)

Packing function pointer type.

The pack routines are built into the QOF object using the qof_pack function pointer and the pilot_pack wrapper. The same type is used for the free object memory function, free_pack_func.

Definition at line 239 of file pilot-qof.h.


Function Documentation

int main ( int  argc,
const char *  argv[] 
)
Todo:
Output debug messages earlier.

Definition at line 825 of file pilot-qof.c.

References QofMain_s::database, ERR_INDENT, QofMain_s::error, QofMain_s::filename, QofMain_s::gz_level, QofMain_s::input_file, QofMain_s::input_session, PQContext_s::invoice_city, PQContext_s::invoice_vendor, PILOT_LINK_SUPPORT, pilot_qof_init(), PILOT_QOF_LOG, PQContext_s::port, PQ_MOD_CLI, PQ_MOD_PILOT, PQContext_s::qof, QOF_CLI_OPTIONS, qof_cmd_explain(), qof_cmd_hotsync(), qof_cmd_list(), qof_cmd_xmlfile(), QOF_MAIN_CLI, qof_main_wrap_line(), qof_mod_category(), qof_mod_convert_deprecated(), qof_mod_database(), qof_mod_encoding(), qof_mod_exclude(), qof_mod_sql(), qof_mod_sql_file(), qof_mod_time(), qof_mod_write(), QOF_OP_INIT, QOF_OP_VARS, and PQContext_s::quiet.

{
    const gchar *help_header_text, *input_file, *plu_port;
    gint plu_quiet, optc;
    PQContext *pilot_qof_context;
    gboolean debug_on;
    poptContext pc;
    gint64 gz_level;
    qof_op_type palm_command;

    QOF_OP_VARS struct poptOption options[] = {
        {"port", 'p', POPT_ARG_STRING, &plu_port, 0,
            _("Use the device <port> to communicate with Palm"),
                "<port>"},
        { "quiet",   'q', POPT_ARG_NONE,  &plu_quiet,  0 ,
         _("Suppress HotSync connection messages"), NULL},
        {"input-file", 'i', POPT_ARG_STRING, &filename, qof_op_offline,
         _("Query the data in <filename>"), _("filename")},
        QOF_CLI_OPTIONS 
        {"hot-query", 'a', POPT_ARG_NONE,
                NULL, qof_op_hotsync,
            _("Activate/HotSync and query the Palm."), NULL},
        {"upload", 'u', POPT_ARG_STRING, &input_file, qof_op_upload,
            _("Upload data from <filename> to the Palm. Requires -a"),
                "filename"},
        {"invoice-vendor", 0, POPT_ARG_NONE, NULL, qof_op_inv_vendor,
            _
            ("Shorthand to relate an event or expense to a contact, by vendor. "
                    "Requires -t."), NULL},
        {"invoice-city", 0, POPT_ARG_NONE, NULL, qof_op_inv_city,
            _
            ("Shorthand to relate an event or expense to a contact, by city. "
                    "Requires -t."), NULL},
        {"use-locale", 0, POPT_ARG_NONE, NULL, qof_op_use_locale,
                _
            ("Write XML using the current locale encoding instead of UTF-8."),
            NULL},
        POPT_TABLEEND
    };

    palm_command = qof_op_noop;
    debug_on = FALSE;
    QOF_OP_INIT;
    input_file = NULL;
    plu_quiet = 0;
    plu_port = NULL;

#ifdef ENABLE_NLS
    setlocale (LC_ALL, "");
    bindtextdomain (GETTEXT_PACKAGE, LOCALE_DIR);
    bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
    textdomain (GETTEXT_PACKAGE);
#endif

    help_header_text = _("\n"
        "   Query Palm databases as objects and save to XML.\n"

        "   pilot-qof provides a query interface to data on a Palm device,\n"
        "   using pilot-link and QOF - the Query Object Framework.\n\n"
        "   pilot-qof supports reading addressbook, datebook, expenses and\n"
        "   ToDo data from a Palm device to XML files. pilot-qof runs SQL-type\n"
        "   queries on the live data or a QSF XML file and results can be imported\n"
        "   into other QOF applications or converted to other text based formats,\n"
        "   including non-XML formats like vcard.\n"
        "   See http://pilot-qof.sourceforge.net/\n\n"
        "   Commands are -x -a -l --explain -s or -f.\n"
        "   Options are -c -t -w, -d or -e.\n"
        "   option -u requires -a\n\n");

    pc = poptGetContext (PACKAGE, argc, argv, options, 0);

    poptSetOtherOptionHelp (pc, help_header_text);

    if (argc < 2)
    {
        poptPrintUsage (pc, stderr, 0);
        return EXIT_FAILURE;
    }
    pilot_qof_context = pilot_qof_init ();
    if (!pilot_qof_context)
    {
        qof_main_wrap_line (stderr, ERR_INDENT,
            _("%s: Failed to initialise "
                "the query object framework."), PACKAGE);
        return EXIT_FAILURE;
    }
    /* convert deprecated date fields into the newly supported
    time values. */
    qof_mod_convert_deprecated (1, &pilot_qof_context->qof);
    while ((optc = poptGetNextOpt (pc)) >= 0)
    {
        switch (optc)
        {
            /* commands - mutually exclusive */
        case qof_op_offline:
        case qof_op_list:
        case qof_op_explain:
        case qof_op_hotsync:
            {
                palm_command = optc;
                break;
            }
        case qof_op_sql:
            {
                qof_mod_sql (sql_query, &pilot_qof_context->qof);
                if (!filename)
                {
                    filename = g_strdup (QOF_STDOUT);
                }
                palm_command = qof_op_empty;
                break;
            }
        case qof_op_sql_file:
            {
                qof_mod_sql_file (sql_file, &pilot_qof_context->qof);
                palm_command = qof_op_empty;
                break;
            }
        case qof_op_vers:
            {
                fprintf (stdout, _("\n This is %s v%s\n"), PACKAGE,
                    VERSION);
                fprintf (stdout,
                    _
                    (" Query interface for Palm databases as objects.\n"));
                fprintf (stdout,
                    "\n Copyright (c) 2005-2006 "
                    "Neil Williams <linux@codehelp.co.uk>\n");
                fprintf (stdout,
                    _(" For %s support, join the QOF-devel "
                        "mailing list at\n"), PACKAGE);
                fprintf (stdout,
                    " http://lists.sourceforge.net/mailman/listinfo/qof-devel\n\n");
/* Translators: Add or subtract dots to keep the translated lines aligned vertically */
                fprintf (stdout, _(" Build target............: %s\n"),
                    HOST_OS);
/* Translators: Add or subtract dots to keep the translated lines aligned vertically */
                fprintf (stdout, _(" Build date..............: %s %s\n"),
                    __DATE__, __TIME__);
/* Translators: Add or subtract dots to keep the translated lines aligned vertically */
                fprintf (stdout, _(" Built for pilot-link ...: %s\n"),
                    PILOT_LINK_SUPPORT);
/* Translators: Add or subtract dots to keep the translated lines aligned vertically */
                fprintf (stdout, _(" --debug logs to.........: %s/%s\n\n"),
                    g_get_tmp_dir (), PILOT_QOF_LOG);
                fprintf (stdout,
                    _
                    (" Please use --help for more detailed options.\n\n"));
                return EXIT_SUCCESS;
            }
            /* optional modifiers - store to act on later. */
        case qof_op_category:
            {
                qof_mod_category (category, &pilot_qof_context->qof);
                break;
            }
        case qof_op_database:
            {
                qof_mod_database (database, &pilot_qof_context->qof);
                break;
            }
        case qof_op_time:
            {
                qof_mod_time (date_time, &pilot_qof_context->qof);
                break;
            }
        case qof_op_exclude:
            {
                qof_mod_exclude (exclude, &pilot_qof_context->qof);
                break;
            }
        case qof_op_write:
            {
                qof_mod_write (write_file, &pilot_qof_context->qof);
                break;
            }
        case qof_op_upload:
            {
                if (palm_command != qof_op_hotsync)
                {
                    fprintf (stderr,
                        _("%s: Error: Please specify -a if you use -u\n"),
                        PACKAGE);
                    poptPrintUsage (pc, stderr, 0);
                    return EXIT_FAILURE;
                }
                pilot_qof_context->qof.input_file = g_strdup (input_file);
                break;
            }
        case qof_op_debug:
            {
                gchar *log;

                log =
                    g_strconcat (g_get_tmp_dir (), "/", PILOT_QOF_LOG,
                    NULL);
                qof_log_init_filename (log);
                g_free (log);
                qof_log_set_default (QOF_LOG_DETAIL);
                qof_log_set_level (PQ_MOD_CLI, QOF_LOG_DETAIL);
                qof_log_set_level (PQ_MOD_PILOT, QOF_LOG_DETAIL);
                qof_log_set_level (QOF_MAIN_CLI, QOF_LOG_DETAIL);
                qof_log_set_level (QOF_MOD_QSF, QOF_LOG_DETAIL);
                qof_log_set_level ("qof-sqlite-module", QOF_LOG_DETAIL);
                debug_on = TRUE;
                break;
            }
        case qof_op_compress:
            {
                pilot_qof_context->qof.gz_level = gz_level;
                break;
            }
        case qof_op_inv_vendor:
            {
                if (!pilot_qof_context->invoice_city)
                    pilot_qof_context->invoice_vendor = TRUE;
                break;
            }
        case qof_op_inv_city:
            {
                pilot_qof_context->invoice_city = TRUE;
                pilot_qof_context->invoice_vendor = FALSE;
                break;
            }
        case qof_op_use_locale:
            {
                const gchar *locale_encoding;
                gboolean test;
                locale_encoding = NULL;
                test = g_get_charset (&locale_encoding);
                if (!test)
                    qof_mod_encoding (locale_encoding,
                        &pilot_qof_context->qof);
                break;
            }
        default:
            {
                fprintf (stderr, _("%s: ERROR: got option %d, arg %s\n"),
                    PACKAGE, optc, poptGetOptArg (pc));
                return EXIT_FAILURE;
            }
        }
    }
    if (qof_op_noop == palm_command)
    {
        qof_main_wrap_line (stderr, ERR_INDENT,
            _("%s: ERROR: specify a command "
                "-x, -a, -l, -s or -f, or --explain.\n"), PACKAGE);
        poptPrintUsage (pc, stderr, 0);
        return EXIT_FAILURE;
    }
    if (qof_op_noop == palm_command)
    {
        fprintf (stderr, _("%s: ERROR: specify a command "
        "-x, -a, -l, -s or -f, or --explain.\n"), PACKAGE);
        poptPrintUsage(pc, stderr, 0);
        return EXIT_FAILURE;
    }
    if (optc < -1)
    {
        fprintf (stderr, "%s: %s %s\n\n", PACKAGE,
            poptBadOption (pc, POPT_BADOPTION_NOALIAS),
            poptStrerror (optc));
        poptPrintUsage (pc, stderr, 0);
        return EXIT_FAILURE;
    }
    /* If we get this far, we should have sensible options: start the work. */
    pilot_qof_context->qof.input_session = qof_session_new ();
    switch (palm_command)
    {
    case qof_op_empty:
    {
        pilot_qof_context->qof.filename = g_strdup (filename);
        if ((pilot_qof_context->invoice_city)
            || (pilot_qof_context->invoice_vendor))
        {
            check_invoice_handler (pilot_qof_context);
            if (pilot_qof_context->qof.error)
                return EXIT_FAILURE;
            pq_invoice_xmlfile (pilot_qof_context);
        }
        else
            qof_cmd_xmlfile (&pilot_qof_context->qof);
        break;
    }
    case qof_op_offline:
        {
            pilot_qof_context->qof.filename = g_strdup (filename);
            if ((pilot_qof_context->invoice_city)
                || (pilot_qof_context->invoice_vendor))
            {
                check_invoice_handler (pilot_qof_context);
                if (pilot_qof_context->qof.error)
                    return EXIT_FAILURE;
                pq_invoice_xmlfile (pilot_qof_context);
            }
            else
                qof_cmd_xmlfile (&pilot_qof_context->qof);
            break;
        }
    case qof_op_list:
        {
            DEBUG (" list mode");
            qof_cmd_list ();
            break;
        }
    case qof_op_explain:
        {
            if (!pilot_qof_context->qof.database)
            {
                qof_main_wrap_line (stderr, ERR_INDENT,
                    _("%s: Error: please specify which database "
                        "you would like explained.\n\n"), PACKAGE);
                break;
            }
            DEBUG (" explain mode");
            qof_cmd_explain (&pilot_qof_context->qof);
            break;
        }
    case qof_op_hotsync:
        {
            DEBUG (" hotsync mode");
            pilot_qof_context->port = g_strdup (plu_port);
            pilot_qof_context->quiet = plu_quiet;
            qof_cmd_hotsync (pilot_qof_context);
            break;
        }
    case qof_op_noop:
    case qof_op_category:
    case qof_op_database:
    case qof_op_time:
    case qof_op_exclude:
    case qof_op_sql:
    case qof_op_sql_file:
    case qof_op_write:
    case qof_op_upload:
    case qof_op_vers:
    case qof_op_compress:
    case qof_op_debug:
    case qof_op_inv_city:
    case qof_op_inv_vendor:
    case qof_op_use_locale:
    default:
            break;
    }
    poptFreeContext (pc);
    pilot_qof_free (pilot_qof_context);
    if (debug_on)
        qof_log_shutdown ();
    qof_close ();
void pilot_app_unpack ( QofIdTypeConst  e_type,
gpointer  user_data 
)

Unpack the database information.

The Palm uses a separate structure for information about the current database, including the list of available categories.

This is a per-database structure, not per record. The records only contain an integer - the value of the category in the index of the CategoryAppInfo. QOF converts this into a string value for the category name for portability.

It does not call any qof_pack routines as there is no QofEntity at this stage.

Parameters:
e_type- determines the type of application information to unpack from the pilot_pack wrapper.
user_data- gpointer to the ::pqd context.

Definition at line 342 of file pilot-qof.c.

References PilotPack_s::app_info_unpack, QofMain_s::error, pilot_qof_pack_lookup(), and PQContext_s::qof.

{
    PQContext *context;
    QofPack app_unpack;
    const PQPack *p;

    context = (PQContext *) user_data;
    g_return_if_fail (context != NULL);
    p = pilot_qof_pack_lookup (e_type);
    if (!p)
        return;
    app_unpack = p->app_info_unpack;
    if (app_unpack == NULL)
    {
        context->qof.error = TRUE;
        PERR (" no app_info_unpack routine for %s", e_type);
        return;
    }
    /* no entity available for the appInfo, pass NULL and work only in the context. */
void pilot_entity_finaliser ( QofBook *  book,
gpointer  key,
gpointer  data 
)

Free the wrapped object.

Set the pointer to the free function for the object within this entity. The function itself is called automatically by QOF when the QofBook is being closed.

Definition at line 387 of file pilot-qof.c.

{
PQContext * pilot_qof_init ( void  )

Register all QOF objects.

If new objects are added, call the register func() here. Ensure you have the pack routines for your object.

Follow the template of other objects to create your own callbacks.

pilot_qof_init must be called by any program wanting to use the QOF framework with pilot-link objects.

Returns:
NULL on error, otherwise a usable pilot_qof_data* context.
Bug:
need to get Expenses from gpe-expenses and then add the pisock layer.

Definition at line 112 of file pilot-qof.c.

References AddressRegister(), DateBookRegister(), and PQExpensesRegister().

Referenced by main().

{
    qof_init ();
    g_return_val_if_fail (AddressRegister (), NULL);
#ifdef HAVE_QOFEXPENSES
    g_return_val_if_fail (ExpensesRegister (), NULL);
#endif
    g_return_val_if_fail (PQExpensesRegister (), NULL);
    g_return_val_if_fail (DateBookRegister (), NULL);
    g_return_val_if_fail (ToDoRegister (), NULL);
    g_return_val_if_fail (packing_registration(), NULL);
void pilot_qof_pack ( QofEntity *  ent,
gpointer  user_data 
)

Pack this object.

Retrieve the pointer to the pack function for the object within this entity. Entity objects are packed prior to being written to a Palm database. Although upload is available for new records, merge and sync are not yet implemented in the pilot-qof Although upload is available for new records, merge and sync are not yet implemented in the pilot-qof application. Functionality to merge two QofBooks to handle the merge and sync does exist in QOF.

Definition at line 269 of file pilot-qof.c.

References CATEGORY_NAME, PQContext_s::db, PQContext_s::ent_category, QofMain_s::error, PilotPack_s::pack_func, PQContext_s::pi_buf, pilot_qof_pack_lookup(), PQ_DEF_BUFSZ, PQ_DLP_NEW_REC, PQ_DLP_REC_ATTR, PQ_DLP_SET_ID, PQContext_s::qof, and PQContext_s::sd.

{
    const gchar *category_name;
    const QofParam *param;
    gint size, result;
    QofPack pack_func;
    PQContext *context;
    const PQPack *p; 

    context = (PQContext *) user_data;
    size = result = 0;
    g_return_if_fail (context != NULL);
    p = pilot_qof_pack_lookup (ent->e_type);
    if (!p)
        return;
    context->pi_buf = pi_buffer_new (PQ_DEF_BUFSZ);
    pack_func = p->pack_func;
    if (pack_func == NULL)
    {
        context->qof.error = TRUE;
        return;
    }
    size = pack_func (ent, context);
    if (size == -1)
        return;
    param = qof_class_get_parameter (ent->e_type, CATEGORY_NAME);
    category_name = (const gchar *) param->param_getfcn (ent, param);
    context->ent_category = pq_findcategory(context, 
        category_name, PLU_CAT_CASE_INSENSITIVE | PLU_CAT_DEFAULT_UNFILED);
/*  context->ent_category = plu_findcategory (context->pi_cat,
        category_name, PLU_CAT_CASE_INSENSITIVE | PLU_CAT_DEFAULT_UNFILED);*/
    if (context->ent_category == 0)
        PWARN (" Category: '%s' not found or not set, using 'Unfiled'",
            category_name);
    result = dlp_WriteRecord (context->sd, context->db,
        PQ_DLP_REC_ATTR, PQ_DLP_NEW_REC, context->ent_category,
        context->pi_buf->data, size, PQ_DLP_SET_ID);
    if (result < 0)
    {
        PERR (" record could not be written: error %d", result);
        return;
const PQPack * pilot_qof_pack_lookup ( QofIdTypeConst  object_type)

provide for looking up an object

Returns the pilot_pack that matches this object type. Uses the same object type as the QofObject->e_type.

Definition at line 403 of file pilot-qof.c.

References PilotPack_s::e_type, and pilot_modules.

Referenced by pilot_app_unpack(), pilot_qof_pack(), and pilot_qof_unpack().

{
    GList *piter;
    PQPack *p;

    if (!object_type)
        return NULL;
    for (piter = pilot_modules; piter; piter = piter->next)
    {
        p = piter->data;
        if (0 == safe_strcmp (p->e_type, object_type))
            return p;
    }
gboolean pilot_qof_pack_register ( const PQPack p)

Shamelessly copied from QOF.

Pilot-link requires a few functions to pack and unpack the database records prior to / post HotSync. These are specific to each object and to allow new objects to be added easily, need to be referenced generically.

pilot-qof implements a mini-QofObject alongside QOF that just contains this pilot-link data.

Definition at line 393 of file pilot-qof.c.

References pilot_modules.

{
    if (g_list_index (pilot_modules, (gpointer) p) == -1)
        pilot_modules = g_list_prepend (pilot_modules, (gpointer) p);
    else
        return FALSE;
void pilot_qof_unpack ( QofEntity *  ent,
gpointer  user_data 
)

Unpack this object.

Retrieve the pointer to the unpack function for this entity and the object it contains. Entities are unpacked after being read from the Palm during a HotSync. The unpack routine populates the object with the Palm data in a usable form. The QOF framework then accesses this data through QOF wrappers.

Definition at line 314 of file pilot-qof.c.

References QofMain_s::error, pilot_qof_pack_lookup(), PQContext_s::qof, and PilotPack_s::unpack_func.

{
    QofPack unpack_func;
    const PQPack *p;
    PQContext *context;
    gint result;

    context = (PQContext *) user_data;
    g_return_if_fail (context && ent);
    p = pilot_qof_pack_lookup (ent->e_type);
    g_return_if_fail (p);
    unpack_func = p->unpack_func;
    if (unpack_func == NULL)
    {
        context->qof.error = TRUE;
        PERR ("No unpack routine was defined for the %s object!",
            ent->e_type);
        return;
    }
    result = unpack_func (ent, context);
    if (result < 0)
    {
        qof_entity_release (ent);
        g_free (ent);
void qof_cmd_hotsync ( PQContext context)

Activate/HotSync and query the Palm, ignoring the offline storage.

Connects the the Palm and queries the live database. If -d or -e are not used, query all supported databases in one HotSync operation.

Definition at line 693 of file pilot-qof.c.

References QofMain_s::database, ERR_INDENT, QofMain_s::error, QofMain_s::exclude, QofMain_s::export_session, QofMain_s::gz_level, QofMain_s::input_file, QofMain_s::input_session, PQContext_s::invoice_city, PQContext_s::invoice_vendor, PQContext_s::port, PQContext_s::qof, qof_main_moderate_query(), qof_main_show_error(), qof_main_wrap_line(), qof_mod_compression(), QofMain_s::query, PQContext_s::quiet, PQContext_s::sd, and QofMain_s::write_file.

Referenced by main().

{
    struct PilotUser QUser;
    QofBook *book;
    gchar *log_msg;

    if (0 == safe_strcmp (context->qof.exclude, context->qof.database)
        && (context->qof.exclude != NULL))
    {
        /* Translators: The first string is the package name.
           The second and third are database names. */
        qof_main_wrap_line (stderr, ERR_INDENT,
            _("%s: Error: Cannot exclude "
                "database \"%s\" with option -e because option -d is set to the "
                "same database: \"%s\""), PACKAGE, context->qof.exclude,
            context->qof.database);
        qof_session_end (context->qof.input_session);
        return;
    }
    if ((context->invoice_city) || (context->invoice_vendor))
        check_invoice_handler (context);
    if (context->qof.error)
        return;
    if (context->qof.input_file)
    {
        PINFO (" Trying to upload %s", context->qof.input_file);
        qof_session_begin (context->qof.input_session,
            context->qof.input_file, TRUE, FALSE);
        qof_session_load (context->qof.input_session, NULL);
    }
    else
        qof_session_begin (context->qof.input_session, QOF_STDOUT, TRUE,
            FALSE);
    context->qof.export_session = qof_session_new ();

    context->sd = plu_connect (context->port, context->quiet);

    if (context->sd < 0)
    {
        pilot_error (context, _("Unable to connect to the Palm"));
        return;
    }
    if (dlp_ReadUserInfo (context->sd, &QUser) < 0)
    {
        pilot_error (context, _("Unable to read Palm user info"));
        return;
    }
    context->qof.error = FALSE;
    qof_object_foreach_type (pilot_database_open, context);
    QUser.lastSyncPC = 0x00010000;
    QUser.lastSyncDate = QUser.successfulSyncDate = time (0);
    if (dlp_WriteUserInfo (context->sd, &QUser) < 0)
    {
        pilot_error (context, _("Unable to write user info"));
        return;
    }
    /* Translators: each string is the package name. */
    log_msg = g_strdup_printf (_("%s hotsync\n\n"
            "Thank you for using %s.\n"), PACKAGE, PACKAGE);
    dlp_AddSyncLogEntry (context->sd, log_msg);
    g_free (log_msg);
    dlp_EndOfSync (context->sd, 0);
    pi_close (context->sd);
    /* Now run the query, copy the objects, destroy the input session */
    /*and write out export_session */
    if (context->qof.write_file)
    {
        qof_session_begin (context->qof.export_session,
            context->qof.write_file, TRUE, TRUE);
        qof_mod_compression (context->qof.gz_level, &context->qof);
    }
    else
        qof_session_begin (context->qof.export_session, QOF_STDOUT, TRUE,
            FALSE);
    /* Note if no query is given, ignore repeater clones?
       Nice idea, but in practice, difficult. It also makes recursive
       queries of the XML harder as the XML needs to understand datebook
       repeats. Instead, we simply ignore all repeater clones when it comes
       to write data to the Palm by a simple check in datebook_pack.
     */
    qof_main_moderate_query (&context->qof);
    /* if invoice_hook, create a second query and lookup in contacts */
    if ((context->invoice_city) || (context->invoice_vendor))
    {
        book = qof_session_get_book (context->qof.export_session);
        context->qof.query = qof_query_create_for (PILOT_LINK_QOF_ADDRESS);
        qof_object_foreach (PILOT_LINK_QOF_DATEBOOK, book,
            find_invoice_contact, context);
        qof_object_foreach (PILOT_LINK_QOF_EXPENSES, book,
            find_invoice_contact, context);
    }
    qof_session_save (context->qof.export_session, NULL);
    qof_main_show_error (context->qof.export_session);
    qof_session_end (context->qof.input_session);

Variable Documentation

QofLogModule log_module = "pilotqof-cli" [static]

used to print debug logs.

Definition at line 64 of file pilot-qof.c.

GList* pilot_modules = NULL [static]

pack routines for communication with pilot

Definition at line 66 of file pilot-qof.c.

Referenced by pilot_qof_pack_lookup(), and pilot_qof_pack_register().