GnuCash  4.8a-80-g9825132ea+
qofsession.cpp
Go to the documentation of this file.
1 /********************************************************************\
2  * qofsesssion.cpp -- session access (connection to backend) *
3  * *
4  * This program is free software; you can redistribute it and/or *
5  * modify it under the terms of the GNU General Public License as *
6  * published by the Free Software Foundation; either version 2 of *
7  * the License, or (at your option) any later version. *
8  * *
9  * This program is distributed in the hope that it will be useful, *
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12  * GNU General Public License for more details. *
13  * *
14  * You should have received a copy of the GNU General Public License*
15  * along with this program; if not, contact: *
16  * *
17  * Free Software Foundation Voice: +1-617-542-5942 *
18  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
19  * Boston, MA 02110-1301, USA gnu@gnu.org *
20 \********************************************************************/
21 
34 #include <glib.h>
35 
36 extern "C"
37 {
38 
39 #include <config.h>
40 
41 #include <stdlib.h>
42 #include <sys/types.h>
43 #include <sys/stat.h>
44 #ifdef HAVE_UNISTD_H
45 # include <unistd.h>
46 #else
47 # ifdef __GNUC__
48 # warning "<unistd.h> required."
49 # endif
50 #endif
51 
52 #include "qof.h"
53 #include "qofobject-p.h"
54 
55 static QofLogModule log_module = QOF_MOD_SESSION;
56 } //extern 'C'
57 
58 #include "qofbook-p.h"
59 #include "qof-backend.hpp"
60 #include "qofsession.hpp"
61 #include "gnc-backend-prov.hpp"
62 
63 #include <vector>
64 #include <boost/algorithm/string.hpp>
65 #include <vector>
66 #include <algorithm>
67 #include <string>
68 #include <sstream>
69 
70 using ProviderVec = std::vector<QofBackendProvider_ptr>;
71 static ProviderVec s_providers;
72 static const std::string empty_string{};
73 /*
74  * These getters are used in tests to reach static vars from outside
75  * They should be removed when no longer needed
76  */
77 
78 ProviderVec& get_providers (void );
79 bool get_providers_initialized (void );
80 
81 ProviderVec&
82 get_providers (void)
83 {
84  return s_providers;
85 }
86 
87 bool
88 get_providers_initialized (void)
89 {
90  return !s_providers.empty();
91 }
92 
93 void
94 qof_backend_register_provider (QofBackendProvider_ptr&& prov)
95 {
96  s_providers.emplace_back(std::move(prov));
97 }
98 
99 void
100 qof_backend_unregister_all_providers ()
101 {
102  s_providers.clear ();
103 }
104 
105 /* Called from C so we have to keep the GList for now. */
106 GList*
108 {
109  GList* list = NULL;
110  std::for_each(s_providers.begin(), s_providers.end(),
111  [&list](QofBackendProvider_ptr& provider) {
112  gpointer method = reinterpret_cast<gpointer>(const_cast<char*>(provider->access_method));
113  list = g_list_prepend(list, method);
114  });
115  return list;
116 }
117 
118 /* QofSessionImpl */
119 /* ====================================================================== */
120 /* Constructor/Destructor ----------------------------------*/
121 
122 QofSessionImpl::QofSessionImpl (QofBook* book) noexcept
123  : m_backend {},
124  m_book {book},
125  m_uri {},
126  m_saving {false},
127  m_last_err {},
128  m_error_message {}
129 {
130 }
131 
132 QofSessionImpl::~QofSessionImpl () noexcept
133 {
134  ENTER ("sess=%p uri=%s", this, m_uri.c_str ());
135  end ();
136  destroy_backend ();
137  qof_book_set_backend (m_book, nullptr);
138  qof_book_destroy (m_book);
139  m_book = nullptr;
140  LEAVE ("sess=%p", this);
141 }
142 
143 void
144 qof_session_destroy (QofSession * session)
145 {
146  delete session;
147 }
148 
149 QofSession *
150 qof_session_new (QofBook* book)
151 {
152  return new QofSessionImpl(book);
153 }
154 
155 void
156 QofSessionImpl::destroy_backend () noexcept
157 {
158  if (m_backend)
159  {
160  clear_error ();
161  delete m_backend;
162  m_backend = nullptr;
163  qof_book_set_backend (m_book, nullptr);
164  }
165 }
166 
167 /* ====================================================================== */
168 
169 void
170 QofSessionImpl::load_backend (std::string access_method) noexcept
171 {
172  std::ostringstream s;
173  s << " list=" << s_providers.size();
174  ENTER ("%s", s.str().c_str());
175  for (auto const & prov : s_providers)
176  {
177  if (!boost::iequals (access_method, prov->access_method))
178  {
179  PINFO ("The provider providers access_method, %s, but we're loading for access_method, %s. Skipping.",
180  prov->access_method, access_method.c_str ());
181  continue;
182  }
183  PINFO (" Selected provider %s", prov->provider_name);
184  // Only do a type check when trying to open an existing file
185  // When saving over an existing file the contents of the original file don't matter
186  if (!m_creating && !prov->type_check (m_uri.c_str ()))
187  {
188  PINFO("Provider, %s, reported not being usable for book, %s.",
189  prov->provider_name, m_uri.c_str ());
190  continue;
191  }
192  m_backend = prov->create_backend();
193  LEAVE (" ");
194  return;
195  }
196  std::string msg {"failed to get_backend using access method \"" + access_method + "\""};
197  push_error (ERR_BACKEND_NO_HANDLER, msg);
198  LEAVE (" ");
199 }
200 
201 void
202 QofSessionImpl::load (QofPercentageFunc percentage_func) noexcept
203 {
204  /* We must have an empty book to load into or bad things will happen. */
205  g_return_if_fail(m_book && qof_book_empty(m_book));
206 
207  if (!m_uri.size ()) return;
208  ENTER ("sess=%p uri=%s", this, m_uri.c_str ());
209 
210  /* At this point, we should are supposed to have a valid book
211  * id and a lock on the file. */
212  clear_error ();
213 
214  /* This code should be sufficient to initialize *any* backend,
215  * whether http, postgres, or anything else that might come along.
216  * Basically, the idea is that by now, a backend has already been
217  * created & set up. At this point, we only need to get the
218  * top-level account group out of the backend, and that is a
219  * generic, backend-independent operation.
220  */
221  qof_book_set_backend (m_book, m_backend);
222 
223  /* Starting the session should result in a bunch of accounts
224  * and currencies being downloaded, but probably no transactions;
225  * The GUI will need to do a query for that.
226  */
227  if (m_backend)
228  {
229  m_backend->set_percentage(percentage_func);
230  m_backend->load (m_book, LOAD_TYPE_INITIAL_LOAD);
231  push_error (m_backend->get_error(), {});
232  }
233 
234  auto err = get_error ();
235  if ((err != ERR_BACKEND_NO_ERR) &&
236  (err != ERR_FILEIO_FILE_TOO_OLD) &&
237  (err != ERR_FILEIO_NO_ENCODING) &&
238  (err != ERR_FILEIO_FILE_UPGRADE) &&
239  (err != ERR_SQL_DB_TOO_OLD) &&
240  (err != ERR_SQL_DB_TOO_NEW))
241  {
242  // Something failed, delete and restore new ones.
243  destroy_backend();
244  qof_book_destroy (m_book);
245  m_book = qof_book_new();
246  LEAVE ("error from backend %d", get_error ());
247  return;
248  }
249 
250  LEAVE ("sess = %p, uri=%s", this, m_uri.c_str ());
251 }
252 
253 void
254 QofSessionImpl::begin (const char* new_uri, SessionOpenMode mode) noexcept
255 {
256 
257 
258  ENTER (" sess=%p mode=%d, URI=%s", this, mode, new_uri);
259  clear_error ();
260  /* Check to see if this session is already open */
261  if (m_uri.size ())
262  {
263  if (ERR_BACKEND_NO_ERR != get_error ())
264  push_error (ERR_BACKEND_LOCKED, {});
265  LEAVE("push error book is already open ");
266  return;
267  }
268 
269  /* seriously invalid */
270  if (!new_uri)
271  {
272  if (ERR_BACKEND_NO_ERR != get_error ())
273  push_error (ERR_BACKEND_BAD_URL, {});
274  LEAVE("push error missing new_uri");
275  return;
276  }
277 
278  char * scheme {g_uri_parse_scheme (new_uri)};
279  char * filename {nullptr};
280  if (g_strcmp0 (scheme, "file") == 0)
281  filename = g_filename_from_uri (new_uri, nullptr, nullptr);
282  else if (!scheme)
283  filename = g_strdup (new_uri);
284 
285  if (filename && g_file_test (filename, G_FILE_TEST_IS_DIR))
286  {
287  if (ERR_BACKEND_NO_ERR == get_error ())
288  push_error (ERR_BACKEND_BAD_URL, {});
289  g_free (filename);
290  g_free (scheme);
291  LEAVE("Can't open a directory");
292  return;
293  }
294  /* destroy the old backend */
295  destroy_backend ();
296  /* Store the session URL */
297  m_uri = new_uri;
298  m_creating = mode == SESSION_NEW_STORE || mode == SESSION_NEW_OVERWRITE;
299  if (filename)
300  load_backend ("file");
301  else /* access method found, load appropriate backend */
302  load_backend (scheme);
303  g_free (filename);
304  g_free (scheme);
305 
306  /* No backend was found. That's bad. */
307  if (m_backend == nullptr)
308  {
309  m_uri = {};
310  if (ERR_BACKEND_NO_ERR == get_error ())
311  push_error (ERR_BACKEND_BAD_URL, {});
312  LEAVE (" BAD: no backend: sess=%p book-id=%s",
313  this, new_uri);
314  return;
315  }
316 
317  /* If there's a begin method, call that. */
318  m_backend->session_begin(this, m_uri.c_str(), mode);
319  PINFO ("Done running session_begin on backend");
320  QofBackendError const err {m_backend->get_error()};
321  auto msg (m_backend->get_message());
322  if (err != ERR_BACKEND_NO_ERR)
323  {
324  m_uri = {};
325  push_error (err, msg);
326  LEAVE (" backend error %d %s", err, msg.empty() ? "(null)" : msg.c_str());
327  return;
328  }
329  if (!msg.empty())
330  {
331  PWARN("%s", msg.c_str());
332  }
333 
334  LEAVE (" sess=%p book-id=%s", this, new_uri);
335 }
336 
337 void
339 {
340  ENTER ("sess=%p uri=%s", this, m_uri.c_str ());
341  auto backend = qof_book_get_backend (m_book);
342  if (backend != nullptr)
343  backend->session_end();
344  clear_error ();
345  m_uri.clear();
346  LEAVE ("sess=%p uri=%s", this, m_uri.c_str ());
347 }
348 
349 /* error handling functions --------------------------------*/
350 
351 void
352 QofSessionImpl::clear_error () noexcept
353 {
354  m_last_err = ERR_BACKEND_NO_ERR;
355  m_error_message = {};
356 
357  /* pop the stack on the backend as well. */
358  if (auto backend = qof_book_get_backend (m_book))
359  {
360  QofBackendError err = ERR_BACKEND_NO_ERR;
361  do
362  err = backend->get_error();
363  while (err != ERR_BACKEND_NO_ERR);
364  }
365 }
366 
367 void
368 QofSessionImpl::push_error (QofBackendError const err, std::string message) noexcept
369 {
370  m_last_err = err;
371  m_error_message = message;
372 }
373 
376 {
377  /* if we have a local error, return that. */
378  if (m_last_err != ERR_BACKEND_NO_ERR)
379  return m_last_err;
380  auto qof_be = qof_book_get_backend (m_book);
381  if (qof_be == nullptr) return ERR_BACKEND_NO_ERR;
382 
383  m_last_err = qof_be->get_error();
384  return m_last_err;
385 }
386 
387 const std::string&
388 QofSessionImpl::get_error_message () const noexcept
389 {
390  return m_error_message;
391 }
392 
394 QofSessionImpl::pop_error () noexcept
395 {
396  QofBackendError err {get_error ()};
397  clear_error ();
398  return err;
399 }
400 
401 /* Accessors (getters/setters) -----------------------------*/
402 
403 QofBook *
404 QofSessionImpl::get_book () const noexcept
405 {
406  if (!m_book) return nullptr;
407  if ('y' == m_book->book_open)
408  return m_book;
409  return nullptr;
410 }
411 
412 QofBackend *
413 QofSession::get_backend () const noexcept
414 {
415  return m_backend;
416 }
417 
418 const std::string&
419 QofSessionImpl::get_file_path () const noexcept
420 {
421  auto backend = qof_book_get_backend (m_book);
422  if (!backend) return empty_string;
423  return backend->get_uri();
424 }
425 
426 std::string const &
427 QofSessionImpl::get_uri () const noexcept
428 {
429  return m_uri;
430 }
431 
432 bool
433 QofSessionImpl::is_saving () const noexcept
434 {
435  return m_saving;
436 }
437 
438 /* Manipulators (save, load, etc.) -------------------------*/
439 
440 void
441 QofSessionImpl::save (QofPercentageFunc percentage_func) noexcept
442 {
443  if (!qof_book_session_not_saved (m_book)) //Clean book, nothing to do.
444  return;
445  m_saving = true;
446  ENTER ("sess=%p uri=%s", this, m_uri.c_str ());
447 
448  /* If there is a backend, the book is dirty, and the backend is reachable
449  * (i.e. we can communicate with it), then synchronize with the backend. If
450  * we cannot contact the backend (e.g. because we've gone offline, the
451  * network has crashed, etc.) then raise an error so that the controlling
452  * dialog can offer the user a chance to save in a different way.
453  */
454  if (m_backend)
455  {
456  /* if invoked as SaveAs(), then backend not yet set */
457  if (qof_book_get_backend (m_book) != m_backend)
458  qof_book_set_backend (m_book, m_backend);
459  m_backend->set_percentage(percentage_func);
460  m_backend->sync(m_book);
461  auto err = m_backend->get_error();
462  if (err != ERR_BACKEND_NO_ERR)
463  {
464  push_error (err, {});
465  m_saving = false;
466  return;
467  }
468  /* If we got to here, then the backend saved everything
469  * just fine, and we are done. So return. */
470  clear_error ();
471  LEAVE("Success");
472  }
473  else
474  {
475  push_error (ERR_BACKEND_NO_HANDLER, "failed to load backend");
476  LEAVE("error -- No backend!");
477  }
478  m_saving = false;
479 }
480 
481 void
482 QofSessionImpl::safe_save (QofPercentageFunc percentage_func) noexcept
483 {
484  if (!(m_backend && m_book)) return;
485  if (qof_book_get_backend (m_book) != m_backend)
486  qof_book_set_backend (m_book, m_backend);
487  m_backend->set_percentage(percentage_func);
488  m_backend->safe_sync(get_book ());
489  auto err = m_backend->get_error();
490  auto msg = m_backend->get_message();
491  if (err != ERR_BACKEND_NO_ERR)
492  {
493  m_uri = "";
494  push_error (err, msg);
495  }
496 }
497 
498 void
499 QofSessionImpl::ensure_all_data_loaded () noexcept
500 {
501  if (!(m_backend && m_book)) return;
502  if (qof_book_get_backend (m_book) != m_backend)
503  qof_book_set_backend (m_book, m_backend);
504  m_backend->load(m_book, LOAD_TYPE_LOAD_ALL);
505  push_error (m_backend->get_error(), {});
506 }
507 
508 void
510 {
511  ENTER ("sess1=%p sess2=%p", this, &other);
512  // don't swap (that is, double-swap) read_only flags
513  if (m_book && other.m_book)
514  std::swap (m_book->read_only, other.m_book->read_only);
515  std::swap (m_book, other.m_book);
516  auto mybackend = qof_book_get_backend (m_book);
517  qof_book_set_backend (m_book, qof_book_get_backend (other.m_book));
518  qof_book_set_backend (other.m_book, mybackend);
519  LEAVE (" ");
520 }
521 
522 bool
523 QofSessionImpl::events_pending () const noexcept
524 {
525  return false;
526 }
527 
528 bool
529 QofSessionImpl::process_events () const noexcept
530 {
531  return false;
532 }
533 
534 /* XXX This exports the list of accounts to a file. It does not
535  * export any transactions. It's a place-holder until full
536  * book-closing is implemented.
537  */
538 bool
539 QofSessionImpl::export_session (QofSessionImpl & real_session,
540  QofPercentageFunc percentage_func) noexcept
541 {
542  auto real_book = real_session.get_book ();
543  ENTER ("tmp_session=%p real_session=%p book=%p uri=%s",
544  this, &real_session, real_book, m_uri.c_str ());
545 
546  /* There must be a backend or else. (It should always be the file
547  * backend too.)
548  */
549  if (!m_backend) return false;
550 
551  m_backend->set_percentage(percentage_func);
552 
553  m_backend->export_coa(real_book);
554  auto err = m_backend->get_error();
555  if (err != ERR_BACKEND_NO_ERR)
556  return false;
557  return true;
558 }
559 
560 /* C Wrapper Functions */
561 /* ====================================================================== */
562 
563 const char *
564 qof_session_get_error_message (const QofSession * session)
565 {
566  if (!session) return "";
567  return session->get_error_message ().c_str ();
568 }
569 
571 qof_session_pop_error (QofSession * session)
572 {
573  if (!session) return ERR_BACKEND_NO_BACKEND;
574  return session->pop_error ();
575 }
576 
577 QofBook *
578 qof_session_get_book (const QofSession *session)
579 {
580  if (!session) return NULL;
581  return session->get_book ();
582 }
583 
584 const char *
585 qof_session_get_file_path (const QofSession *session)
586 {
587  if (!session) return nullptr;
588  auto& path{session->get_file_path()};
589  return path.empty() ? nullptr : path.c_str ();
590 }
591 
592 void
594 {
595  if (session == nullptr) return;
596  return session->ensure_all_data_loaded ();
597 }
598 
599 const char *
600 qof_session_get_url (const QofSession *session)
601 {
602  if (!session) return NULL;
603  return session->get_uri ().c_str ();
604 }
605 
606 QofBackend *
607 qof_session_get_backend (const QofSession *session)
608 {
609  if (!session) return NULL;
610  return session->get_backend ();
611 }
612 
613 void
614 qof_session_begin (QofSession *session, const char * uri, SessionOpenMode mode)
615 {
616  if (!session) return;
617  session->begin(uri, mode);
618 }
619 
620 void
621 qof_session_load (QofSession *session,
622  QofPercentageFunc percentage_func)
623 {
624  if (!session) return;
625  session->load (percentage_func);
626 }
627 
628 void
629 qof_session_save (QofSession *session,
630  QofPercentageFunc percentage_func)
631 {
632  if (!session) return;
633  session->save (percentage_func);
634 }
635 
636 void
637 qof_session_safe_save(QofSession *session, QofPercentageFunc percentage_func)
638 {
639  if (!session) return;
640  session->safe_save (percentage_func);
641 }
642 
643 gboolean
644 qof_session_save_in_progress(const QofSession *session)
645 {
646  if (!session) return false;
647  return session->is_saving ();
648 }
649 
650 void
651 qof_session_end (QofSession *session)
652 {
653  if (!session) return;
654  session->end ();
655 }
656 
657 void
658 qof_session_swap_data (QofSession *session_1, QofSession *session_2)
659 {
660  if (session_1 == session_2) return;
661  if (!session_1 || !session_2) return;
662  session_1->swap_books (*session_2);
663 }
664 
665 gboolean
666 qof_session_events_pending (const QofSession *session)
667 {
668  if (!session) return false;
669  return session->events_pending ();
670 }
671 
672 gboolean
673 qof_session_process_events (QofSession *session)
674 {
675  if (!session) return FALSE;
676  return session->process_events ();
677 }
678 
679 gboolean
680 qof_session_export (QofSession *tmp_session,
681  QofSession *real_session,
682  QofPercentageFunc percentage_func)
683 {
684  if ((!tmp_session) || (!real_session)) return FALSE;
685  return tmp_session->export_session (*real_session, percentage_func);
686 }
687 
688 /* ================= Static function access for testing ================= */
689 
690 void init_static_qofsession_pointers (void);
691 
692 void qof_session_load_backend (QofSession * session, const char * access_method)
693 {
694  session->load_backend (access_method);
695 }
696 
697 static void
698 qof_session_clear_error (QofSession * session)
699 {
700  session->clear_error ();
701 }
702 
703 static void
704 qof_session_destroy_backend (QofSession * session)
705 {
706  session->destroy_backend ();
707 }
708 
709 void qof_session_set_uri (QofSession * session, char const * uri)
710 {
711  if (!uri)
712  session->m_uri = "";
713  else
714  session->m_uri = uri;
715 }
716 
717 void (*p_qof_session_load_backend) (QofSession *, const char * access_method);
718 void (*p_qof_session_clear_error) (QofSession *);
719 void (*p_qof_session_destroy_backend) (QofSession *);
720 void (*p_qof_session_set_uri) (QofSession *, char const * uri);
721 
722 void
723 init_static_qofsession_pointers (void)
724 {
725  p_qof_session_load_backend = &qof_session_load_backend;
726  p_qof_session_clear_error = &qof_session_clear_error;
727  p_qof_session_destroy_backend = &qof_session_destroy_backend;
728  p_qof_session_set_uri = &qof_session_set_uri;
729 }
730 
732 qof_session_get_error (QofSession * session)
733 {
734  if (!session) return ERR_BACKEND_NO_BACKEND;
735  return session->get_error();
736 }
void qof_session_save(QofSession *session, QofPercentageFunc percentage_func)
The qof_session_save() method will commit all changes that have been made to the session.
Definition: qofsession.cpp:629
void swap_books(QofSessionImpl &) noexcept
Swap books with another session.
Definition: qofsession.cpp:509
gboolean qof_session_save_in_progress(const QofSession *session)
The qof_session_not_saved() subroutine will return TRUE if any data in the session hasn&#39;t been saved ...
Definition: qofsession.cpp:644
void(* QofPercentageFunc)(const char *message, double percent)
The qof_session_load() method causes the QofBook to be made ready to to use with this URL/datastore...
Definition: qofsession.h:199
#define PINFO(format, args...)
Print an informational note.
Definition: qoflog.h:256
gboolean qof_session_events_pending(const QofSession *session)
The qof_session_events_pending() method will return TRUE if the backend has pending events which must...
Definition: qofsession.cpp:666
QofBackendError
The errors that can be reported to the GUI & other front-end users.
Definition: qofbackend.h:57
void qof_session_safe_save(QofSession *session, QofPercentageFunc percentage_func)
A special version of save used in the sql backend which moves the existing tables aside...
Definition: qofsession.cpp:637
void qof_backend_register_provider(QofBackendProvider_ptr &&prov)
Let the system know about a new provider of backends.
Definition: qofsession.cpp:94
void end() noexcept
Terminates the current backend.
Definition: qofsession.cpp:338
void qof_session_begin(QofSession *session, const char *uri, SessionOpenMode mode)
Begins a new session.
Definition: qofsession.cpp:614
QofBook * qof_book_new(void)
Allocate, initialise and return a new QofBook.
Definition: qofbook.cpp:385
database is old and needs upgrading
Definition: qofbackend.h:113
Can&#39;t parse url.
Definition: qofbackend.h:62
in use by another user (ETXTBSY)
Definition: qofbackend.h:66
Create a new store at the URI.
Definition: qofsession.h:126
const char * qof_session_get_file_path(const QofSession *session)
The qof_session_get_file_path() routine returns the fully-qualified file path for the session...
Definition: qofsession.cpp:585
void qof_session_ensure_all_data_loaded(QofSession *session)
Ensure all of the data is loaded from the session.
Definition: qofsession.cpp:593
#define ENTER(format, args...)
Print a function entry debugging message.
Definition: qoflog.h:272
file will be upgraded and not be able to be read by prior versions - warn users
Definition: qofbackend.h:103
the Core Object Registration/Lookup Private Interface
#define PWARN(format, args...)
Log a warning.
Definition: qoflog.h:250
gboolean qof_book_empty(const QofBook *book)
Check if the book has had anything loaded into it.
Definition: qofbook.cpp:594
std::string const & get_uri() const noexcept
We return by reference so that a pointer to the data of the string lives long enough to make it back ...
Definition: qofsession.cpp:427
file does not specify encoding
Definition: qofbackend.h:99
database is newer, we can&#39;t write to it
Definition: qofbackend.h:114
QofBook * qof_session_get_book(const QofSession *session)
Returns the QofBook of this session.
Definition: qofsession.cpp:578
QofBackendError qof_session_pop_error(QofSession *session)
The qof_session_pop_error() routine can be used to obtain the reason for any failure.
Definition: qofsession.cpp:571
GList * qof_backend_get_registered_access_method_list(void)
Return a list of strings for the registered access methods.
Definition: qofsession.cpp:107
QofBackendError get_error() noexcept
Returns and clears the local cached error.
Definition: qofsession.cpp:375
QofBackendError qof_session_get_error(QofSession *session)
The qof_session_get_error() routine can be used to obtain the reason for any failure.
Definition: qofsession.cpp:732
void qof_session_swap_data(QofSession *session_1, QofSession *session_2)
The qof_session_swap_data () method swaps the book of the two given sessions.
Definition: qofsession.cpp:658
no backend handler found for this access method (ENOSYS)
Definition: qofbackend.h:60
gboolean qof_book_session_not_saved(const QofBook *book)
qof_book_not_saved() returns the value of the session_dirty flag, set when changes to any object in t...
Definition: qofbook.cpp:459
virtual void load(QofBook *, QofBackendLoadType)=0
Load the minimal set of application data needed for the application to be operable at initial startup...
SessionOpenMode
Mode for opening sessions.
Definition: qofsession.h:120
Backend * pointer was unexpectedly null.
Definition: qofbackend.h:61
void begin(const char *new_uri, SessionOpenMode mode) noexcept
Begin this session.
Definition: qofsession.cpp:254
#define LEAVE(format, args...)
Print a function exit debugging message.
Definition: qoflog.h:282
void qof_session_end(QofSession *session)
The qof_session_end() method will release the session lock.
Definition: qofsession.cpp:651
QofBackend * qof_book_get_backend(const QofBook *book)
Retrieve the backend used by this book.
Definition: qofbook.cpp:524
QofBackend * qof_session_get_backend(const QofSession *session)
Returns the qof session&#39;s backend.
Definition: qofsession.cpp:607
gboolean qof_session_process_events(QofSession *session)
The qof_session_process_events() method will process any events indicated by the qof_session_events_p...
Definition: qofsession.cpp:673
file version so old we can&#39;t read it
Definition: qofbackend.h:93
Open will fail if the URI doesn&#39;t exist or is locked.
Definition: qofsession.h:124
void qof_book_destroy(QofBook *book)
End any editing sessions associated with book, and free all memory associated with it...
Definition: qofbook.cpp:419
QofBackendError get_error()
Retrieve the currently-stored error and clear it.
Definition: qof-backend.cpp:67