QOF  0.8.7
qof-gda.c
Go to the documentation of this file.
1 /********************************************************************
2  * qof-gda.c
3  *
4  * Sat Sep 9 13:11:17 2006
5  * Copyright 2006-2008 Neil Williams
6  * linux@codehelp.co.uk
7  ********************************************************************/
8 /*
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22  */
23 
24 #include "config.h"
25 #include <glib.h>
26 #include <glib/gstdio.h>
27 #include <libintl.h>
28 #include <libgda/libgda.h>
29 #include "qof.h"
30 #include "qof-gda.h"
31 #include "qofsql-p.h"
32 
33 #define _(String) dgettext (GETTEXT_PACKAGE, String)
34 #define ACCESS_METHOD "gda"
35 #define LIBGDA_DIR ".qofgda"
36 #define GDA_DBNAME "gda-database-name"
37 #define GDA_USERNAME "gda-username"
38 #define GDA_PASSWORD "gda-password"
39 #define GDA_DATASOURCE "qof-gda-source"
40 
42 #define ONLY_DEBUG 1
43 
49 static QofLogModule log_module = QOF_MOD_GDA;
50 
51 typedef struct
52 {
53  QofBackend be;
54  GdaClient * client_pool;
55  GdaConnection * connection;
56  GdaCommand * command;
57  GValue * gda_value;
58  /* GdaTransaction is now just a string label */
59  gchar * undo_trans, * commit_trans;
60  GError * gda_err;
61  GList * entities;
62  gint dbversion;
63  gint create_handler;
64  gint delete_handler;
65  const gchar *fullpath;
66  const gchar * table_name; /* revised each iteration. */
67  /* QofBackendOption settings: */
68  gchar * data_source_name;
69  gchar * provider_name;
70  gchar * database_name;
71  gchar * source_description;
72  gchar * username;
73  gchar * password;
74  gchar * gdahome;
75  /* end QofBackendOption */
76  gchar *err;
77  gchar *sql_str;
79  GList *dirty_list;
81  gboolean exists;
82  gboolean error;
83  QofIdType e_type;
84  QofBook * book;
85  QofErrorId err_delete, err_insert, err_update, err_create;
86 } QGdaBackend;
87 
88 static gboolean
89 qgda_determine_file_type (const gchar * path)
90 {
91  if (!path)
92  return FALSE;
93  /* accept all requests for the gda: access_method */
94  return TRUE;
95 }
96 
97 static void
98 qgda_modify (QofBackend *be, QofInstance *inst)
99 {
100  QGdaBackend *qgda_be;
101 
102  qgda_be = (QGdaBackend *) be;
103  if (!inst)
104  return;
105  if (!inst->param)
106  return;
107 // if (loading)
108 // return;
109  if (!inst->param->param_setfcn)
110  return;
111  qgda_be->gda_err = NULL;
112  ENTER (" modified %s param:%s", ((QofEntity *) inst)->e_type, inst->param->param_name);
113  qgda_be->sql_str = qof_sql_entity_update ((QofEntity*)inst);
114  if (!qgda_be->sql_str)
115  {
116  LEAVE (" null string");
117  return;
118  }
119  DEBUG (" sql_str=%s", qgda_be->sql_str);
120  qgda_be->command = gda_command_new (qgda_be->sql_str, GDA_COMMAND_TYPE_SQL,
121  GDA_COMMAND_OPTION_STOP_ON_ERRORS);
122  gda_connection_execute_non_select_command (qgda_be->connection,
123  qgda_be->command, NULL, &qgda_be->gda_err);
124  if (qgda_be->gda_err)
125  {
126  qof_error_set_be (be, qgda_be->err_update);
127  qgda_be->error = TRUE;
128  PERR (" error on modify:%s", qgda_be->err);
129  LEAVE (" ");
130  g_error_free (qgda_be->gda_err);
131  qgda_be->gda_err = NULL;
132  return;
133  }
134  inst->dirty = FALSE;
135  g_free (qgda_be->sql_str);
136  qgda_be->error = FALSE;
137  LEAVE (" ");
138 }
139 
140 static void
141 create_tables (QofObject * obj, gpointer user_data)
142 {
143  QGdaBackend * qgda_be;
144  QofBackend * be;
145 // GdaParameterList * plist;
146  gchar * str;
147 
148  qgda_be = (QGdaBackend*)user_data;
149  be = (QofBackend*)qgda_be;
150  if (!gda_connection_is_opened (qgda_be->connection))
151  {
152  qof_error_set_be (be, qof_error_register
153  (_("GDA: No connection available."), FALSE));
154  qgda_be->error = TRUE;
155  PERR (" no connection to gda available");
156  return;
157  }
158  qgda_be->gda_err = NULL;
159  str = qof_sql_object_create_table (obj);
160  qgda_be->command = gda_command_new (str, GDA_COMMAND_TYPE_SQL,
161  GDA_COMMAND_OPTION_STOP_ON_ERRORS);
162  gda_connection_execute_non_select_command (qgda_be->connection,
163  qgda_be->command, NULL, &qgda_be->gda_err);
164  if (qgda_be->gda_err)
165  {
166  gchar * msg;
167 
168  /* Translators: the string is the error message from GDA */
169  msg = g_strdup_printf (_("GDA: Error: %s"), qgda_be->gda_err->message);
170  qof_error_set_be (be, qof_error_register (msg, FALSE));
171  qgda_be->error = TRUE;
172  g_error_free (qgda_be->gda_err);
173  g_free (msg);
174  }
176 // g_free (plist);
177  gda_command_free (qgda_be->command);
178 }
179 
180 static gboolean
181 create_data_source (QGdaBackend * qgda_be)
182 {
183  gchar * cnc_string, * msg;
184  QofBackend * be;
185  GdaProviderInfo * prov;
186 
187  ENTER (" ");
188  be = (QofBackend*)qgda_be;
189  if (!qgda_be->data_source_name)
190  {
191  qof_error_set_be (be, qof_error_register
192  (_("GDA: Missing data source name."), FALSE));
193  LEAVE (" empty data source name");
194  return FALSE;
195  }
196  qgda_be->gda_err = NULL;
197  prov = gda_config_get_provider_by_name (qgda_be->provider_name);
198  if (!prov)
199  {
200  /* Translators: The string is the GDA provider name. */
201  msg = g_strdup_printf (_("GDA Provider '%s' could not be found"),
202  qgda_be->provider_name);
203  qof_error_set_be (be, qof_error_register(msg, FALSE));
204  g_free (msg);
205  LEAVE (" provider '%s' not found", qgda_be->provider_name);
206  return FALSE;
207  }
208  cnc_string = g_strconcat ("DB_DIR=", qgda_be->gdahome, ";DB_NAME=",
209  qgda_be->database_name, NULL);
210  /* creates db within source if db does not exist */
211  {
212  GdaServerOperation * prepare;
213  gboolean modify_global_config, save_data_source, test;
214  prepare = gda_client_prepare_create_database (qgda_be->client_pool,
215  qgda_be->data_source_name, qgda_be->provider_name);
216  test = gda_client_perform_create_database (qgda_be->client_pool, prepare, NULL);
217  if (test)
218  PINFO ("performed creation of new database ok");
219  else
220  PERR ("creation of new database failed");
221  modify_global_config = gda_config_can_modify_global_config ();
222  /* only the root user can modify global config in GDA - find out */
223  gda_config_has_section ("/apps/libgda/Datasources/QOF_DEBUG");
224  modify_global_config = gda_config_can_modify_global_config ();
225  save_data_source = gda_config_save_data_source (qgda_be->data_source_name,
226  qgda_be->provider_name, cnc_string,
227  qgda_be->source_description, qgda_be->username,
228  qgda_be->password, modify_global_config);
229  g_return_val_if_fail (save_data_source, FALSE);
230  }
231  qgda_be->connection = gda_client_open_connection
232  (qgda_be->client_pool, qgda_be->data_source_name,
233  NULL, NULL, GDA_CONNECTION_OPTIONS_NONE, &qgda_be->gda_err);
234  if (!qgda_be->connection)
235  {
236  gchar * msg;
237  /* Translators: First string is the data source name,
238  second string is the message from GDA. */
239  msg = g_strdup_printf
240  (_("GDA: Failed to connect to the data source '%s'. "
241  "The GDA error was '%s'."), qgda_be->data_source_name,
242  qgda_be->gda_err->message);
243  qof_error_set_be (be, qof_error_register (msg, FALSE));
244  g_free (msg);
245  qgda_be->error = TRUE;
246 #ifdef ONLY_DEBUG
247  PERR ("connect request failed, removing %s", qgda_be->data_source_name);
248  g_message ("connect request failed, removing %s", qgda_be->data_source_name);
249  gda_config_remove_data_source (qgda_be->data_source_name);
250 #endif
251  g_error_free (qgda_be->gda_err);
252  return FALSE;
253  }
254  /* create tables per QofObject */
255  qof_object_foreach_type (create_tables, qgda_be);
256  /* gda_connection_create_table (don't log password) */
257  LEAVE (" created data source for %s, %s, %s, %s",
258  qgda_be->data_source_name,
259  qgda_be->provider_name, cnc_string,
260  qgda_be->username);
261  return TRUE;
262 }
263 
264 static void
266  gchar *book_path, gboolean ignore_lock,
267  gboolean create_if_nonexistent)
268 {
269  QGdaBackend *qgda_be;
270  GdaDataSourceInfo * source;
271  gboolean created;
272 
273  /* cannot use ignore_lock */
274  PINFO (" gda session start");
275  qgda_be = (QGdaBackend*)be;
276  be->fullpath = g_strdup (book_path);
277  qgda_be->gda_err = NULL;
278  if(book_path == NULL)
279  {
280  qof_error_set_be (be, qof_error_register
281  (_("GDA: No data source path specified."), FALSE));
282  qgda_be->error = TRUE;
283  LEAVE (" bad URL");
284  return;
285  }
286  /* check/create the ~/.libgda location. */
287  {
288  struct stat lg;
289  gint ret;
290 
291  ret = g_stat (g_get_home_dir(), &lg);
292  if (ret)
293  {
294  qof_error_set_be (be, qof_error_register
295  (_("GDA: Unable to locate your home directory."),
296  FALSE));
297  qgda_be->error = TRUE;
298  LEAVE (" unable to use stat on home_dir.");
299  return;
300  }
301  qgda_be->gdahome = g_strconcat (g_get_home_dir(), "/", LIBGDA_DIR, NULL);
302  if (!S_ISDIR (lg.st_mode) || lg.st_size == 0)
303  ret = g_mkdir_with_parents (qgda_be->gdahome, 0700);
304  if (ret)
305  {
306  qof_error_set_be (be, qof_error_register
307  (_("GDA: Unable to create a .libgda directory "
308  "within your home directory."), FALSE));
309  qgda_be->error = TRUE;
310  LEAVE (" unable to create '%s' 0700", qgda_be->gdahome);
311  return;
312  }
313  }
314  if (qgda_be->data_source_name)
315  {
316  /* check data source */
317  qgda_be->book = qof_session_get_book (session);
318  PINFO ("name=%s", qgda_be->data_source_name);
319  PINFO ("provider=%s", qgda_be->provider_name);
320  created = FALSE;
321  source = gda_config_find_data_source
322  (qgda_be->data_source_name);
323  if (!source && create_if_nonexistent)
324  {
325  DEBUG (" no source, creating . . .");
326  created = create_data_source (qgda_be);
327  }
328  if (!source && !created)
329  {
330  qof_error_set_be (be, qof_error_register
331  (_("GDA: No data source found at '%s' - Try loading data "
332  "from another file and write to gda: again to create the "
333  "GDA data source."), TRUE));
334  DEBUG (" no source but set not to create.");
335  qgda_be->error = TRUE;
336  return;
337  }
338  }
339  PINFO (" trying for a connection");
340  /* use the username and password that created the source */
341  qgda_be->connection = gda_client_open_connection
342  (qgda_be->client_pool, qgda_be->data_source_name,
343  NULL, NULL, GDA_CONNECTION_OPTIONS_DONT_SHARE, &qgda_be->gda_err);
344  if (qgda_be->connection)
345  {
346  PINFO (" appear to be connected.");
347  /* create tables per QofObject */
348  qof_object_foreach_type (create_tables, qgda_be);
349  }
350  else
351  {
352  gchar * msg;
353 
354  msg = g_strdup_printf (
355  _("GDA encountered an error '%s' using data source '%s'."),
356  qgda_be->gda_err->message, qgda_be->data_source_name);
357  qof_error_set_be (be, qof_error_register (msg, FALSE));
358  PERR (" failed to connect to GDA: '%s'", msg);
359  qgda_be->error = TRUE;
360  g_message (msg);
361  g_free (msg);
362  g_error_free (qgda_be->gda_err);
363 #ifdef ONLY_DEBUG
364  PERR ("connect request failed, removing %s", qgda_be->data_source_name);
366  g_message ("connect request failed, removing %s", qgda_be->data_source_name);
367  gda_config_remove_data_source (qgda_be->data_source_name);
368 #endif
369  }
370 }
371 
372 static void
373 load_entities (gpointer value, gpointer user_data)
374 {
375  gint column_id, row_id;
376  GdaDataModel * dm;
377  QGdaBackend * qgda_be;
378 
379  qgda_be = (QGdaBackend*)user_data;
380  dm = (GdaDataModel*)value;
381  if (!dm)
382  {
383  qgda_be->error = TRUE;
384  DEBUG (" empty data model on load");
385  return;
386  }
387  for (column_id = 0; column_id < gda_data_model_get_n_columns (dm);
388  column_id++)
389  g_print("%s\t", gda_data_model_get_column_title (dm, column_id));
390  g_print("\n");
391  for (row_id = 0; row_id < gda_data_model_get_n_rows (dm); row_id++) {
392  for (column_id = 0; column_id < gda_data_model_get_n_columns (dm);
393  column_id++)
394  {
395  gchar *str;
396 
397  qgda_be->gda_value = (GValue*)gda_data_model_get_value_at
398  (dm, column_id, row_id);
399  str = gda_value_stringify (qgda_be->gda_value);
400  g_print ("%s\t", str);
401  g_free (str);
402  }
403  g_print("\n");
404  }
405  g_object_unref(dm);
406 }
407 
408 static void
409 qgda_class_foreach (QofObject * obj, gpointer data)
410 {
411  QGdaBackend *qgda_be;
412 
413  qgda_be = (QGdaBackend*)data;
414  qgda_be->gda_err = NULL;
415  qgda_be->sql_str = g_strdup_printf("SELECT * FROM %s;", obj->e_type);
416  PINFO (" sql=%s", qgda_be->sql_str);
417  qgda_be->command = gda_command_new (qgda_be->sql_str,
418  GDA_COMMAND_TYPE_SQL, GDA_COMMAND_OPTION_STOP_ON_ERRORS);
419  qgda_be->entities = gda_connection_execute_command (qgda_be->connection,
420  qgda_be->command, NULL, &qgda_be->gda_err);
421  if (qgda_be->gda_err)
422  g_error_free (qgda_be->gda_err);
423  g_list_foreach (qgda_be->entities, load_entities, qgda_be);
424  gda_command_free (qgda_be->command);
425 }
426 
427 static void
428 qgda_db_load (QofBackend *be, QofBook *book)
429 {
430  QGdaBackend *qgda_be;
431 
432  qgda_be = (QGdaBackend*)be;
433  if (qgda_be->error)
434  return;
435  /* select all */
436  qgda_be->book = book;
437  qof_object_foreach_type(qgda_class_foreach, qgda_be);
438 }
439 
440 static void
441 qgda_check_entity (QofEntity * ent, gpointer data)
442 {
443  QofInstance *inst;
444  QGdaBackend * qgda_be;
445  gchar * gstr;
446 
447  qgda_be = (QGdaBackend*) data;
448  inst = (QofInstance *) ent;
449  if (!inst->dirty)
450  return;
451  /* check if this entity already exists */
452  gstr = g_strnfill (GUID_ENCODING_LENGTH + 1, ' ');
454  qgda_be->sql_str = g_strdup_printf
455  ("SELECT * FROM %s where guid = \"%s\";", ent->e_type, gstr);
456  qgda_be->dirty_list = NULL;
457  /* assume entity does not yet exist in backend,
458  e.g. being copied from another session. */
459  qgda_be->exists = FALSE;
460 }
461 
462 static void
463 qgda_write_foreach (QofObject * obj, gpointer data)
464 {
465  QGdaBackend *qgda_be;
466 
467  qgda_be = (QGdaBackend*)data;
468  qgda_be->gda_err = NULL;
469  if (!qof_book_not_saved (qgda_be->book))
470  return;
471  qof_object_foreach (obj->e_type, qgda_be->book, qgda_check_entity, &qgda_be);
472 }
473 
474 static void
475 qgda_write_db (QofBackend *be, QofBook *book)
476 {
477  QGdaBackend *qgda_be;
478 
479  g_return_if_fail (be);
480  qgda_be = (QGdaBackend *) be;
481  qgda_be->book = book;
482  /* update each record with current state */
483  qof_object_foreach_type (qgda_write_foreach, qgda_be);
484 }
485 
486 static void
487 qgda_session_end (QofBackend *be)
488 {
489  QGdaBackend *qgda_be;
490 
491  qgda_be = (QGdaBackend*)be;
492  if (qgda_be)
493  {
494  /* only remove data_source whilst debugging! */
495  PINFO ("removing %s", qgda_be->data_source_name);
496  gda_config_remove_data_source (qgda_be->data_source_name);
497  gda_client_close_all_connections (qgda_be->client_pool);
498  g_object_unref(G_OBJECT(qgda_be->client_pool));
499  }
500 }
501 
502 static void
503 qgda_destroy_backend (QofBackend *be)
504 {
505  QGdaBackend *qgda_be;
506 
507  qgda_be = (QGdaBackend*)be;
508  qof_event_unregister_handler (qgda_be->create_handler);
509  qof_event_unregister_handler (qgda_be->delete_handler);
510  g_free (be);
511  g_free (qgda_be);
512 }
513 
514 static void
515 option_cb (QofBackendOption * option, gpointer data)
516 {
517  QGdaBackend * qgda_be;
518 
519  qgda_be = (QGdaBackend *) data;
520  g_return_if_fail (qgda_be);
521  if (0 == safe_strcmp (GDA_DBNAME, option->option_name))
522  {
523  qgda_be->database_name = g_strdup (option->value);
524  PINFO (" database name = %s", qgda_be->database_name);
525  }
526  if (0 == safe_strcmp (GDA_USERNAME, option->option_name))
527  {
528  qgda_be->username = g_strdup (option->value);
529  PINFO (" username=%s", qgda_be->username);
530  }
531  if (0 == safe_strcmp (GDA_PASSWORD, option->option_name))
532  {
533  /* don't log the password! :-) */
534  qgda_be->password = g_strdup (option->value);
535  }
536  if (0 == safe_strcmp (GDA_DATASOURCE, option->option_name))
537  {
538  qgda_be->data_source_name = g_strdup (option->value);
539  }
540 }
541 
542 static void
543 load_config (QofBackend * be, KvpFrame * config)
544 {
545  QGdaBackend *qgda_be;
546 
547  ENTER (" ");
548  qgda_be = (QGdaBackend *) be;
549  g_return_if_fail (qgda_be);
550  qof_backend_option_foreach (config, option_cb, qgda_be);
551  LEAVE (" ");
552 }
553 
554 static KvpFrame *
555 get_config (QofBackend * be)
556 {
557  QofBackendOption *option;
558  QGdaBackend *qgda_be;
559 
560  if (!be)
561  return NULL;
562  ENTER (" ");
563  qgda_be = (QGdaBackend *) be;
564  g_return_val_if_fail (qgda_be, NULL);
566  option = g_new0 (QofBackendOption, 1);
567  option->option_name = GDA_DBNAME;
568  option->description =
569  _("Name of the database to use.");
570  option->tooltip =
571  _("Override the default database name with "
572  "a name of your own choice.");
573  option->type = KVP_TYPE_STRING;
574  option->value = (gpointer) qgda_be->database_name;
575  qof_backend_prepare_option (be, option);
576  g_free (option);
577  option = g_new0 (QofBackendOption, 1);
578  option->option_name = GDA_USERNAME;
579  option->description =
580  _("The username to use to access this data source.");
581  option->tooltip =
582  _("The username specified in the configuration of this "
583  "data source that provides write access to the data.");
584  option->type = KVP_TYPE_STRING;
585  option->value = (gpointer) qgda_be->username;
586  qof_backend_prepare_option (be, option);
587  g_free (option);
588  option = g_new0 (QofBackendOption, 1);
589  option->option_name = GDA_PASSWORD;
590  option->description =
591  _("Password to use with the username.");
592  option->tooltip =
593  _("The password that is to be used with the specified "
594  "username.");
595  option->type = KVP_TYPE_STRING;
596  option->value = (gpointer) qgda_be->password;
597  qof_backend_prepare_option (be, option);
598  g_free (option);
599  option = g_new0 (QofBackendOption, 1);
600  option->option_name = GDA_DATASOURCE;
601  option->description =
602  _("Name of this data source.");
603  option->tooltip =
604  _("The name of this data source as specified "
605  "in the GDA configuration.");
606  option->type = KVP_TYPE_STRING;
607  option->value = (gpointer) qgda_be->password;
608  qof_backend_prepare_option (be, option);
609  g_free (option);
610  LEAVE (" ");
611  return qof_backend_complete_frame (be);
612 }
613 
614 static QofBackend *
615 qgda_backend_new (void)
616 {
617  QGdaBackend *qgda_be;
618  QofBackend *be;
619 
620  ENTER (" ");
621  qgda_be = g_new0(QGdaBackend, 1);
622  be = (QofBackend*) qgda_be;
623  qof_backend_init(be);
624  gda_init (PACKAGE, "0.1", 0, NULL);
625  qgda_be->client_pool = gda_client_new ();
626  qgda_be->dbversion = QOF_OBJECT_VERSION;
627  qgda_be->err_delete =
628  qof_error_register (_("Unable to delete record."), FALSE);
629  qgda_be->err_create =
630  qof_error_register (_("Unable to create record."), FALSE);
631  qgda_be->err_insert =
632  qof_error_register (_("Unable to insert a new record."), FALSE);
633  qgda_be->err_update =
634  qof_error_register (_("Unable to update existing record."), FALSE);
635  be->session_begin = qgda_session_begin;
636 
637  be->session_end = qgda_session_end;
638  be->destroy_backend = qgda_destroy_backend;
639  be->load = qgda_db_load;
640  be->save_may_clobber_data = NULL;
641  be->begin = NULL;
642  /* commit: write to gda, commit undo record. */
643  be->commit = qgda_modify;
644  be->rollback = NULL;
645  /* would need a QofQuery back to QofSqlQuery conversion. */
646  be->compile_query = NULL;
647  /* unused */
648  be->free_query = NULL;
649  be->run_query = NULL;
650  be->counter = NULL;
651  /* The QOF GDA backend might be multi-user */
652  be->events_pending = NULL;
653  be->process_events = NULL;
654 
655  be->sync = qgda_write_db;
656  be->load_config = load_config;
657  be->get_config = get_config;
658  LEAVE (" ");
659 
660 #ifdef ONLY_DEBUG
661  qgda_be->data_source_name = "QOF_DEBUG";
662  qgda_be->database_name = "DB_DIR=/home/neil/";
663  qgda_be->provider_name = "SQLite";
664  qgda_be->source_description = "QOF GDA debug data";
665 #endif
666  return be;
667 }
668 
669 static void
670 qgda_provider_free (QofBackendProvider *prov)
671 {
672  prov->provider_name = NULL;
673  prov->access_method = NULL;
674  g_free (prov);
675 }
676 
678 {
679  QofBackendProvider *prov;
680 
681  bindtextdomain (PACKAGE, LOCALE_DIR);
682  prov = g_new0 (QofBackendProvider, 1);
683  prov->provider_name = "QOF GDA Backend Version 0.1";
684  prov->access_method = ACCESS_METHOD;
685  prov->partial_book_supported = TRUE;
686  prov->backend_new = qgda_backend_new;
687  prov->check_data_type = qgda_determine_file_type;
688  prov->provider_free = qgda_provider_free;
690 }
QofErrorId qof_error_register(const gchar *err_message, gboolean use_file)
Generate and register a new error.
Definition: qoferror.c:73
gchar * fullpath
Definition: qofbackend-p.h:332
gboolean(* save_may_clobber_data)(QofBackend *)
Definition: qofbackend-p.h:320
#define PERR(format, args...)
Definition: qoflog.h:183
const gchar * QofIdType
Definition: qofid.h:81
#define PINFO(format, args...)
Definition: qoflog.h:199
void qof_backend_register_provider(QofBackendProvider *)
Definition: qofsession.c:59
#define QOF_OBJECT_VERSION
Definition: qofobject.h:57
void qof_object_foreach(QofIdTypeConst type_name, QofBook *book, QofEntityForeachCB cb, gpointer user_data)
Definition: qofobject.c:174
const gchar * description
Definition: qofbackend.h:119
gboolean partial_book_supported
Partial QofBook handler.
Definition: qofbackend-p.h:254
gint32 QofErrorId
The ID of this error.
Definition: qofbackend.h:54
gchar * qof_sql_object_create_table(QofObject *obj)
Build a SQL &#39;CREATE&#39; statement for this object.
Definition: qofsql.c:1346
struct _KvpFrame KvpFrame
Definition: kvpframe.h:74
KvpFrame * qof_backend_complete_frame(QofBackend *be)
Definition: qofbackend.c:183
#define LEAVE(format, args...)
Definition: qoflog.h:227
#define GUID_ENCODING_LENGTH
Definition: guid.h:64
gchar * qof_sql_entity_update(QofEntity *ent)
Build a SQL &#39;UPDATE&#39; statement for the current entity parameter.
Definition: qofsql.c:1460
gboolean qof_book_not_saved(QofBook *book)
Definition: qofbook.c:135
void qof_backend_prepare_option(QofBackend *be, QofBackendOption *option)
Definition: qofbackend.c:101
void qof_backend_option_foreach(KvpFrame *config, QofBackendOptionCB cb, gpointer data)
Definition: qofbackend.c:349
void(* provider_free)(QofBackendProvider *)
Definition: qofbackend-p.h:280
#define DEBUG(format, args...)
Definition: qoflog.h:208
QofBackend *(* backend_new)(void)
Definition: qofbackend-p.h:260
const gchar * option_name
Definition: qofbackend.h:118
void qof_event_unregister_handler(gint handler_id)
Unregister an event handler.
Definition: qofevent.c:103
gchar * guid_to_string_buff(const GUID *guid, gchar *buff)
void qof_sql_entity_set_kvp_exists(gboolean exist)
Set or clear a flag that the KVP table exists or not.
Definition: qofsql.c:1574
Private QOF SQL generation routines.
const gchar * access_method
Definition: qofbackend-p.h:247
static void qgda_session_begin(QofBackend *be, QofSession *session, const gchar *book_path, gboolean ignore_lock, gboolean create_if_nonexistent)
Definition: qof-gda.c:265
gboolean(* check_data_type)(const gchar *)
Distinguish two providers with same access method.
Definition: qofbackend-p.h:277
const GUID * qof_entity_get_guid(QofEntity *ent)
Definition: qofid.c:105
const gchar * tooltip
Definition: qofbackend.h:120
standard C string
Definition: kvpframe.h:112
gint safe_strcmp(const gchar *da, const gchar *db)
Definition: qofutil.c:75
const QofParam * param
Definition: qofinstance-p.h:53
const gchar * provider_name
Definition: qofbackend-p.h:241
void qof_gda_provider_init(void)
Initialises the libgda2 QOF backend.
Definition: qof-gda.c:677
#define ENTER(format, args...)
Definition: qoflog.h:217
void qof_object_foreach_type(QofForeachTypeCB cb, gpointer user_data)
Definition: qofobject.c:140
KvpValueType type
Definition: qofbackend.h:116
const gchar * QofLogModule
Definition: qofid.h:85
Public interface of qof-backend-gda.
void qof_backend_prepare_frame(QofBackend *be)
Definition: qofbackend.c:89