qof-main.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  *            qof-main.c
00003  *
00004  *  This is an auto-generated file. Patches are available from
00005  *  http://qof-gen.sourceforge.net/
00006  *
00007  *  Thu Jan 13 10:55:44 2005
00008  *  Copyright  2005-2006  Neil Williams
00009  *  linux@codehelp.co.uk
00010  ****************************************************************************/
00011 /*
00012  *  This program is free software; you can redistribute it and/or modify
00013  *  it under the terms of the GNU General Public License as published by
00014  *  the Free Software Foundation; either version 2 of the License, or
00015  *  (at your option) any later version.
00016  *
00017  *  This program is distributed in the hope that it will be useful,
00018  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00019  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020  *  GNU General Public License for more details.
00021  *
00022  *  You should have received a copy of the GNU General Public License
00023  *  along with this program; if not, write to the Free Software
00024  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00025  */
00026 
00038 #define _GNU_SOURCE
00039 #include "config.h"
00040 #include <glib.h>
00041 #include <glib/gi18n.h>
00042 #include <glib/gprintf.h>
00043 #include <qof.h>
00044 #include <stdlib.h>
00045 #include <stdio.h>
00046 #include <regex.h>
00047 #include <time.h>
00048 #include "qof-main.h"
00049 
00050 #define MAX_LINE 79
00051 
00052 /* the debugging module for this file. */
00053 static QofLogModule log_module = QOF_MAIN_CLI;
00054 
00055 void
00056 qof_main_wrap_line (FILE * fp, gint indent, 
00057                                         const gchar * template, ...)
00058 {
00059         gint line_length, msg_length;
00060         va_list wraps;
00061         gchar *message;
00062 
00063         line_length = MAX_LINE;
00064         /* note the modulus. Don't use CLAMP here */
00065         /* indent != line_length or particularly close to it. */
00066         indent = indent >= line_length ? indent % line_length : indent;
00067         indent = indent < 0 ? 0 : indent;
00068         message = NULL;
00069         g_return_if_fail (template);
00070         va_start (wraps, template);
00071         message = g_strdup_vprintf (template, wraps);
00072         va_end (wraps);
00073         g_return_if_fail (message);
00074         msg_length = strlen (message);
00075         while (msg_length > line_length)
00076         {
00077                 gchar *chunk;
00078                 gchar format[16];
00079 
00080                 chunk = message + line_length - 1;
00081                 while (chunk > message && !g_ascii_isspace (*chunk))
00082                         chunk--;
00083                 if (chunk == message)
00084                         break;                          /* give up */
00085                 while (chunk > (message + 1) && g_ascii_isspace (*chunk))
00086                         chunk--;
00087                 chunk++;
00088                 g_sprintf (format, "%%.%ds\n%%%ds", (gint) (chunk - message),
00089                         indent);
00090                 g_fprintf (fp, format, message, "");
00091                 message = chunk;
00092                 while (g_ascii_isspace (*message) && *message)
00093                         message++;
00094                 msg_length = strlen (message);
00095                 if (line_length == MAX_LINE)
00096                         line_length -= indent;
00097         }
00098         if (msg_length)
00099                 g_fprintf (fp, "%s\n", message);
00100 }
00101 
00102 gchar *
00103 qof_main_make_utf8 (gchar * string)
00104 {
00105         gchar *value;
00106 
00107         if (!string)
00108                 return NULL;
00109         if (g_utf8_validate (string, -1, NULL))
00110                 return string;
00111         value = g_locale_to_utf8 (string, -1, NULL, NULL, NULL);
00112         if (!value)
00113         {
00114                 PWARN (" unable to convert from locale %s", string);
00115                 PINFO ("trying to convert from ISO-8859-15.");
00116                 value = g_convert (string, -1, "UTF-8", "ISO-8859-15",
00117                         NULL, NULL, NULL);
00118                 if (!value)
00119                 {
00120                         PERR (" conversion failed");
00121                         return string;
00122                 }
00123                 return value;
00124         }
00125         return value;
00126 }
00127 
00128 static void
00129 qof_main_run_sql (QofMainContext * context)
00130 {
00131         QofSqlQuery *q;
00132         QofBook *book;
00133         gchar *sql;
00134 
00135         ENTER (" ");
00136         q = qof_sql_query_new ();
00137         sql = g_strdup (context->sql_str);
00138         book = qof_session_get_book (context->input_session);
00139         qof_sql_query_set_book (q, book);
00140         qof_sql_query_run (q, sql);
00141         context->query = qof_sql_query_get_query (q);
00142         LEAVE (" ");
00143 }
00144 
00145 static void
00146 qof_main_run_query (QofMainContext * context)
00147 {
00148         QofBook *book;
00149         GList *results;
00150 
00151         ENTER (" ");
00152         results = NULL;
00153         book = qof_session_get_book (context->input_session);
00154         qof_query_set_book (context->query, book);
00155         results = qof_query_run (context->query);
00156         if (results != NULL)
00157                 qof_entity_copy_list (context->export_session, results);
00158         LEAVE (" ");
00159 }
00160 
00161 void
00162 qof_main_free (QofMainContext * context)
00163 {
00164         g_free (context->filename);
00165         g_free (context->write_file);
00166         g_free (context->sql_file);
00167         g_free (context->database);
00168         g_free (context->category);
00169 }
00170 
00171 static void
00172 find_param_cb (QofParam * param, gpointer user_data)
00173 {
00174         gchar * tmp;
00175         QofMainContext *context;
00176         QofQueryPredData *time_pred_data;
00177 
00178         context = (QofMainContext *) user_data;
00179         if ((param->param_getfcn == NULL) || 
00180                 (param->param_setfcn == NULL))
00181                 return;
00182         if (0 == safe_strcmp (context->param_type, param->param_type))
00183         {
00184                 time_pred_data = qof_query_time_predicate (QOF_COMPARE_GTE,
00185                         QOF_DATE_MATCH_NORMAL, context->min_qt);
00186                 tmp = g_strdup (param->param_name);
00187                 qof_query_add_term (context->query, 
00188                         qof_query_build_param_list (tmp, NULL), time_pred_data, QOF_QUERY_AND);
00189                 time_pred_data = qof_query_time_predicate (QOF_COMPARE_LTE,
00190                         QOF_DATE_MATCH_NORMAL, context->max_qt);
00191                 qof_query_add_term (context->query, 
00192                         qof_query_build_param_list (tmp, NULL), time_pred_data, QOF_QUERY_AND);
00193                 qof_main_run_query (context);
00194                 qof_query_purge_terms (context->query, 
00195                         qof_query_build_param_list (tmp, QOF_ID_BOOK, QOF_TYPE_GUID, NULL));
00196                 PINFO (" param_name=%s added", tmp);
00197         }
00198         LEAVE (" ");
00199 }
00200 
00201 /* takes one database name and runs -c and -t queries against it. */
00202 static void
00203 build_database_list (QofIdTypeConst obj_type, QofMainContext * context)
00204 {
00205         if (!obj_type || !context)
00206                 return;
00207         if (!qof_class_is_registered (obj_type))
00208                 return;
00209         ENTER (" object_type=%s", obj_type);
00210         context->query = qof_query_create_for (obj_type);
00211         if (context->category != NULL)
00212         {
00213                 QofQueryPredData *category_pred;
00214 
00215                 category_pred =
00216                         qof_query_string_predicate (QOF_COMPARE_EQUAL,
00217                         context->category, QOF_STRING_MATCH_CASEINSENSITIVE, 
00218                         FALSE);
00219                 qof_query_add_term (context->query, 
00220                         qof_query_build_param_list (CATEGORY_NAME, NULL),
00221                         category_pred, QOF_QUERY_AND);
00222         }
00223         if (context->min_qt)
00224         {
00225                 PINFO (" Preparing a time based queryset.");
00226                 context->param_type = QOF_TYPE_TIME;
00227                 qof_class_param_foreach (obj_type, find_param_cb, context);
00228         }
00229         else
00230         {
00231                 qof_main_run_query (context);
00232                 if (context->query)
00233                         qof_query_clear (context->query);
00234         }
00235         LEAVE (" ");
00236 }
00237 
00238 static void
00239 select_cb (QofObject * obj, gpointer data)
00240 {
00241         QofMainContext *context;
00242 
00243         context = (QofMainContext *) data;
00244         g_return_if_fail (context);
00245         if (0 != safe_strcmp (context->exclude, obj->e_type))
00246                 build_database_list (obj->e_type, context);
00247 }
00248 
00249 void
00250 qof_main_moderate_query (QofMainContext * context)
00251 {
00252         GSList *date_param_list, *category_param_list;
00253         gboolean all;
00254 
00255         ENTER (" ");
00256         all = TRUE;
00257         context->query = qof_query_create ();
00258         date_param_list = NULL;
00259         category_param_list = NULL;
00260         while (context->sql_list)
00261         {
00262                 PINFO ("running sql_list");
00263                 context->sql_str = g_strdup (context->sql_list->data);
00264                 qof_main_run_sql (context);
00265                 qof_main_run_query (context);
00266                 if (context->query)
00267                         qof_query_clear (context->query);
00268                 g_free (context->sql_str);
00269                 context->sql_str = NULL;
00270                 all = FALSE;
00271                 context->sql_list = g_list_next (context->sql_list);
00272         }
00273         if (0 < g_list_length (context->sql_list))
00274         {
00275                 context->sql_str = NULL;
00276                 g_list_free (context->sql_list);
00277                 all = FALSE;
00278         }
00279         if (context->sql_str != NULL)
00280         {
00281                 PINFO ("running sql_str");
00282                 qof_main_run_sql (context);
00283                 qof_main_run_query (context);
00284                 if (context->query)
00285                         qof_query_clear (context->query);
00286                 all = FALSE;
00287         }
00288         if ((context->exclude != NULL)
00289                 && (qof_class_is_registered (context->exclude)))
00290         {
00291                 qof_object_foreach_type (select_cb, context);
00292                 all = FALSE;
00293         }
00294         if ((context->database != NULL)
00295                 && (qof_class_is_registered (context->database)))
00296         {
00297                 build_database_list (context->database, context);
00298                 all = FALSE;
00299         }
00300         if (all == TRUE)
00301                 qof_object_foreach_type (select_cb, context);
00302         LEAVE (" ");
00303 }
00304 
00305 static void
00306 option_cb (QofBackendOption * option, gpointer data)
00307 {
00308         QofMainContext *context;
00309 
00310         context = (QofMainContext *) data;
00311         g_return_if_fail (context);
00312 /* Normally, I'd use GPOINTER_TO_INT but internally, 
00313 the QofBackendOption uses gint64 which gets mangled by
00314 the 32-bit macro. */
00315         ENTER (" compression=%" G_GINT64_FORMAT " encoding=%s",
00316                 context->gz_level, context->encoding);
00317         if (0 == safe_strcmp (QSF_COMPRESS, option->option_name))
00318                 option->value = (gpointer) & context->gz_level;
00319         if (0 == safe_strcmp (QSF_ENCODING, option->option_name))
00320                 option->value = (gpointer) g_strdup(context->encoding);
00321         if (0 == safe_strcmp (QSF_DATE_CONVERT, option->option_name))
00322                 option->value = (gpointer) & context->convert;
00323         LEAVE (" ");
00324 }
00325 
00326 void
00327 qof_mod_compression (gint64 gz_level, QofMainContext * context)
00328 {
00329         KvpFrame *be_config;
00330         QofBook *book;
00331         QofBackend *be;
00332 
00333         ENTER (" compression=%" G_GINT64_FORMAT, gz_level);
00334         if ((gz_level > 0) && (gz_level <= 9))
00335         {
00336                 book = qof_session_get_book (context->export_session);
00337                 be = qof_book_get_backend (book);
00338                 be_config = qof_backend_get_config (be);
00339                 context->gz_level = gz_level;
00340                 qof_backend_option_foreach (be_config, option_cb, context);
00341                 qof_backend_load_config (be, be_config);
00342         }
00343         LEAVE (" ");
00344 }
00345 
00346 void
00347 qof_mod_encoding (const gchar * encoding, QofMainContext * context)
00348 {
00349         KvpFrame *be_config;
00350         QofBook *book;
00351         QofBackend *be;
00352 
00353         ENTER (" encode to %s", encoding);
00354         book = qof_session_get_book (context->export_session);
00355         be = qof_book_get_backend (book);
00356         be_config = qof_backend_get_config (be);
00357         context->encoding = encoding;
00358         qof_backend_option_foreach (be_config, option_cb, context);
00359         qof_backend_load_config (be, be_config);
00360         LEAVE (" ");
00361 }
00362 
00363 void
00364 qof_mod_convert_deprecated (gint64 convert, QofMainContext * context)
00365 {
00366         KvpFrame *be_config;
00367         QofBook *book;
00368         QofBackend *be;
00369         gboolean set;
00370 
00371         set = (convert == 0) ? FALSE : TRUE;
00372         ENTER (" convert deprecated date values? %i No if 0.", set);
00373         book = qof_session_get_book (context->export_session);
00374         be = qof_book_get_backend (book);
00375         be_config = qof_backend_get_config (be);
00376         context->convert = convert;
00377         qof_backend_option_foreach (be_config, option_cb, context);
00378         qof_backend_load_config (be, be_config);
00379         LEAVE (" ");
00380 }
00381 
00382 void
00383 qof_cmd_xmlfile (QofMainContext * context)
00384 {
00385         QofSession *input_session, *export_session;
00386 
00387         ENTER (" ");
00388         input_session = context->input_session;
00389         if (0 == safe_strcmp (context->exclude, context->database)
00390                 && (context->exclude != NULL))
00391         {
00392                 qof_main_wrap_line (stderr, ERR_INDENT,
00393                 /* Translators: This line is wrapped by the program - 
00394                 please make sure you do NOT add line endings here. */
00395                         _("%s: Error: Cannot exclude database \"%s\" with option -e "
00396                                 "because option -d is set to include the database: \"%s\". "
00397                                 "Use the \'-l\' command to see the full list of supported "
00398                                 "databases.\n"), PACKAGE, context->exclude,
00399                         context->database);
00400                 qof_session_end (input_session);
00401                 LEAVE (" conflicting options");
00402                 return;
00403         }
00404         qof_session_begin (input_session, context->filename, TRUE, FALSE);
00405         qof_main_show_error (input_session);
00406         if (0 != safe_strcmp (QOF_STDOUT, context->filename))
00407                 qof_session_load (input_session, NULL);
00408         qof_main_show_error (input_session);
00409         export_session = qof_session_new ();
00410         context->export_session = export_session;
00411         if (context->write_file)
00412         {
00413                 qof_session_begin (export_session, context->write_file, TRUE,
00414                         TRUE);
00415                 qof_mod_compression (context->gz_level, context);
00416         }
00417         else
00418                 qof_session_begin (export_session, QOF_STDOUT, TRUE, TRUE);
00419         qof_main_show_error (export_session);
00420         /* ensure encoding value is set in the new export_session */
00421         qof_mod_encoding (context->encoding, context);
00422         qof_main_moderate_query (context);
00423         qof_session_save (export_session, NULL);
00424         qof_main_show_error (export_session);
00425         qof_main_show_error (input_session);
00426         qof_session_end (input_session);
00427         qof_session_end (export_session);
00428         LEAVE (" ");
00429 }
00430 
00431 static void
00432 qof_main_list (QofObject * obj, gpointer G_GNUC_UNUSED data)
00433 {
00434         fprintf (stdout, "%-20s%-20s\n", obj->e_type, obj->type_label);
00435 }
00436 
00437 void
00438 qof_main_select (QofMainContext * context)
00439 {
00440         g_return_if_fail (context);
00441         qof_object_foreach_type (select_cb, context);
00442 }
00443 
00444 void
00445 qof_cmd_list (void)
00446 {
00447         qof_main_wrap_line (stdout, 0,
00448         /* Translators: This line is wrapped by the program - 
00449         please make sure you do NOT add line endings here. */
00450                 _("\n%s: You can use the supported database names with '%s -d' "
00451                         "and in SQL queries (as the table name) with '%s -s|f'. "
00452                         "Descriptions are shown only for readability.\n"),
00453                 PACKAGE, PACKAGE, PACKAGE);
00454         fprintf (stdout, "%-20s%-20s\n", _("Name"), _("Description"));
00455         qof_object_foreach_type (qof_main_list, NULL);
00456         qof_main_wrap_line (stdout, 0,
00457         /* Translators: This line is wrapped by the program -
00458         please make sure you do NOT add line endings here. */
00459                 _("\nUse '%s -d <database> --explain' to see the list of fields "
00460                         "within any supported database."), PACKAGE);
00461         fprintf (stdout, _("\nThank you for using %s\n\n"), PACKAGE);
00462 }
00463 
00464 static void
00465 explain_cb (QofParam * param, gpointer G_GNUC_UNUSED user_data)
00466 {
00467         if (param->param_getfcn && param->param_setfcn)
00468                 fprintf (stdout, _("Type: %s\tName: %s\n"),
00469                         param->param_type, param->param_name);
00470 }
00471 
00472 void
00473 qof_cmd_explain (QofMainContext * context)
00474 {
00475         if (context->error)
00476                 return;
00477         fprintf (stdout, _("\nParameters of the %s database:\n\n"),
00478                 context->database);
00479         qof_class_param_foreach (context->database, explain_cb, NULL);
00480         fprintf (stdout, _("\nThank you for using %s\n\n"), PACKAGE);
00481 }
00482 
00483 void
00484 qof_mod_category (const gchar * category, QofMainContext * data)
00485 {
00486         data->category = g_strdup (category);
00487 }
00488 
00489 glong
00490 qof_mod_get_local_offset (void)
00491 {
00492         glong local_offset;
00493         struct tm local;
00494         time_t now;
00495 
00496         local_offset = 0; /* UTC */
00497         now = time (NULL);
00498         local = *localtime_r (&now, &local);
00499         local_offset -= local.tm_gmtoff;
00500         return local_offset;
00501 }
00502 
00503 void
00504 qof_mod_database (const gchar * database, QofMainContext * data)
00505 {
00506         if (qof_class_is_registered (database))
00507                 data->database = g_strdup (database);
00508 }
00509 
00510 void
00511 qof_mod_time (const gchar * date_time, QofMainContext * data)
00512 {
00513         QofDate *qd;
00514         gboolean all_year, all_month;
00515         gint adding_days;
00516         gchar *info;
00517 
00518         /* incoming date is assumed to be localtime */
00519         ENTER (" date_time=%s", date_time);
00520         all_month = all_year = FALSE;
00521         g_return_if_fail (date_time);
00522         qd = qof_date_parse (date_time, QOF_DATE_FORMAT_ISO);
00523         if (!qd)
00524                 qd = qof_date_parse (date_time, QOF_DATE_FORMAT_UTC);
00525         info = qof_date_print (qd, QOF_DATE_FORMAT_ISO8601);
00526         PINFO (" parsed start_time=%s", info);
00527         g_free (info);
00528         /* set first second of day, UTC */
00529         qof_date_set_day_start (qd);
00530         data->min_qt = qof_date_to_qtime (qd);
00531         /* adjust for incoming localtime */
00532         qof_time_add_secs (data->min_qt, 
00533                 qof_mod_get_local_offset());
00534         /* year specified but no month or day, select the entire year */
00535         if (strlen (date_time) == 4)
00536         {
00537                 PINFO (" match entire year %s", date_time);
00538                 /* go to end of this year, not first day of next. */
00539                 adding_days = qof_date_isleap(qd->qd_year) ? 365 : 364;
00540                 qof_date_adddays (qd, adding_days);
00541         }
00542         /* month specified, but no day, select entire month */
00543         if (strlen (date_time) == 7)
00544         {
00545                 PINFO (" match entire month %s", date_time);
00546                 adding_days = qof_date_get_mday (qd->qd_mon, qd->qd_year);
00547                 qof_date_adddays (qd, adding_days - 1);
00548         }
00549         /* set last second of day */
00550         qof_date_set_day_end (qd);
00551         data->max_qt = qof_date_to_qtime (qd);
00552         /* adjust for incoming localtime */
00553         qof_time_add_secs (data->max_qt, 
00554                 qof_mod_get_local_offset());
00555         LEAVE (" ");
00556 }
00557 
00558 void
00559 qof_mod_exclude (const gchar * exclude, QofMainContext * data)
00560 {
00561         if (qof_class_is_registered (exclude))
00562                 data->exclude = g_strdup (exclude);
00563 }
00564 
00565 void
00566 qof_mod_sql (const gchar * sql_query, QofMainContext * data)
00567 {
00568         data->sql_str = g_strdup (sql_query);
00569 }
00570 
00571 void
00572 qof_mod_sql_file (const gchar * sql_file, QofMainContext * data)
00573 {
00574         FILE *filehandle;
00575 #ifndef HAVE_GETLINE
00576         gchar lineptr[1024];
00577 #else
00578         gchar *lineptr;
00579 #endif
00580         gchar *buf;
00581         size_t n;
00582         QofQuery *q;
00583         regex_t *r;
00584         gint reg_exp_check;
00585         const gchar *fmt;
00586         static gchar *pattern = QOF_SQL_SUPPORTED;
00587 
00588         ENTER (" ");
00589         data->sql_file = g_strdup (sql_file);
00590         n = 0;
00591         q = NULL;
00592         data->sql_list = NULL;
00593         filehandle = fopen (sql_file, "r");
00594         if (!filehandle)
00595         {
00596                 fmt = _("%s: There was an error reading the file '%s'.\n");
00597                 qof_main_wrap_line (stderr, ERR_INDENT, fmt, PACKAGE, sql_file);
00598                 return;
00599         }
00600         r = g_new (regex_t, 1);
00601 #ifndef HAVE_GETLINE
00602         while (NULL != (fgets (lineptr, sizeof (lineptr), filehandle)))
00603 #else
00604         lineptr = NULL;
00605         while (0 < getline (&lineptr, &n, filehandle))
00606 #endif
00607         {
00608                 reg_exp_check =
00609                         regcomp (r, pattern, REG_ICASE | REG_NOSUB | REG_EXTENDED);
00610                 g_return_if_fail (reg_exp_check == 0);
00611                 if (0 != regexec (r, lineptr, 0, NULL, 0))
00612                         continue;
00613                 buf = g_strdup (g_strchomp (lineptr));
00614                 data->sql_list = g_list_prepend (data->sql_list, buf);
00615         }
00616         regfree (r);
00617         g_free (r);
00618         fclose (filehandle);
00619         LEAVE (" sql_list=%d", g_list_length (data->sql_list));
00620 }
00621 
00622 void
00623 qof_mod_write (const gchar * write_file, QofMainContext * data)
00624 {
00625         data->write_file = g_strdup (write_file);
00626 }
00627 
00628 void
00629 qof_main_show_error (QofSession * session)
00630 {
00631         const gchar *fmt;
00632 
00633         if (qof_error_check (session))
00634         {
00635                 fmt = "%s: %s\n";
00636                 qof_main_wrap_line (stderr, ERR_INDENT, fmt, PACKAGE,
00637                         qof_error_get_message (session));
00638         }
00639 }
00640 
00643 /*==================== END OF FILE ======================*/

Generated on Mon Jun 4 11:24:16 2007 for gpe-expenses by  doxygen 1.5.2