Using QOF as a framework around pilot-link
[Query Object Framework]


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.


Files

file  pilot-qof.c
 Executable interface to the QOF external framework.
file  pilot-qof.h
 Executable interface to the QOF external 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...

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 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

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 PQExp_s PQExpensePref
typedef 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"


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 70 of file pilot-qof.c.

#define EXCLUDE_REPEATER_SQL

Value:

"SELECT * from pilot_datebook " \
"where DATEBOOK_REPEATER == TRUE;"

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

#define PILOT_LINK_SUPPORT   "0.12"

This is the 0.1.x series of pilot-qof

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

Referenced by main().

#define PILOT_QOF_LOG   "pilot-qof.trace"

the debug log file.

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

Referenced by main().

#define PQ_DEF_BUFSZ   0xffff

Default pi_buffer size

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

Referenced by addr_appinfo_unpack(), datebook_appinfo_unpack(), exp_appinfo_unpack(), exp_pack(), exp_pref_unpack(), pilot_database_open(), pilot_qof_pack(), todo_appinfo_unpack(), and write_ent_cb().

#define PQ_DLP_APPREAD   -1

The number of bytes to read from the AppBlock.

Specify negative one for all available bytes.

Definition at line 132 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 132 of file pilot-qof.h.

Referenced by pilot_database_open().

#define PQ_DLP_CARD   0

The DLP Card Number reference

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

Referenced by pilot_database_open().

#define PQ_DLP_NEW_REC   0

The DLP Record ID - 0 for a new record

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

Referenced by pilot_qof_pack().

#define PQ_DLP_OFFSET   0

The DLP Offset

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

Referenced by pilot_database_open().

#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 138 of file pilot-qof.h.

Referenced by pilot_qof_pack().

#define PQ_DLP_RECORD   0

The DLP Record Index

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

Referenced by pilot_database_open().

#define PQ_DLP_SET_ID   0

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

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

Referenced by pilot_qof_pack().

#define PQ_MOD_CLI   "pilotqof-cli"

debug module identifier

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

Referenced by main().

#define PQ_MOD_PILOT   "pilotqof-objects"

default log module for objects

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

#define PQ_MOD_PILOT   "pilotqof-objects"

default log module for objects

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

Referenced by main().

#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 152 of file pilot-qof.h.

Referenced by pilot_database_open().

#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 158 of file pilot-qof.h.

Referenced by pilot_database_open().

#define PQ_PREF_VERSION   0

Preferences version if not NULL.

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

Referenced by pilot_database_open().


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 242 of file pilot-qof.h.


Function Documentation

int main ( int  argc,
const char *  argv[] 
)

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

References check_invoice_handler(), 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_free(), pilot_qof_init(), PILOT_QOF_LOG, PQContext_s::port, pq_invoice_xmlfile(), 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.

00816 {
00817     const gchar *help_header_text, *input_file, *plu_port;
00818     gint plu_quiet, optc;
00819     PQContext *pilot_qof_context;
00820     gboolean debug_on;
00821     poptContext pc;
00822     gint64 gz_level;
00823     qof_op_type palm_command;
00824 
00825     QOF_OP_VARS struct poptOption options[] = {
00826         {"port", 'p', POPT_ARG_STRING, &plu_port, 0,
00827             _("Use the device <port> to communicate with Palm"),
00828                 "<port>"},
00829         { "quiet",   'q', POPT_ARG_NONE,  &plu_quiet,  0 ,
00830          _("Suppress HotSync connection messages"), NULL},
00831         QOF_CLI_OPTIONS 
00832         {"hot-query", 'a', POPT_ARG_NONE,
00833                 NULL, qof_op_hotsync,
00834             _("Activate/HotSync and query the Palm."), NULL},
00835         {"upload", 'u', POPT_ARG_STRING, &input_file, qof_op_upload,
00836             _("Upload data from <filename> to the Palm. Requires -a"),
00837                 "filename"},
00838         {"invoice-vendor", 0, POPT_ARG_NONE, NULL, qof_op_inv_vendor,
00839             _
00840             ("Shorthand to relate an event or expense to a contact, by vendor. "
00841                     "Requires -t."), NULL},
00842         {"invoice-city", 0, POPT_ARG_NONE, NULL, qof_op_inv_city,
00843             _
00844             ("Shorthand to relate an event or expense to a contact, by city. "
00845                     "Requires -t."), NULL},
00846         {"use-locale", 0, POPT_ARG_NONE, NULL, qof_op_use_locale,
00847                 _
00848             ("Write XML using the current locale encoding instead of UTF-8."),
00849             NULL},
00850         POPT_TABLEEND
00851     };
00852 
00853     palm_command = qof_op_noop;
00854     debug_on = FALSE;
00855     QOF_OP_INIT;
00856     input_file = NULL;
00857     plu_quiet = 0;
00858     plu_port = NULL;
00859 
00860 #ifdef ENABLE_NLS
00861     setlocale (LC_ALL, "");
00862     bindtextdomain (GETTEXT_PACKAGE, LOCALE_DIR);
00863     bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
00864     textdomain (GETTEXT_PACKAGE);
00865 #endif
00866 
00867     help_header_text = _("\n"
00868         "   Query Palm databases as objects and save to XML.\n"
00869 
00870         "   pilot-qof provides a query interface to data on a Palm device,\n"
00871         "   using pilot-link and QOF - the Query Object Framework.\n\n"
00872         "   pilot-qof supports reading addressbook, datebook, expenses and\n"
00873         "   ToDo data from a Palm device to XML files. pilot-qof runs SQL-type\n"
00874         "   queries on the live data or a QSF XML file and results can be imported\n"
00875         "   into other QOF applications or converted to other text based formats,\n"
00876         "   including non-XML formats like vcard.\n"
00877         "   See http://pilot-qof.sourceforge.net/\n\n"
00878         "   Commands are -x -a -l --explain -s or -f.\n"
00879         "   Options are -c -t -w, -d or -e.\n"
00880         "   option -u requires -a\n\n");
00881 
00882     pc = poptGetContext (PACKAGE, argc, argv, options, 0);
00883 
00884     poptSetOtherOptionHelp (pc, help_header_text);
00885 
00886     if (argc < 2)
00887     {
00888         poptPrintUsage (pc, stderr, 0);
00889         return EXIT_FAILURE;
00890     }
00891     pilot_qof_context = pilot_qof_init ();
00892     if (!pilot_qof_context)
00893     {
00894         qof_main_wrap_line (stderr, ERR_INDENT,
00895             _("%s: Failed to initialise "
00896                 "the query object framework."), PACKAGE);
00897         return EXIT_FAILURE;
00898     }
00899     /* convert deprecated date fields into the newly supported
00900     time values. */
00901     qof_mod_convert_deprecated (1, &pilot_qof_context->qof);
00902     while ((optc = poptGetNextOpt (pc)) >= 0)
00903     {
00904         switch (optc)
00905         {
00906             /* commands - mutually exclusive */
00907         case qof_op_offline:
00908         case qof_op_list:
00909         case qof_op_explain:
00910         case qof_op_hotsync:
00911             {
00912                 palm_command = optc;
00913                 break;
00914             }
00915         case qof_op_sql:
00916             {
00917                 qof_mod_sql (sql_query, &pilot_qof_context->qof);
00918                 if (!filename)
00919                 {
00920                     filename = g_strdup (QOF_STDOUT);
00921                 }
00922                 palm_command = qof_op_empty;
00923                 break;
00924             }
00925         case qof_op_sql_file:
00926             {
00927                 qof_mod_sql_file (sql_file, &pilot_qof_context->qof);
00928                 palm_command = qof_op_empty;
00929                 break;
00930             }
00931         case qof_op_vers:
00932             {
00933                 fprintf (stdout, _("\n This is %s v%s\n"), PACKAGE,
00934                     VERSION);
00935                 fprintf (stdout,
00936                     _
00937                     (" Query interface for Palm databases as objects.\n"));
00938                 fprintf (stdout,
00939                     "\n Copyright (c) 2005-2006 "
00940                     "Neil Williams <linux@codehelp.co.uk>\n");
00941                 fprintf (stdout,
00942                     _(" For %s support, join the QOF-devel "
00943                         "mailing list at\n"), PACKAGE);
00944                 fprintf (stdout,
00945                     " http://lists.sourceforge.net/mailman/listinfo/qof-devel\n\n");
00946 /* Translators: Add or subtract dots to keep the translated lines aligned vertically */
00947                 fprintf (stdout, _(" Build target............: %s\n"),
00948                     HOST_OS);
00949 /* Translators: Add or subtract dots to keep the translated lines aligned vertically */
00950                 fprintf (stdout, _(" Build date..............: %s %s\n"),
00951                     __DATE__, __TIME__);
00952 /* Translators: Add or subtract dots to keep the translated lines aligned vertically */
00953                 fprintf (stdout, _(" Built for pilot-link ...: %s\n"),
00954                     PILOT_LINK_SUPPORT);
00955 /* Translators: Add or subtract dots to keep the translated lines aligned vertically */
00956                 fprintf (stdout, _(" --debug logs to.........: %s/%s\n\n"),
00957                     g_get_tmp_dir (), PILOT_QOF_LOG);
00958                 fprintf (stdout,
00959                     _
00960                     (" Please use --help for more detailed options.\n\n"));
00961                 return EXIT_SUCCESS;
00962             }
00963             /* optional modifiers - store to act on later. */
00964         case qof_op_category:
00965             {
00966                 qof_mod_category (category, &pilot_qof_context->qof);
00967                 break;
00968             }
00969         case qof_op_database:
00970             {
00971                 qof_mod_database (database, &pilot_qof_context->qof);
00972                 break;
00973             }
00974         case qof_op_time:
00975             {
00976                 qof_mod_time (date_time, &pilot_qof_context->qof);
00977                 break;
00978             }
00979         case qof_op_exclude:
00980             {
00981                 qof_mod_exclude (exclude, &pilot_qof_context->qof);
00982                 break;
00983             }
00984         case qof_op_write:
00985             {
00986                 qof_mod_write (write_file, &pilot_qof_context->qof);
00987                 break;
00988             }
00989         case qof_op_upload:
00990             {
00991                 if (palm_command != qof_op_hotsync)
00992                 {
00993                     fprintf (stderr,
00994                         _("%s: Error: Please specify -a if you use -u\n"),
00995                         PACKAGE);
00996                     poptPrintUsage (pc, stderr, 0);
00997                     return EXIT_FAILURE;
00998                 }
00999                 pilot_qof_context->qof.input_file = g_strdup (input_file);
01000                 break;
01001             }
01002         case qof_op_debug:
01003             {
01004                 gchar *log;
01005 
01006                 log =
01007                     g_strconcat (g_get_tmp_dir (), "/", PILOT_QOF_LOG,
01008                     NULL);
01009                 qof_log_init_filename (log);
01010                 g_free (log);
01011                 qof_log_set_default (QOF_LOG_DETAIL);
01012                 qof_log_set_level (PQ_MOD_CLI, QOF_LOG_DETAIL);
01013                 qof_log_set_level (PQ_MOD_PILOT, QOF_LOG_DETAIL);
01014                 qof_log_set_level (QOF_MAIN_CLI, QOF_LOG_DETAIL);
01015                 qof_log_set_level (QOF_MOD_QSF, QOF_LOG_DETAIL);
01016                 qof_log_set_level ("qof-sqlite-module", QOF_LOG_DETAIL);
01017                 debug_on = TRUE;
01019                 break;
01020             }
01021         case qof_op_compress:
01022             {
01023                 pilot_qof_context->qof.gz_level = gz_level;
01024                 break;
01025             }
01026         case qof_op_inv_vendor:
01027             {
01028                 if (!pilot_qof_context->invoice_city)
01029                     pilot_qof_context->invoice_vendor = TRUE;
01030                 break;
01031             }
01032         case qof_op_inv_city:
01033             {
01034                 pilot_qof_context->invoice_city = TRUE;
01035                 pilot_qof_context->invoice_vendor = FALSE;
01036                 break;
01037             }
01038         case qof_op_use_locale:
01039             {
01040                 const gchar *locale_encoding;
01041                 gboolean test;
01042                 locale_encoding = NULL;
01043                 test = g_get_charset (&locale_encoding);
01044                 if (!test)
01045                     qof_mod_encoding (locale_encoding,
01046                         &pilot_qof_context->qof);
01047                 break;
01048             }
01049         default:
01050             {
01051                 fprintf (stderr, _("%s: ERROR: got option %d, arg %s\n"),
01052                     PACKAGE, optc, poptGetOptArg (pc));
01053                 return EXIT_FAILURE;
01054             }
01055         }
01056     }
01057     if (qof_op_noop == palm_command)
01058     {
01059         qof_main_wrap_line (stderr, ERR_INDENT,
01060             _("%s: ERROR: specify a command "
01061                 "-x, -a, -l, -s or -f, or --explain.\n"), PACKAGE);
01062         poptPrintUsage (pc, stderr, 0);
01063         return EXIT_FAILURE;
01064     }
01065     if (qof_op_noop == palm_command)
01066     {
01067         fprintf (stderr, _("%s: ERROR: specify a command "
01068         "-x, -a, -l, -s or -f, or --explain.\n"), PACKAGE);
01069         poptPrintUsage(pc, stderr, 0);
01070         return EXIT_FAILURE;
01071     }
01072     if (optc < -1)
01073     {
01074         fprintf (stderr, "%s: %s %s\n\n", PACKAGE,
01075             poptBadOption (pc, POPT_BADOPTION_NOALIAS),
01076             poptStrerror (optc));
01077         poptPrintUsage (pc, stderr, 0);
01078         return EXIT_FAILURE;
01079     }
01080     /* If we get this far, we should have sensible options: start the work. */
01081     pilot_qof_context->qof.input_session = qof_session_new ();
01082     switch (palm_command)
01083     {
01084     case qof_op_empty:
01085     {
01086         pilot_qof_context->qof.filename = g_strdup (filename);
01087         if ((pilot_qof_context->invoice_city)
01088             || (pilot_qof_context->invoice_vendor))
01089         {
01090             check_invoice_handler (pilot_qof_context);
01091             if (pilot_qof_context->qof.error)
01092                 return EXIT_FAILURE;
01093             pq_invoice_xmlfile (pilot_qof_context);
01094         }
01095         else
01096             qof_cmd_xmlfile (&pilot_qof_context->qof);
01097         break;
01098     }
01099     case qof_op_offline:
01100         {
01101             pilot_qof_context->qof.filename = g_strdup (filename);
01102             if ((pilot_qof_context->invoice_city)
01103                 || (pilot_qof_context->invoice_vendor))
01104             {
01105                 check_invoice_handler (pilot_qof_context);
01106                 if (pilot_qof_context->qof.error)
01107                     return EXIT_FAILURE;
01108                 pq_invoice_xmlfile (pilot_qof_context);
01109             }
01110             else
01111                 qof_cmd_xmlfile (&pilot_qof_context->qof);
01112             break;
01113         }
01114     case qof_op_list:
01115         {
01116             DEBUG (" list mode");
01117             qof_cmd_list ();
01118             break;
01119         }
01120     case qof_op_explain:
01121         {
01122             if (!pilot_qof_context->qof.database)
01123             {
01124                 qof_main_wrap_line (stderr, ERR_INDENT,
01125                     _("%s: Error: please specify which database "
01126                         "you would like explained.\n\n"), PACKAGE);
01127                 break;
01128             }
01129             DEBUG (" explain mode");
01130             qof_cmd_explain (&pilot_qof_context->qof);
01131             break;
01132         }
01133     case qof_op_hotsync:
01134         {
01135             DEBUG (" hotsync mode");
01136             pilot_qof_context->port = g_strdup (plu_port);
01137             pilot_qof_context->quiet = plu_quiet;
01138             qof_cmd_hotsync (pilot_qof_context);
01139             break;
01140         }
01141     default:
01142         {
01143             /* should be impossible */
01144             break;
01145         }
01146     }
01147     poptFreeContext (pc);
01148     pilot_qof_free (pilot_qof_context);
01149     if (debug_on)
01150         qof_log_shutdown ();
01151     qof_close ();
01152     return EXIT_SUCCESS;
01153 }

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 335 of file pilot-qof.c.

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

Referenced by pilot_database_open().

00336 {
00337     PQContext *context;
00338     QofPack app_unpack;
00339     const PQPack *p;
00340 
00341     context = (PQContext *) user_data;
00342     g_return_if_fail (context != NULL);
00343     p = pilot_qof_pack_lookup (e_type);
00344     if (!p)
00345         return;
00346     app_unpack = p->app_info_unpack;
00347     if (app_unpack == NULL)
00348     {
00349         context->qof.error = TRUE;
00350         PERR (" no app_info_unpack routine for %s", e_type);
00351         return;
00352     }
00353     /* no entity available for the appInfo, pass NULL and work only in the context. */
00354     app_unpack (NULL, context);
00355 }

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 380 of file pilot-qof.c.

References pilot_object_free().

00381 {
00382     qof_object_foreach_type (pilot_object_free, book);
00383 }

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.

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

References AddressRegister(), DateBookRegister(), ExpensesRegister(), pilot_qof_create(), and ToDoRegister().

Referenced by main().

00110 {
00111     qof_init ();
00112     g_return_val_if_fail (AddressRegister (), NULL);
00113     g_return_val_if_fail (ExpensesRegister (), NULL);
00114     g_return_val_if_fail (DateBookRegister (), NULL);
00115     g_return_val_if_fail (ToDoRegister (), NULL);
00116     return pilot_qof_create ();
00117 }

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 262 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, pq_findcategory(), PQContext_s::qof, and PQContext_s::sd.

Referenced by write_ent_cb().

00263 {
00264     const gchar *category_name;
00265     const QofParam *param;
00266     gint size, result;
00267     QofPack pack_func;
00268     PQContext *context;
00269     const PQPack *p;
00270 
00271     context = (PQContext *) user_data;
00272     size = result = 0;
00273     g_return_if_fail (context != NULL);
00274     p = pilot_qof_pack_lookup (ent->e_type);
00275     if (!p)
00276         return;
00277     context->pi_buf = pi_buffer_new (PQ_DEF_BUFSZ);
00278     pack_func = p->pack_func;
00279     if (pack_func == NULL)
00280     {
00281         context->qof.error = TRUE;
00282         return;
00283     }
00284     size = pack_func (ent, context);
00285     if (size == -1)
00286         return;
00287     param = qof_class_get_parameter (ent->e_type, CATEGORY_NAME);
00288     category_name = (const gchar *) param->param_getfcn (ent, param);
00289     context->ent_category = pq_findcategory(context, 
00290         category_name, PLU_CAT_CASE_INSENSITIVE | PLU_CAT_DEFAULT_UNFILED);
00291 /*  context->ent_category = plu_findcategory (context->pi_cat,
00292         category_name, PLU_CAT_CASE_INSENSITIVE | PLU_CAT_DEFAULT_UNFILED);*/
00293     if (context->ent_category == 0)
00294         PWARN (" Category: '%s' not found or not set, using 'Unfiled'",
00295             category_name);
00296     result = dlp_WriteRecord (context->sd, context->db,
00297         PQ_DLP_REC_ATTR, PQ_DLP_NEW_REC, context->ent_category,
00298         context->pi_buf->data, size, PQ_DLP_SET_ID);
00299     if (result < 0)
00300     {
00301         PERR (" record could not be written: error %d", result);
00302         return;
00303     }
00304 }

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 396 of file pilot-qof.c.

References PilotPack_s::e_type, and pilot_modules.

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

00397 {
00398     GList *piter;
00399     PQPack *p;
00400 
00401     if (!object_type)
00402         return NULL;
00403     for (piter = pilot_modules; piter; piter = piter->next)
00404     {
00405         p = piter->data;
00406         if (0 == safe_strcmp (p->e_type, object_type))
00407             return p;
00408     }
00409     return NULL;
00410 }

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 386 of file pilot-qof.c.

References pilot_modules.

Referenced by AddressRegister(), DateBookRegister(), ExpensesRegister(), and ToDoRegister().

00387 {
00388     if (g_list_index (pilot_modules, (gpointer) p) == -1)
00389         pilot_modules = g_list_prepend (pilot_modules, (gpointer) p);
00390     else
00391         return FALSE;
00392     return TRUE;
00393 }

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 307 of file pilot-qof.c.

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

Referenced by pilot_database_open().

00308 {
00309     QofPack unpack_func;
00310     const PQPack *p;
00311     PQContext *context;
00312     gint result;
00313 
00314     context = (PQContext *) user_data;
00315     g_return_if_fail (context && ent);
00316     p = pilot_qof_pack_lookup (ent->e_type);
00317     g_return_if_fail (p);
00318     unpack_func = p->unpack_func;
00319     if (unpack_func == NULL)
00320     {
00321         context->qof.error = TRUE;
00322         PERR ("No unpack routine was defined for the %s object!",
00323             ent->e_type);
00324         return;
00325     }
00326     result = unpack_func (ent, context);
00327     if (result < 0)
00328     {
00329         qof_entity_release (ent);
00330         g_free (ent);
00331     }
00332 }

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 683 of file pilot-qof.c.

References check_invoice_handler(), QofMain_s::database, ERR_INDENT, QofMain_s::error, QofMain_s::exclude, QofMain_s::export_session, find_invoice_contact(), QofMain_s::gz_level, QofMain_s::input_file, QofMain_s::input_session, PQContext_s::invoice_city, PQContext_s::invoice_vendor, pilot_database_open(), pilot_error(), PILOT_LINK_QOF_ADDRESS, PILOT_LINK_QOF_DATEBOOK, PILOT_LINK_QOF_EXPENSES, plu_connect(), 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().

00684 {
00685     struct PilotUser QUser;
00686     QofBook *book;
00687     gchar *log_msg;
00688 
00689     if (0 == safe_strcmp (context->qof.exclude, context->qof.database)
00690         && (context->qof.exclude != NULL))
00691     {
00692         /* Translators: The first string is the package name.
00693            The second and third are database names. */
00694         qof_main_wrap_line (stderr, ERR_INDENT,
00695             _("%s: Error: Cannot exclude "
00696                 "database \"%s\" with option -e because option -d is set to the "
00697                 "same database: \"%s\""), PACKAGE, context->qof.exclude,
00698             context->qof.database);
00699         qof_session_end (context->qof.input_session);
00700         return;
00701     }
00702     if ((context->invoice_city) || (context->invoice_vendor))
00703         check_invoice_handler (context);
00704     if (context->qof.error)
00705         return;
00706     if (context->qof.input_file)
00707     {
00708         PINFO (" Trying to upload %s", context->qof.input_file);
00709         qof_session_begin (context->qof.input_session,
00710             context->qof.input_file, TRUE, FALSE);
00711         qof_session_load (context->qof.input_session, NULL);
00712     }
00713     else
00714         qof_session_begin (context->qof.input_session, QOF_STDOUT, TRUE,
00715             FALSE);
00716     context->qof.export_session = qof_session_new ();
00717 
00718     context->sd = plu_connect (context->port, context->quiet);
00719 
00720     if (context->sd < 0)
00721     {
00722         pilot_error (context, _("Unable to connect to the Palm"));
00723         return;
00724     }
00725     if (dlp_ReadUserInfo (context->sd, &QUser) < 0)
00726     {
00727         pilot_error (context, _("Unable to read Palm user info"));
00728         return;
00729     }
00730     context->qof.error = FALSE;
00731     qof_object_foreach_type (pilot_database_open, context);
00732     QUser.lastSyncPC = 0x00010000;
00733     QUser.lastSyncDate = QUser.successfulSyncDate = time (0);
00734     if (dlp_WriteUserInfo (context->sd, &QUser) < 0)
00735     {
00736         pilot_error (context, _("Unable to write user info"));
00737         return;
00738     }
00739     /* Translators: each string is the package name. */
00740     log_msg = g_strdup_printf (_("%s hotsync\n\n"
00741             "Thank you for using %s.\n"), PACKAGE, PACKAGE);
00742     dlp_AddSyncLogEntry (context->sd, log_msg);
00743     g_free (log_msg);
00744     dlp_EndOfSync (context->sd, 0);
00745     pi_close (context->sd);
00746     /* Now run the query, copy the objects, destroy the input session */
00747     /*and write out export_session */
00748     if (context->qof.write_file)
00749     {
00750         qof_session_begin (context->qof.export_session,
00751             context->qof.write_file, TRUE, TRUE);
00752         qof_mod_compression (context->qof.gz_level, &context->qof);
00753     }
00754     else
00755         qof_session_begin (context->qof.export_session, QOF_STDOUT, TRUE,
00756             FALSE);
00757     /* Note if no query is given, ignore repeater clones?
00758        Nice idea, but in practice, difficult. It also makes recursive
00759        queries of the XML harder as the XML needs to understand datebook
00760        repeats. Instead, we simply ignore all repeater clones when it comes
00761        to write data to the Palm by a simple check in datebook_pack.
00762      */
00763     qof_main_moderate_query (&context->qof);
00764     /* if invoice_hook, create a second query and lookup in contacts */
00765     if ((context->invoice_city) || (context->invoice_vendor))
00766     {
00767         book = qof_session_get_book (context->qof.export_session);
00768         context->qof.query = qof_query_create_for (PILOT_LINK_QOF_ADDRESS);
00769         qof_object_foreach (PILOT_LINK_QOF_DATEBOOK, book,
00770             find_invoice_contact, context);
00771         qof_object_foreach (PILOT_LINK_QOF_EXPENSES, book,
00772             find_invoice_contact, context);
00773     }
00774     qof_session_save (context->qof.export_session, NULL);
00775     qof_main_show_error (context->qof.export_session);
00776     qof_session_end (context->qof.input_session);
00777     qof_session_end (context->qof.export_session);
00778 }


Variable Documentation

QofLogModule log_module = "pilotqof-cli" [static]

used to print debug logs.

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

GList* pilot_modules = NULL [static]

pack routines for communication with pilot

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

Referenced by pilot_qof_pack_lookup(), and pilot_qof_pack_register().


Generated on Tue Mar 6 00:08:09 2007 for pilot-qof by  doxygen 1.5.1