GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
test-backend-dbi-basic.c
1 /*
2  * utest-backend-dbi-basic.c
3  *
4  * Created on: 2011-04-23
5  * Author: phil
6  */
7 
8 #include "config.h"
9 
10 #include <sys/types.h>
11 #include <unistd.h>
12 #include <glib/gstdio.h>
13 
14 #include <qof.h>
15 #include <unittest-support.h>
16 #include <test-stuff.h>
17 #include <test-dbi-stuff.h>
18 #include <test-dbi-business-stuff.h>
19 /* For cleaning up the database */
20 #include <dbi/dbi.h>
21 #include <gnc-uri-utils.h>
22 /* For setup_business */
23 #include "Account.h"
24 #include <TransLog.h>
25 #include "Transaction.h"
26 #include "Split.h"
27 #include "gnc-commodity.h"
28 #include "gncAddress.h"
29 #include "gncCustomer.h"
30 #include "gncInvoice.h"
31 /* For test_conn_index_functions */
32 #include "../gnc-backend-dbi-priv.h"
33 /* For version_control */
34 #include <gnc-prefs.h>
35 #include <qofsession-p.h>
36 
37 #if LIBDBI_VERSION >= 900
38 #define HAVE_LIBDBI_R 1
39 static dbi_inst dbi_instance = NULL;
40 #else
41 #define HAVE_LIBDBI_R 0
42 #endif
43 
44 static const gchar* suitename = "/backend/dbi";
45 void test_suite_gnc_backend_dbi (void);
46 
47 typedef struct
48 {
49  QofSession *session;
50  gchar *filename;
51  GSList *hdlrs;
52 } Fixture;
53 
54 static void
55 setup (Fixture *fixture, gconstpointer pData)
56 {
57  gchar *url = (gchar *)pData;
58  fixture->session = qof_session_new();
59  /* When running distcheck the source directory is read-only, which
60  * prevents creating the lock file. Force the session to get
61  * around that.
62  */
63  qof_session_begin (fixture->session, DBI_TEST_XML_FILENAME, TRUE,
64  FALSE, TRUE);
65  g_assert_cmpint (qof_session_get_error (fixture->session), ==,
66  ERR_BACKEND_NO_ERR);
67  qof_session_load (fixture->session, NULL);
68 
69  if (g_strcmp0 (url, "sqlite3") == 0)
70  fixture->filename = g_strdup_printf ("/tmp/test-sqlite-%d", getpid());
71  else
72  fixture->filename = NULL;
73 }
74 
75 static void
76 setup_memory (Fixture *fixture, gconstpointer pData)
77 {
78  QofSession* session = qof_session_new();
79  gchar *url = (gchar*)pData;
80  QofBook* book;
81  Account *root, *acct1, *acct2;
82  KvpFrame* frame;
83  Transaction* tx;
84  Split *spl1, *spl2;
86  gnc_commodity* currency;
87 
88  session = qof_session_new();
89  book = qof_session_get_book (session);
90  root = gnc_book_get_root_account (book);
91 
92  table = gnc_commodity_table_get_table (book);
93  currency = gnc_commodity_table_lookup (table, GNC_COMMODITY_NS_CURRENCY, "CAD");
94 
95  acct1 = xaccMallocAccount (book);
97  xaccAccountSetName (acct1, "Bank 1");
98  xaccAccountSetCommodity (acct1, currency);
99 
100  frame = qof_instance_get_slots (QOF_INSTANCE(acct1));
101  kvp_frame_set_gint64 (frame, "int64-val", 100);
102  kvp_frame_set_double (frame, "double-val", 3.14159);
103  kvp_frame_set_numeric (frame, "numeric-val", gnc_numeric_zero());
104 
105  kvp_frame_set_timespec (frame, "timespec-val", timespec_now ());
106 
107  kvp_frame_set_string (frame, "string-val", "abcdefghijklmnop");
108  kvp_frame_set_guid (frame, "guid-val", qof_instance_get_guid (QOF_INSTANCE(acct1)));
109 
110  gnc_account_append_child (root, acct1);
111 
112  acct2 = xaccMallocAccount (book);
114  xaccAccountSetName (acct2, "Bank 1");
115 
116  tx = xaccMallocTransaction (book);
117  xaccTransBeginEdit (tx);
118  xaccTransSetCurrency (tx, currency);
119  spl1 = xaccMallocSplit (book);
120  xaccTransAppendSplit (tx, spl1);
121  spl2 = xaccMallocSplit (book);
122  xaccTransAppendSplit (tx, spl2);
123  xaccTransCommitEdit (tx);
124 
125  fixture->session = session;
126  if (g_strcmp0 (url, "sqlite3") == 0)
127  fixture->filename = g_strdup_printf ("/tmp/test-sqlite-%d", getpid());
128  else
129  fixture->filename = NULL;
130 }
131 
132 static void
133 setup_business (Fixture *fixture, gconstpointer pData)
134 {
135  QofSession* session = qof_session_new();
136  gchar *url = (gchar*)pData;
137  QofBook* book = qof_session_get_book (session);
138  Account* root = gnc_book_get_root_account (book);
139  Account* acct1;
140  Account* acct2;
141  gnc_commodity_table* table;
142  gnc_commodity* currency;
143  GncAddress* addr;
144  GncCustomer* cust;
145  GncEmployee* emp;
146  GncTaxTable* tt;
147  GncTaxTableEntry* tte;
148 
149  table = gnc_commodity_table_get_table (book);
150  currency = gnc_commodity_table_lookup (table, GNC_COMMODITY_NS_CURRENCY, "CAD");
151 
152  acct1 = xaccMallocAccount (book);
154  xaccAccountSetName (acct1, "Bank 1");
155  xaccAccountSetCommodity (acct1, currency);
156  xaccAccountSetHidden (acct1, FALSE);
157  xaccAccountSetPlaceholder (acct1, FALSE);
158  gnc_account_append_child (root, acct1);
159 
160  acct2 = xaccMallocAccount (book);
162  xaccAccountSetName (acct2, "Bank 2");
163  xaccAccountSetCommodity (acct2, currency);
164  xaccAccountSetHidden (acct2, FALSE);
165  xaccAccountSetPlaceholder (acct2, FALSE);
166  gnc_account_append_child (root, acct2);
167 
168  tt = gncTaxTableCreate (book);
169  gncTaxTableSetName (tt, "tt");
170  tte = gncTaxTableEntryCreate();
171  gncTaxTableEntrySetAccount (tte, acct1);
172  gncTaxTableEntrySetType (tte, GNC_AMT_TYPE_VALUE);
173  gncTaxTableEntrySetAmount (tte, gnc_numeric_zero());
174  gncTaxTableAddEntry (tt, tte);
175  tte = gncTaxTableEntryCreate();
176  gncTaxTableEntrySetAccount (tte, acct2);
177  gncTaxTableEntrySetType (tte, GNC_AMT_TYPE_PERCENT);
178  gncTaxTableEntrySetAmount (tte, gnc_numeric_zero());
179  gncTaxTableAddEntry (tt, tte);
180 
181  cust = gncCustomerCreate (book);
182  gncCustomerSetID (cust, "0001");
183  gncCustomerSetName (cust, "MyCustomer");
184  gncCustomerSetNotes (cust, "Here are some notes");
185  gncCustomerSetCurrency (cust, currency);
186  addr = gncAddressCreate (book, QOF_INSTANCE(cust));
187  gncAddressSetName (addr, "theAddress");
188  gncAddressSetAddr1 (addr, "Address line #1");
189  gncAddressSetAddr2 (addr, "Address line #2");
190  gncAddressSetAddr3 (addr, "Address line #3");
191  gncAddressSetAddr4 (addr, "Address line #4");
192  gncAddressSetPhone (addr, "(123) 555-1212");
193  gncAddressSetPhone (addr, "(123) 555-2121");
194  gncAddressSetEmail (addr, "[email protected]");
195 
196  emp = gncEmployeeCreate (book);
197  gncEmployeeSetID (emp, "0001");
198  gncEmployeeSetUsername (emp, "gnucash");
199  gncEmployeeSetLanguage (emp, "english");
200  gncEmployeeSetCurrency (emp, currency);
201 
202  fixture->session = session;
203  if (g_strcmp0 (url, "sqlite3") == 0)
204  fixture->filename = g_strdup_printf ("/tmp/test-sqlite-%d", getpid());
205  else
206  fixture->filename = NULL;
207 }
208 
209 static void
210 drop_table (gconstpointer tdata, gconstpointer cdata)
211 {
212  gchar *table = (gchar*)tdata;
213  dbi_conn conn = (dbi_conn)cdata;
214  gchar *query = g_strdup_printf ("DROP TABLE %s", table);
215  dbi_result rslt = dbi_conn_query (conn, query);
216  g_free (query);
217 }
218 
219 static void
220 destroy_database (gchar* url)
221 {
222  gchar *protocol = NULL;
223  gchar *host = NULL;
224  gchar *dbname = NULL;
225  gchar *username = NULL;
226  gchar *password = NULL;
227  gchar *basename = NULL;
228  gint portnum = 0;
229  gchar *port = NULL;
230  gchar *pgsql = "pgsql";
231  dbi_conn conn = NULL;
232  gchar *errfmt = "Unable to delete tables in %s: %s";
233  gint fail = 0;
234  dbi_result tables;
235  GSList *list = NULL;
236 
237  gnc_uri_get_components (url, &protocol, &host, &portnum,
238  &username, &password, &dbname);
239  if (g_strcmp0 (protocol, "postgres") == 0)
240  #if HAVE_LIBDBI_R
241  conn = dbi_conn_new_r( pgsql, dbi_instance );
242  #else
243  conn = dbi_conn_new( pgsql );
244  #endif
245  else
246  #if HAVE_LIBDBI_R
247  conn = dbi_conn_new_r (protocol, dbi_instance);
248  #else
249  conn = dbi_conn_new (protocol);
250  #endif
251  port = g_strdup_printf ("%d", portnum);
252  if (conn == NULL)
253  {
254  g_printf (errfmt, url, "failed to create connection");
255  return;
256  }
257  fail = dbi_conn_set_option (conn, "host", host);
258  if (!fail && portnum)
259  fail = dbi_conn_set_option (conn, "port", port);
260  if (!fail)
261  fail = dbi_conn_set_option (conn, "dbname", dbname);
262  if (!fail)
263  fail = dbi_conn_set_option (conn, "username", username);
264  if (!fail)
265  fail = dbi_conn_set_option (conn, "password", password);
266  if (!fail)
267  fail = dbi_conn_set_option (conn, "encoding", "UTF-8");
268  g_free (port);
269  if (fail != 0)
270  {
271  g_printf (errfmt, url, "failed to set an option");
272  dbi_conn_close (conn);
273  return;
274  }
275  fail = dbi_conn_connect (conn);
276  if (fail != 0)
277  {
278  const gchar *error;
279  gint errnum = dbi_conn_error (conn, &error);
280  g_printf (errfmt, url, error);
281  dbi_conn_close (conn);
282  return;
283  }
284  tables = dbi_conn_get_table_list (conn, dbname, NULL);
285  while (dbi_result_next_row (tables) != 0)
286  {
287  const gchar *table = dbi_result_get_string_idx (tables, 1);
288  list = g_slist_prepend (list, g_strdup (table));
289  }
290  dbi_result_free (tables);
291  g_slist_foreach (list, (GFunc)drop_table, (gpointer)conn);
292  g_slist_free_full (list, (GDestroyNotify)g_free);
293 }
294 
295 static void
296 teardown (Fixture *fixture, gconstpointer pData)
297 {
298  gchar *lockfile = g_strdup_printf ("%s/test-dbi.xml.LCK",
299  g_path_get_dirname (DBI_TEST_XML_FILENAME));
300  gchar *msg = g_strdup_printf ("[xml_session_end()] Error on g_unlink(%s): 2: No such file or directory", lockfile);
301  gchar *logdomain = "gnc.backend";
302  guint loglevel = G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL;
303  TestErrorStruct *check = test_error_struct_new (logdomain, loglevel, msg);
304  fixture->hdlrs = test_log_set_fatal_handler (fixture->hdlrs, check,
305  (GLogFunc)test_checked_handler);
306  qof_session_end (fixture->session);
307  qof_session_destroy (fixture->session);
308  if (fixture->filename)
309  {
310  g_unlink (fixture->filename);
311  g_free (fixture->filename);
312  }
313  else
314  destroy_database ((gchar*)pData);
315 
316  g_free (msg);
317  g_free (lockfile);
318  g_slist_free_full (fixture->hdlrs, test_free_log_handler);
319  test_clear_error_list();
320 }
321 
322 
323 static void
324 test_conn_index_functions (QofBackend *qbe)
325 {
326  GncDbiBackend *be = (GncDbiBackend*)qbe;
327  GncDbiSqlConnection *conn = (GncDbiSqlConnection*)(be->sql_be.conn);
328  GSList *index_list, *iter;
329 
330  index_list = conn->provider->get_index_list (be->conn);
331  g_test_message ("Returned from index list\n");
332  g_assert (index_list != NULL);
333  g_assert_cmpint (g_slist_length (index_list), ==, 4);
334  for (iter = index_list; iter != NULL; iter = g_slist_next (iter))
335  {
336  const char *errmsg;
337  conn->provider->drop_index (be->conn, iter->data);
338  g_assert (DBI_ERROR_NONE == dbi_conn_error (conn->conn, &errmsg));
339  }
340 
341  g_slist_free (index_list);
342 }
343 
344 /* Given a synthetic session, use the same logic as
345  * QofSession::save_as to save it to a specified sql url, then load it
346  * back and compare. */
347 static void
348 test_dbi_store_and_reload (Fixture *fixture, gconstpointer pData)
349 {
350 
351  const gchar* url = (const gchar*)pData;
352  QofSession* session_2;
353  QofSession* session_3;
354  QofBackend *be;
355 
356  gchar *msg = "[gnc_dbi_unlock()] There was no lock entry in the Lock table";
357  gchar *log_domain = "gnc.backend.dbi";
358  guint loglevel = G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL;
359  TestErrorStruct *check = test_error_struct_new (log_domain, loglevel, msg);
360  fixture->hdlrs = test_log_set_fatal_handler (fixture->hdlrs, check,
361  (GLogFunc)test_checked_handler);
362  if (fixture->filename)
363  url = fixture->filename;
364 
365  // Save the session data
366  session_2 = qof_session_new();
367  qof_session_begin (session_2, url, FALSE, TRUE, TRUE);
368  g_assert (session_2 != NULL);
369  g_assert_cmpint (qof_session_get_error (session_2), ==, ERR_BACKEND_NO_ERR);
370  qof_session_swap_data (fixture->session, session_2);
371  qof_session_save (session_2, NULL);
372  g_assert (session_2 != NULL);
373  g_assert_cmpint (qof_session_get_error (session_2), ==, ERR_BACKEND_NO_ERR);
374 
375  // Reload the session data
376  session_3 = qof_session_new();
377  g_assert (session_3 != NULL);
378  qof_session_begin (session_3, url, TRUE, FALSE, FALSE);
379  g_assert (session_3 != NULL);
380  g_assert_cmpint (qof_session_get_error (session_3), ==, ERR_BACKEND_NO_ERR);
381  qof_session_load (session_3, NULL);
382  g_assert (session_3 != NULL);
383  g_assert_cmpint (qof_session_get_error (session_3), ==, ERR_BACKEND_NO_ERR);
384  // Compare with the original data
385  compare_books (qof_session_get_book (session_2),
386  qof_session_get_book (session_3));
387  /* fixture->session belongs to the fixture and teardown() will clean it up */
388  qof_session_end (session_2);
389  qof_session_destroy (session_2);
390  qof_session_end (session_3);
391  qof_session_destroy (session_3);
392 }
393 
401 static void
402 test_dbi_safe_save (Fixture *fixture, gconstpointer pData)
403 {
404  gchar *url = (gchar*)pData;
405  QofSession *session_1 = NULL, *session_2 = NULL;
406  QofBackend *be;
407 
408  gchar *msg = "[gnc_dbi_unlock()] There was no lock entry in the Lock table";
409  gchar *log_domain = "gnc.backend.dbi";
410  guint loglevel = G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL;
411  TestErrorStruct *check = test_error_struct_new (log_domain, loglevel, msg);
412 
413  if (fixture->filename)
414  url = fixture->filename;
415 
416  // Load the session data
417  session_1 = qof_session_new ();
418  qof_session_begin (session_1, url, FALSE, TRUE, TRUE);
419  if (session_1 &&
420  qof_session_get_error (session_1) != ERR_BACKEND_NO_ERR)
421  {
422  g_warning ("Session Error: %d, %s", qof_session_get_error (session_1),
423  qof_session_get_error_message (session_1));
424  g_test_message ("DB Session Creation Failed");
425  g_assert (FALSE);
426  goto cleanup;
427  }
428  qof_session_swap_data (fixture->session, session_1);
429  qof_session_save (session_1, NULL);
430  /* Do a safe save */
431  qof_session_safe_save (session_1, NULL);
432  if (session_1 && qof_session_get_error(session_1) != ERR_BACKEND_NO_ERR)
433  {
434  g_warning ("Session Error: %s",
435  qof_session_get_error_message(session_1));
436  g_test_message ("DB Session Safe Save Failed");
437  g_assert (FALSE);
438  goto cleanup;
439  }
440  /* Destroy the session and reload it */
441 
442  session_2 = qof_session_new ();
443  qof_session_begin (session_2, url, TRUE, FALSE, FALSE);
444  if (session_2 &&
445  qof_session_get_error (session_2) != ERR_BACKEND_NO_ERR)
446  {
447  g_warning ("Session Error: %d, %s", qof_session_get_error(session_2),
448  qof_session_get_error_message(session_2));
449  g_test_message ("DB Session re-creation Failed");
450  g_assert (FALSE);
451  goto cleanup;
452  }
453  qof_session_load (session_2, NULL);
454  compare_books (qof_session_get_book (session_1),
455  qof_session_get_book (session_2));
456  be = qof_book_get_backend (qof_session_get_book (session_2));
457  test_conn_index_functions (be);
458 
459 cleanup:
460  fixture->hdlrs = test_log_set_fatal_handler (fixture->hdlrs, check,
461  (GLogFunc)test_checked_handler);
462  if (session_2 != NULL)
463  {
464  qof_session_end (session_2);
465  qof_session_destroy (session_2);
466  }
467  if (session_1 != NULL)
468  {
469  qof_session_end (session_1);
470  qof_session_destroy (session_1);
471  }
472  return;
473 }
474 /* Test the gnc_dbi_load logic that forces a newer database to be
475  * opened read-only and an older one to be safe-saved. Again, it would
476  * be better to do this starting from a fresh file, but instead we're
477  * being lazy and using an existing one. */
478 static void
479 test_dbi_version_control (Fixture *fixture, gconstpointer pData)
480 {
481  gchar *url = (gchar*)pData;
482  QofSession *sess;
483  QofBook *book;
484  QofBackend *qbe;
485  QofBackendError err;
486  gint ourversion = gnc_prefs_get_long_version();
487 
488  // Load the session data
489  if (fixture->filename)
490  url = fixture->filename;
491  sess = qof_session_new();
492  qof_session_begin (sess, url, FALSE, TRUE, TRUE);
493  if (sess && qof_session_get_error(sess) != ERR_BACKEND_NO_ERR)
494  {
495  g_warning ("Session Error: %d, %s", qof_session_get_error(sess),
496  qof_session_get_error_message(sess));
497  g_test_message ("DB Session Creation Failed");
498  g_assert (FALSE);
499  goto cleanup;
500  }
501  qof_session_swap_data (fixture->session, sess);
502  qof_session_save (sess, NULL);
503  qbe = qof_session_get_backend (sess);
504  book = qof_session_get_book (sess);
505  qof_book_begin_edit (book);
507  "Gnucash", GNUCASH_RESAVE_VERSION - 1);
508  qof_book_commit_edit (book);
509  qof_session_end (sess);
510  qof_session_destroy (sess);
511  sess = qof_session_new();
512  qof_session_begin (sess, url, TRUE, FALSE, FALSE);
513  qof_session_load (sess, NULL);
514  err = qof_session_pop_error (sess);
515  g_assert_cmpint (err, ==, ERR_SQL_DB_TOO_OLD);
516  qbe = qof_session_get_backend (sess);
517  book = qof_session_get_book (sess);
518  qof_book_begin_edit (book);
520  "Gnucash", ourversion);
522  "Gnucash-Resave", ourversion + 1);
523  qof_book_commit_edit (book);
524  qof_session_end (sess);
525  qof_session_destroy (sess);
526  sess = qof_session_new();
527  qof_session_begin (sess, url, TRUE, FALSE, FALSE);
528  qof_session_load (sess, NULL);
530  err = qof_session_pop_error (sess);
531  g_assert_cmpint (err, ==, ERR_SQL_DB_TOO_NEW);
532 cleanup:
533  qbe = qof_session_get_backend (sess);
534  book = qof_session_get_book (sess);
535  qof_book_begin_edit (book);
537  "Gnucash-Resave", GNUCASH_RESAVE_VERSION);
538  qof_book_commit_edit (book);
539  qof_session_end (sess);
540  qof_session_destroy (sess);
541 }
542 
543 static void
544 test_dbi_business_store_and_reload (Fixture *fixture, gconstpointer pData)
545 {
546  QofSession* session_2;
547  QofSession* session_3;
548  const gchar* url = (gchar*)pData;
549 
550  gchar *msg = "[gnc_dbi_unlock()] There was no lock entry in the Lock table";
551  gchar *log_domain = "gnc.backend.dbi";
552  guint loglevel = G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL;
553  TestErrorStruct *check = test_error_struct_new (log_domain, loglevel, msg);
554  if (fixture->filename)
555  url = fixture->filename;
556  // Save the session data
557  session_2 = qof_session_new();
558  qof_session_begin (session_2, url, FALSE, TRUE, TRUE);
559  qof_session_swap_data (fixture->session, session_2);
560  qof_session_save (session_2, NULL);
561 
562  // Reload the session data
563  session_3 = qof_session_new();
564  qof_session_begin (session_3, url, TRUE, FALSE, FALSE);
565  qof_session_load (session_3, NULL);
566 
567  // Compare with the original data
568  compare_business_books (qof_session_get_book (session_2), qof_session_get_book (session_3));
569  qof_session_end (session_2);
570  qof_session_destroy (session_2);
571 
572  fixture->hdlrs = test_log_set_fatal_handler (fixture->hdlrs, check,
573  (GLogFunc)test_checked_handler);
574  qof_session_end (session_3);
575  qof_session_destroy (session_3);
576 }
577 
578 static void
579 create_dbi_test_suite (gchar *dbm_name, gchar *url)
580 {
581  gchar *subsuite = g_strdup_printf ("%s/%s", suitename, dbm_name);
582  GNC_TEST_ADD (subsuite, "store_and_reload", Fixture, url, setup,
583  test_dbi_store_and_reload, teardown);
584  GNC_TEST_ADD (subsuite, "safe_save", Fixture, url, setup_memory,
585  test_dbi_safe_save, teardown);
586  GNC_TEST_ADD (subsuite, "version_control", Fixture, url, setup_memory,
587  test_dbi_version_control, teardown);
588  GNC_TEST_ADD (subsuite, "business_store_and_reload", Fixture, url,
589  setup_business, test_dbi_version_control, teardown);
590  g_free (subsuite);
591 
592 }
593 
594 void
595 test_suite_gnc_backend_dbi (void)
596 {
597  dbi_driver driver = NULL;
598  GList *drivers = NULL;
599  #if HAVE_LIBDBI_R
600  if (dbi_instance == NULL)
601  dbi_initialize_r (NULL, &dbi_instance);
602  while ((driver = dbi_driver_list_r (driver, dbi_instance)))
603  #else
604  dbi_initialize (NULL);
605  while ((driver = dbi_driver_list (driver)))
606  #endif
607  {
608  drivers = g_list_prepend (drivers,
609  (gchar*)dbi_driver_get_name (driver));
610  }
611  if (g_list_find_custom (drivers, "sqlite3", (GCompareFunc)g_strcmp0))
612  create_dbi_test_suite ("sqlite3", "sqlite3");
613  if (strlen (TEST_MYSQL_URL) > 0 &&
614  g_list_find_custom (drivers, "mysql", (GCompareFunc)g_strcmp0))
615  create_dbi_test_suite ("mysql", TEST_MYSQL_URL);
616  if (strlen (TEST_PGSQL_URL) > 0 &&
617  g_list_find_custom (drivers, "pgsql", (GCompareFunc)g_strcmp0))
618  {
619  g_setenv ("PGOPTIONS", "-c client_min_messages=WARNING", FALSE);
620  create_dbi_test_suite ("postgres", TEST_PGSQL_URL);
621  }
622 
623 }
void xaccAccountSetType(Account *acc, GNCAccountType tip)
Definition: Account.c:2208
Core Customer Interface.
#define xaccTransAppendSplit(t, s)
Definition: Transaction.h:357
gnc_commodity_table * gnc_commodity_table_get_table(QofBook *book)
Transaction * xaccMallocTransaction(QofBook *book)
Definition: Transaction.c:513
void qof_session_save(QofSession *session, QofPercentageFunc percentage_func)
void kvp_frame_set_timespec(KvpFrame *frame, const gchar *path, Timespec ts)
void gnc_account_append_child(Account *new_parent, Account *child)
Definition: Account.c:2525
const GncGUID * qof_instance_get_guid(gconstpointer)
QofBackendError
The errors that can be reported to the GUI & other front-end users.
Definition: qofbackend.h:59
void qof_session_safe_save(QofSession *session, QofPercentageFunc percentage_func)
void kvp_frame_set_gint64(KvpFrame *frame, const gchar *path, gint64 ival)
GncSqlConnection * conn
API for Transactions and Splits (journal entries)
void xaccTransSetCurrency(Transaction *trans, gnc_commodity *curr)
Definition: Transaction.c:1354
QofBook * qof_session_get_book(const QofSession *session)
Account handling public routines.
void xaccAccountSetPlaceholder(Account *acc, gboolean val)
Definition: Account.c:3923
gboolean gnc_sql_set_table_version(GncSqlBackend *be, const gchar *table_name, gint version)
QofBackendError qof_session_pop_error(QofSession *session)
void gnc_uri_get_components(const gchar *uri, gchar **protocol, gchar **hostname, gint32 *port, gchar **username, gchar **password, gchar **path)
Definition: gnc-uri-utils.c:82
void kvp_frame_set_numeric(KvpFrame *frame, const gchar *path, gnc_numeric nval)
QofBackendError qof_session_get_error(QofSession *session)
void qof_session_swap_data(QofSession *session_1, QofSession *session_2)
void xaccTransCommitEdit(Transaction *trans)
Definition: Transaction.c:1579
void xaccTransBeginEdit(Transaction *trans)
Definition: Transaction.c:1380
Split * xaccMallocSplit(QofBook *book)
Definition: Split.c:582
Generic api to store and retrieve preferences.
API for the transaction logger.
Business Invoice Interface.
void qof_session_begin(QofSession *session, const char *book_id, gboolean ignore_lock, gboolean create, gboolean force)
void kvp_frame_set_double(KvpFrame *frame, const gchar *path, double dval)
Definition: SplitP.h:71
void xaccAccountSetHidden(Account *acc, gboolean val)
Definition: Account.c:3970
Timespec timespec_now(void)
void qof_session_ensure_all_data_loaded(QofSession *session)
struct KvpFrameImpl KvpFrame
Definition: kvp_frame.h:76
Account * xaccMallocAccount(QofBook *book)
Definition: Account.c:1083
Utility functions for convert uri in separate components and back.
void qof_session_end(QofSession *session)
QofBackend * qof_book_get_backend(const QofBook *book)
Retrieve the backend used by this book.
an Address object
API for Transactions and Splits (journal entries)
void kvp_frame_set_string(KvpFrame *frame, const gchar *path, const gchar *str)
Store a copy of the string at the indicated path.
void xaccAccountSetName(Account *acc, const char *str)
Definition: Account.c:2229
Commodity handling public routines.
void xaccAccountSetCommodity(Account *acc, gnc_commodity *com)
Definition: Account.c:2389