GnuCash  2.6.17
Files | Macros | Typedefs | Enumerations | Functions


file  qofbackend.h
 API for data storage Backend.
file  qofsession.h
 Encapsulates a connection to a backend (persistent store)


#define QOF_MOD_BACKEND   "qof.backend"
#define QOF_MOD_SESSION   "qof.session"


typedef void(* QofBePercentageFunc) (const char *message, double percent)
typedef void(* QofPercentageFunc) (const char *message, double percent)


enum  QofBackendError {
 The errors that can be reported to the GUI & other front-end users. More...


void qof_backend_set_error (QofBackend *be, QofBackendError err)
QofBackendError qof_backend_get_error (QofBackend *be)
gboolean qof_backend_check_error (QofBackend *be)
gboolean qof_load_backend_library (const gchar *directory, const gchar *module_name)
 Load a QOF-compatible backend shared library. More...
void qof_finalize_backend_libraries (void)
 Finalize all loaded backend sharable libraries.
QofBackend * qof_book_get_backend (const QofBook *book)
 Retrieve the backend used by this book.
void qof_book_set_backend (QofBook *book, QofBackend *)
QofSession * qof_session_new (void)
void qof_session_destroy (QofSession *session)
void qof_session_swap_data (QofSession *session_1, QofSession *session_2)
void qof_session_begin (QofSession *session, const char *book_id, gboolean ignore_lock, gboolean create, gboolean force)
void qof_session_load (QofSession *session, QofPercentageFunc percentage_func)
QofBook * qof_session_get_book (const QofSession *session)
const char * qof_session_get_file_path (const QofSession *session)
const char * qof_session_get_url (const QofSession *session)
gboolean qof_session_save_in_progress (const QofSession *session)
void qof_session_save (QofSession *session, QofPercentageFunc percentage_func)
void qof_session_safe_save (QofSession *session, QofPercentageFunc percentage_func)
void qof_session_end (QofSession *session)

Allow access to the begin routine for this backend.

void qof_backend_run_begin (QofBackend *be, QofInstance *inst)
gboolean qof_backend_begin_exists (const QofBackend *be)
void qof_backend_run_commit (QofBackend *be, QofInstance *inst)
gboolean qof_backend_commit_exists (const QofBackend *be)

Session Errors

QofBackendError qof_session_get_error (QofSession *session)
const char * qof_session_get_error_message (const QofSession *session)
QofBackendError qof_session_pop_error (QofSession *session)

Detailed Description

The QOF Backend is a pseudo-object providing an interface between the engine and a persistent data store (e.g. a server, a database, or a file). Backends are not meant to be used directly by an application; instead the Session should be used to make a connection with some particular backend. There are no backend functions that are 'public' to users of the engine. The backend can, however, report errors to the GUI & other front-end users. This file defines these errors.

Backends are used to save and restore Entities in a Book.

The QOF Session encapsulates a connection to a storage backend. That is, it manages the connection to a persistent data store; whereas the backend is the thing that performs the actual datastore access.

This class provides several important services:

1) It resolves and loads the appropriate backend, based on the URL.

2) It reports backend errors (e.g. network errors, storage corruption errors) through a single, backend-independent API.

3) It reports non-error events received from the backend.

4) It helps manage global dataset locks. For example, for the file backend, the lock prevents multiple users from editing the same file at the same time, thus avoiding lost data due to race conditions. Thus, an open session implies that the associated file is locked.

5) Misc utilities, such as a search path for the file to be edited, and/or other URL resolution utilities. This should simplify install & maintenance problems for naive users who may not have a good grasp on what a file system is, or where they want to keep their data files.

6) In the future, this class is probably a good place to manage a portion of the user authentication process, and hold user credentials/cookies/keys/tokens. This is because at the coarsest level, authorization can happen at the datastore level: i.e. does this user even have the authority to connect to and open this datastore?

A brief note about books & sessions: A book encapsulates the datasets manipulated by QOF. A book holds the actual data. By contrast, the session mediates the connection between a book (the thing that lives in virtual memory in the local process) and the datastore (the place where book data lives permanently, e.g., file, database).

In the current design, a session may hold multiple books. For now, exactly what this means is somewhat vague, and code in various places makes some implicit assumptions: first, only one book is 'current' and open for editing. Next, its assumed that all of the books in a session are related in some way. i.e. that they are all earlier accounting periods of the currently open book. In particular, the backends probably make that assumption, in order to store the different accounting periods in a clump so that one can be found, given another.

If you want multiple books that are unrelated to each other, use multiple sessions.

The session now calls QofBackendProvider->check_data_type to check that the incoming path contains data that the backend provider can open. The backend provider should also check if it can contact it's storage media (disk, network, server, etc.) and abort if it can't. Malformed file URL's would be handled the same way.

Typedef Documentation

◆ QofPercentageFunc

typedef 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. When the URL points at a file, then this routine would load the data from the file. With remote backends, e.g. network or SQL, this would load only enough data to make the book actually usable; it would not cause all of the data to be loaded.

XXX the current design tries to accommodate multiple calls to 'load' for each session, each time wiping out the old books; this seems wrong to me, and should be restricted to allow only one load per session.

Definition at line 168 of file qofsession.h.

Enumeration Type Documentation

◆ QofBackendError

The errors that can be reported to the GUI & other front-end users.

(GnuCash) If you modify QofBackendError, please update src/engine/gw-engine-spec.scm

no backend handler found for this access method (ENOSYS)


Backend * pointer was unexpectedly null


Can't parse url


the named database doesn't exist


bad dbname/login/passwd or network failure


Lost connection to server


in use by another user (ETXTBSY)


File exists, data would be destroyed


cannot write to file/directory


file/db version newer than what we can read


data in db is corrupt


error in response from server


internal memory allocation failure


user login successful, but no permissions to access the desired object


commit of object update failed because another user has modified the object


commit of object update failed because another user has deleted the object


undetermined error


EOVERFLOW - generated by strtol or strtoll.

When converting XML strings into numbers, an overflow has been detected. The XML file contains invalid data in a field that is meant to hold a signed long integer or signed long long integer.


read failed or file prematurely truncated


file exists, is readable, but is empty


mangled locks (unspecified error)


not found / no such file


file version so old we can't read it


didn't recognize the file type


couldn't parse the data in the file


couldn't make a backup of the file


couldn't write to the file


Could not open the file for reading.


file does not specify encoding


No read access permission for the given file


User attempt to write to a directory reserved for internal use by GnuCash


file will be upgraded and not be able to be read by prior versions - warn users


not enough bytes received


wrong kind of server, wrong data served


whatever it is, we can't parse it.


database doesn't contain expected data


database is old and needs upgrading


database is newer, we can't write to it


database is busy, cannot upgrade version


LibDBI has numeric errors


could not complete test for LibDBI bug


Host unknown


can't bind to address


can't accept connection


no connection to server


RPC Version Mismatch


Operation failed


object not added

Definition at line 55 of file qofbackend.h.

56 {
86  /* fileio errors */
104  /* network errors */
109  /* database errors */
117  /* RPC errors */
118  ERR_RPC_HOST_UNK = 4000,
The errors that can be reported to the GUI & other front-end users.
Definition: qofbackend.h:55

Function Documentation

◆ qof_backend_check_error()

gboolean qof_backend_check_error ( QofBackend *  be)

Report if the backend is in an error state. Since get_error resets the error state, its use for branching as the backend bubbles back up to the session would make the session think that there was no error.

beThe backend being tested.
TRUE if the backend has an error set.

Definition at line 68 of file qofbackend.c.

69 {
70  g_return_val_if_fail (be != NULL, TRUE);
71  return be->last_err != ERR_BACKEND_NO_ERR;
72 }

◆ qof_backend_get_error()

QofBackendError qof_backend_get_error ( QofBackend *  be)

The qof_backend_get_error() routine pops an error code off the error stack.

Definition at line 56 of file qofbackend.c.

57 {
58  QofBackendError err;
59  if (!be) return ERR_BACKEND_NO_BACKEND;
61  /* use 'stack-pop' semantics */
62  err = be->last_err;
63  be->last_err = ERR_BACKEND_NO_ERR;
64  return err;
65 }
The errors that can be reported to the GUI & other front-end users.
Definition: qofbackend.h:55

◆ qof_backend_set_error()

void qof_backend_set_error ( QofBackend *  be,
QofBackendError  err 

The qof_backend_set_error() routine pushes an error code onto the error stack. (FIXME: the stack is 1 deep in current implementation).

Definition at line 46 of file qofbackend.c.

47 {
48  if (!be) return;
50  /* use stack-push semantics. Only the earliest error counts */
51  if (ERR_BACKEND_NO_ERR != be->last_err) return;
52  be->last_err = err;
53 }

◆ qof_load_backend_library()

gboolean qof_load_backend_library ( const gchar *  directory,
const gchar *  module_name 

Load a QOF-compatible backend shared library.

directoryCan be NULL if filename is a complete path.
module_nameName of the .la file that describes the shared library. This provides platform independence, courtesy of libtool.
FALSE in case or error, otherwise TRUE.

◆ qof_session_begin()

void qof_session_begin ( QofSession *  session,
const char *  book_id,
gboolean  ignore_lock,
gboolean  create,
gboolean  force 

The qof_session_begin () method begins a new session. It takes as an argument the book id. The book id must be a string in the form of a URI/URL. The access method specified depends on the loaded backends. Paths may be relative or absolute. If the path is relative; that is, if the argument is "file://somefile.xml" then the current working directory is assumed. Customized backends can choose to search other, application-specific, directories as well.

The 'ignore_lock' argument, if set to TRUE, will cause this routine to ignore any global-datastore locks (e.g. file locks) that it finds. If set to FALSE, then file/database-global locks will be tested and obeyed.

If the datastore exists, can be reached (e.g over the net), connected to, opened and read, and a lock can be obtained then a lock will be obtained. Note that while multi-user datastores (e.g. the SQL backend) typically will have record-level locking and therefor should not need to get a global lock, qof works by having a local copy of the whole database and can't be trusted to handle multiple users writing data, so we lock the database anyway.

If qof_session_begin is called with create == TRUE, then it will check for the existence of the file or database and return after posting a QOF_BACKEND_STORE_EXISTS error if it exists, unless force is also set to true.

If an error occurs, it will be pushed onto the session error stack, and that is where it should be examined.

Definition at line 421 of file qofsession.c.

423 {
424  gchar *scheme = NULL, *filename = NULL;
426  if (!session) return;
428  ENTER (" sess=%p ignore_lock=%d, book-id=%s",
429  session, ignore_lock,
430  book_id ? book_id : "(null)");
432  /* Clear the error condition of previous errors */
433  qof_session_clear_error (session);
435  /* Check to see if this session is already open */
436  if (session->book_id)
437  {
438  if (ERR_BACKEND_NO_ERR != qof_session_get_error(session))
439  qof_session_push_error (session, ERR_BACKEND_LOCKED, NULL);
440  LEAVE("push error book is already open ");
441  return;
442  }
444  /* seriously invalid */
445  if (!book_id)
446  {
447  if (ERR_BACKEND_NO_ERR != qof_session_get_error(session))
448  qof_session_push_error (session, ERR_BACKEND_BAD_URL, NULL);
449  LEAVE("push error missing book_id");
450  return;
451  }
452  scheme = g_uri_parse_scheme (book_id);
453  if (g_strcmp0 (scheme, "file") == 0)
454  filename = g_filename_from_uri (book_id, NULL, NULL);
455  else if (!scheme)
456  filename = g_strdup (book_id);
458  if (filename && g_file_test (filename, G_FILE_TEST_IS_DIR))
459  {
460  if (ERR_BACKEND_NO_ERR == qof_session_get_error(session))
461  qof_session_push_error (session, ERR_BACKEND_BAD_URL, NULL);
462  g_free (filename);
463  g_free (scheme);
464  LEAVE("Can't open a directory");
465  return;
466  }
469  /* destroy the old backend */
470  qof_session_destroy_backend(session);
472  /* Store the session URL */
473  session->book_id = g_strdup (book_id);
475  if (filename)
476  qof_session_load_backend(session, "file");
477  else /* access method found, load appropriate backend */
478  qof_session_load_backend(session, scheme);
479  g_free (filename);
480  g_free (scheme);
482  /* No backend was found. That's bad. */
483  if (NULL == session->backend)
484  {
485  g_free(session->book_id);
486  session->book_id = NULL;
487  if (ERR_BACKEND_NO_ERR == qof_session_get_error(session))
488  qof_session_push_error (session, ERR_BACKEND_BAD_URL, NULL);
489  LEAVE (" BAD: no backend: sess=%p book-id=%s",
490  session, book_id ? book_id : "(null)");
491  return;
492  }
494  /* If there's a begin method, call that. */
495  if (session->backend->session_begin)
496  {
497  char *msg;
498  int err;
500  (session->backend->session_begin)(session->backend, session,
501  session->book_id, ignore_lock,
502  create, force);
503  PINFO("Done running session_begin on backend");
504  err = qof_backend_get_error(session->backend);
505  msg = qof_backend_get_message(session->backend);
506  if (err != ERR_BACKEND_NO_ERR)
507  {
508  g_free(session->book_id);
509  session->book_id = NULL;
510  qof_session_push_error (session, err, msg);
511  LEAVE(" backend error %d %s", err, msg ? msg : "(null)");
512  return;
513  }
514  if (msg != NULL)
515  {
516  PWARN("%s", msg);
517  g_free(msg);
518  }
519  }
521  LEAVE (" sess=%p book-id=%s",
522  session, book_id ? book_id : "(null)");
523 }
char * qof_backend_get_message(QofBackend *be)
Definition: qofbackend.c:99
#define PINFO(format, args...)
Definition: qoflog.h:244
#define ENTER(format, args...)
Definition: qoflog.h:256
#define PWARN(format, args...)
Definition: qoflog.h:238
QofBackendError qof_session_get_error(QofSession *session)
Definition: qofsession.c:200
QofBackendError qof_backend_get_error(QofBackend *be)
Definition: qofbackend.c:56
#define LEAVE(format, args...)
Definition: qoflog.h:266

◆ qof_session_end()

void qof_session_end ( QofSession *  session)

The qof_session_end() method will release the session lock. For the file backend, it will not save the data to a file. Thus, this method acts as an "abort" or "rollback" primitive. However, for other backends, such as the sql backend, the data would have been written out before this, and so this routines wouldn't roll-back anything; it would just shut the connection.

Definition at line 809 of file qofsession.c.

810 {
811  if (!session) return;
813  ENTER ("sess=%p book_id=%s", session, session->book_id
814  ? session->book_id : "(null)");
816  /* close down the backend first */
817  if (session->backend && session->backend->session_end)
818  {
819  (session->backend->session_end)(session->backend);
820  }
822  qof_session_clear_error (session);
824  g_free (session->book_id);
825  session->book_id = NULL;
827  LEAVE ("sess=%p book_id=%s", session, session->book_id
828  ? session->book_id : "(null)");
829 }
#define ENTER(format, args...)
Definition: qoflog.h:256
#define LEAVE(format, args...)
Definition: qoflog.h:266

◆ qof_session_get_book()

QofBook* qof_session_get_book ( const QofSession *  session)

Returns the QofBook of this session.

Definition at line 273 of file qofsession.c.

274 {
275  if (!session) return NULL;
276  if (!session->book) return NULL;
278  if ('y' == session->book->book_open)
279  {
280  return session->book;
281  }
282  else
283  {
284  return NULL;
285  }
286 }

◆ qof_session_get_error()

QofBackendError qof_session_get_error ( QofSession *  session)

The qof_session_get_error() routine can be used to obtain the reason for any failure. Calling this routine returns the current error.

Definition at line 200 of file qofsession.c.

201 {
202  QofBackendError err;
204  if (!session) return ERR_BACKEND_NO_BACKEND;
206  /* if we have a local error, return that. */
207  if (ERR_BACKEND_NO_ERR != session->last_err)
208  {
209  return session->last_err;
210  }
212  /* maybe we should return a no-backend error ??? */
213  if (! session->backend) return ERR_BACKEND_NO_ERR;
215  err = qof_backend_get_error (session->backend);
216  session->last_err = err;
217  return err;
218 }
The errors that can be reported to the GUI & other front-end users.
Definition: qofbackend.h:55
QofBackendError qof_backend_get_error(QofBackend *be)
Definition: qofbackend.c:56

◆ qof_session_get_file_path()

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. That is, if a relative or partial filename was for the session, then it had to have been fully resolved to open the session. This routine returns the result of this resolution. The path is always guaranteed to reside in the local file system, even if the session itself was opened as a URL. (currently, the filepath is derived from the url by substituting commas for slashes).

The qof_session_get_url() routine returns the url that was opened. URL's for local files take the form of file:/some/where/some/file.gml

Definition at line 296 of file qofsession.c.

297 {
298  if (!session) return NULL;
299  if (!session->backend) return NULL;
300  return session->backend->fullpath;
301 }

◆ qof_session_pop_error()

QofBackendError qof_session_pop_error ( QofSession *  session)

The qof_session_pop_error() routine can be used to obtain the reason for any failure. Calling this routine resets the error value.

This routine allows an implementation of multiple error values, e.g. in a stack, where this routine pops the top value. The current implementation has a stack that is one-deep.

See qofbackend.h for a listing of returned errors.

Definition at line 236 of file qofsession.c.

237 {
238  QofBackendError err;
240  if (!session) return ERR_BACKEND_NO_BACKEND;
242  err = qof_session_get_error(session);
243  qof_session_clear_error(session);
245  return err;
246 }
The errors that can be reported to the GUI & other front-end users.
Definition: qofbackend.h:55
QofBackendError qof_session_get_error(QofSession *session)
Definition: qofsession.c:200

◆ qof_session_safe_save()

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, then saves everything to new tables, then deletes the old tables after the save is completed without error. If there are errors, it removes the old tables and renames the new tables back.

Definition at line 781 of file qofsession.c.

782 {
783  QofBackend *be = session->backend;
784  gint err;
785  char *msg = NULL;
786  g_return_if_fail( be != NULL );
787  g_return_if_fail( be->safe_sync != NULL );
788  be->percentage = percentage_func;
789  (be->safe_sync)( be, qof_session_get_book( session ));
790  err = qof_backend_get_error(session->backend);
791  msg = qof_backend_get_message(session->backend);
792  if (err != ERR_BACKEND_NO_ERR)
793  {
794  g_free(session->book_id);
795  session->book_id = NULL;
796  qof_session_push_error (session, err, msg);
797  }
798 }
char * qof_backend_get_message(QofBackend *be)
Definition: qofbackend.c:99
QofBook * qof_session_get_book(const QofSession *session)
Definition: qofsession.c:273
QofBackendError qof_backend_get_error(QofBackend *be)
Definition: qofbackend.c:56

◆ qof_session_save()

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. For the file backend, this is nothing more than a write to the file of the current Accounts & etc. For the SQL backend, this is typically a no-op (since all data has already been written out to the database.

check the access_method too, not in scope here, yet.

Definition at line 625 of file qofsession.c.

627 {
628  QofBackend *be;
629  gboolean partial, change_backend;
630  QofBackendProvider *prov;
631  GSList *p;
632  QofBook *book;
633  int err;
634  char *msg = NULL;
635  char *book_id;
637  if (!session) return;
638  if (!g_atomic_int_dec_and_test(&session->lock))
639  goto leave;
640  ENTER ("sess=%p book_id=%s",
641  session, session->book_id ? session->book_id : "(null)");
642  /* Partial book handling. */
643  book = qof_session_get_book(session);
644  partial = (gboolean)GPOINTER_TO_INT(qof_book_get_data(book, PARTIAL_QOFBOOK));
645  change_backend = FALSE;
646  msg = g_strdup_printf(" ");
647  book_id = g_strdup(session->book_id);
648  if (partial == TRUE)
649  {
650  if (session->backend && session->backend->provider)
651  {
652  prov = session->backend->provider;
653  if (TRUE == prov->partial_book_supported)
654  {
655  /* if current backend supports partial, leave alone. */
656  change_backend = FALSE;
657  }
658  else
659  {
660  change_backend = TRUE;
661  }
662  }
663  /* If provider is undefined, assume partial not supported. */
664  else
665  {
666  change_backend = TRUE;
667  }
668  }
669  if (change_backend == TRUE)
670  {
671  qof_session_destroy_backend(session);
672  if (!qof_providers_initialized)
673  {
674  qof_providers_initialized = TRUE;
675  }
676  p = provider_list;
677  while (p != NULL)
678  {
679  prov = p->data;
680  if (TRUE == prov->partial_book_supported)
681  {
683  /* if((TRUE == prov->partial_book_supported) &&
684  (0 == g_ascii_strcasecmp (access_method, prov->access_method)))
685  {*/
686  if (NULL == prov->backend_new) continue;
687  /* Use the providers creation callback */
688  session->backend = (*(prov->backend_new))();
689  session->backend->provider = prov;
690  if (session->backend->session_begin)
691  {
692  /* Call begin - backend has been changed,
693  so make sure a file can be written,
694  use ignore_lock and force create */
695  g_free(session->book_id);
696  session->book_id = NULL;
697  (session->backend->session_begin)(session->backend, session,
698  book_id, TRUE, TRUE, TRUE);
699  PINFO("Done running session_begin on changed backend");
700  err = qof_backend_get_error(session->backend);
701  msg = qof_backend_get_message(session->backend);
702  if (err != ERR_BACKEND_NO_ERR)
703  {
704  g_free(session->book_id);
705  session->book_id = NULL;
706  qof_session_push_error (session, err, msg);
707  LEAVE("changed backend error %d", err);
708  goto leave;
709  }
710  if (msg != NULL)
711  {
712  PWARN("%s", msg);
713  g_free(msg);
714  msg = NULL;
715  }
716  }
717  /* Tell the book about the backend that they'll be using. */
718  qof_book_set_backend (session->book, session->backend);
719  p = NULL;
720  }
721  if (p)
722  {
723  p = p->next;
724  }
725  }
726  if (!session->backend)
727  {
728  if (ERR_BACKEND_NO_ERR != qof_session_get_error(session))
729  {
730  msg = g_strdup_printf("failed to load backend");
731  qof_session_push_error(session, ERR_BACKEND_NO_HANDLER, msg);
732  }
733  goto leave;
734  }
735  }
736  /* If there is a backend, and the backend is reachable
737  * (i.e. we can communicate with it), then synchronize with
738  * the backend. If we cannot contact the backend (e.g.
739  * because we've gone offline, the network has crashed, etc.)
740  * then give the user the option to save to the local disk.
741  *
742  * hack alert -- FIXME -- XXX the code below no longer
743  * does what the words above say. This needs fixing.
744  */
745  be = session->backend;
746  if (be)
747  {
748  /* if invoked as SaveAs(), then backend not yet set */
749  qof_book_set_backend (session->book, be);
750  be->percentage = percentage_func;
751  if (be->sync)
752  {
753  (be->sync)(be, session->book);
754  if (save_error_handler(be, session))
755  goto leave;
756  }
758  /* If we got to here, then the backend saved everything
759  * just fine, and we are done. So return. */
760  /* Return the book_id to previous value. */
761  qof_session_clear_error (session);
762  LEAVE("Success");
763  goto leave;
764  }
765  else
766  {
767  if (ERR_BACKEND_NO_ERR != qof_session_get_error(session))
768  {
769  msg = g_strdup_printf("failed to load backend");
770  qof_session_push_error(session, ERR_BACKEND_NO_HANDLER, msg);
771  }
772  }
773  LEAVE("error -- No backend!");
774 leave:
775  if (msg != NULL) g_free(msg);
776  g_atomic_int_inc(&session->lock);
777  return;
778 }
char * qof_backend_get_message(QofBackend *be)
Definition: qofbackend.c:99
#define PINFO(format, args...)
Definition: qoflog.h:244
#define ENTER(format, args...)
Definition: qoflog.h:256
#define PWARN(format, args...)
Definition: qoflog.h:238
QofBook * qof_session_get_book(const QofSession *session)
Definition: qofsession.c:273
QofBackendError qof_session_get_error(QofSession *session)
Definition: qofsession.c:200
QofBackendError qof_backend_get_error(QofBackend *be)
Definition: qofbackend.c:56
#define LEAVE(format, args...)
Definition: qoflog.h:266
gpointer qof_book_get_data(const QofBook *book, const gchar *key)
Flag indicating a partial QofBook.
Definition: qofreference.h:135

◆ qof_session_save_in_progress()

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't been saved to long-term storage.

Definition at line 803 of file qofsession.c.

804 {
805  return (session && g_atomic_int_get(&session->lock) != 1);
806 }

◆ qof_session_swap_data()

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. It is useful for 'Save As' type functionality.

Definition at line 857 of file qofsession.c.

858 {
859  QofBook *book_1, *book_2;
860  gboolean tmp;
862  if (session_1 == session_2) return;
863  if (!session_1 || !session_2) return;
865  ENTER ("sess1=%p sess2=%p", session_1, session_2);
867  book_1 = session_1->book;
868  book_2 = session_2->book;
870  // Swap the read_only flags backwards.
871  tmp = book_1->read_only;
872  book_1->read_only = book_2->read_only;
873  book_2->read_only = tmp;
875  session_1->book = book_2;
876  session_2->book = book_1;
878  qof_book_set_backend (book_1, session_2->backend);
879  qof_book_set_backend (book_2, session_1->backend);
881  LEAVE (" ");
882 }
#define ENTER(format, args...)
Definition: qoflog.h:256
#define LEAVE(format, args...)
Definition: qoflog.h:266