GnuCash c935c2f+
Loading...
Searching...
No Matches
Public Member Functions | Friends
QofSession Struct Reference

Public Member Functions

 QofSessionImpl (QofBook *book=nullptr) noexcept
 
void begin (const char *new_uri, SessionOpenMode mode) noexcept
 Begin this session.
 
void swap_books (QofSessionImpl &) noexcept
 Swap books with another session.
 
void ensure_all_data_loaded () noexcept
 
void load (QofPercentageFunc) noexcept
 
void save (QofPercentageFunc) noexcept
 
void safe_save (QofPercentageFunc) noexcept
 
bool save_in_progress () const noexcept
 
bool export_session (QofSessionImpl &real_session, QofPercentageFunc) noexcept
 
bool events_pending () const noexcept
 
bool process_events () const noexcept
 
void clear_error () noexcept
 
QofBackendError pop_error () noexcept
 
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 to C code.
 
QofBackendError get_error () noexcept
 Returns and clears the local cached error.
 
const std::string & get_error_message () const noexcept
 
QofBookget_book () const noexcept
 
QofBackendget_backend () const noexcept
 
const std::string & get_file_path () const noexcept
 
bool is_saving () const noexcept
 
void end () noexcept
 Terminates the current backend.
 
void destroy_backend () noexcept
 

Friends

void qof_session_load_backend (QofSession *, const char *)
 
char const * qof_session_get_uri (QofSession *)
 
void qof_session_set_uri (QofSession *, char const *)
 

Detailed Description

Definition at line 37 of file qofsession.hpp.

Constructor & Destructor Documentation

◆ QofSessionImpl()

QofSession::QofSessionImpl ( QofBook book = nullptr)
noexcept

Definition at line 119 of file qofsession.cpp.

120 : m_backend {},
121 m_book {book},
122 m_uri {},
123 m_saving {false},
124 m_last_err {},
125 m_error_message {}
126{
127}

◆ ~QofSessionImpl()

QofSession::~QofSessionImpl ( )
noexcept

Definition at line 129 of file qofsession.cpp.

130{
131 ENTER ("sess=%p uri=%s", this, m_uri.c_str ());
132 end ();
133 destroy_backend ();
134 qof_book_set_backend (m_book, nullptr);
135 qof_book_destroy (m_book);
136 m_book = nullptr;
137 LEAVE ("sess=%p", this);
138}
void qof_book_destroy(QofBook *book)
End any editing sessions associated with book, and free all memory associated with it.
Definition qofbook.cpp:331
#define LEAVE(format, args...)
Print a function exit debugging message.
Definition qoflog.h:282
#define ENTER(format, args...)
Print a function entry debugging message.
Definition qoflog.h:272
void end() noexcept
Terminates the current backend.

Member Function Documentation

◆ begin()

void QofSession::begin ( const char *  new_uri,
SessionOpenMode  mode 
)
noexcept

Begin this session.


Definition at line 251 of file qofsession.cpp.

252{
253
254
255 ENTER (" sess=%p mode=%d, URI=%s", this, mode, new_uri);
256 clear_error ();
257 /* Check to see if this session is already open */
258 if (m_uri.size ())
259 {
260 if (ERR_BACKEND_NO_ERR != get_error ())
261 push_error (ERR_BACKEND_LOCKED, {});
262 LEAVE("push error book is already open ");
263 return;
264 }
265
266 /* seriously invalid */
267 if (!new_uri)
268 {
269 if (ERR_BACKEND_NO_ERR != get_error ())
270 push_error (ERR_BACKEND_BAD_URL, {});
271 LEAVE("push error missing new_uri");
272 return;
273 }
274
275 char * scheme {g_uri_parse_scheme (new_uri)};
276 char * filename {nullptr};
277 if (g_strcmp0 (scheme, "file") == 0)
278 filename = gnc_uri_get_path(new_uri);
279 else if (!scheme)
280 filename = g_strdup (new_uri);
281
282 if (filename && g_file_test (filename, G_FILE_TEST_IS_DIR))
283 {
284 if (ERR_BACKEND_NO_ERR == get_error ())
285 push_error (ERR_BACKEND_BAD_URL, {});
286 g_free (filename);
287 g_free (scheme);
288 LEAVE("Can't open a directory");
289 return;
290 }
291 /* destroy the old backend */
292 destroy_backend ();
293 /* Store the session URL */
294 m_uri = new_uri;
295 m_creating = mode == SESSION_NEW_STORE || mode == SESSION_NEW_OVERWRITE;
296 if (filename)
297 load_backend ("file");
298 else /* access method found, load appropriate backend */
299 load_backend (scheme);
300 g_free (filename);
301 g_free (scheme);
302
303 /* No backend was found. That's bad. */
304 if (m_backend == nullptr)
305 {
306 m_uri = {};
307 if (ERR_BACKEND_NO_ERR == get_error ())
308 push_error (ERR_BACKEND_BAD_URL, {});
309 LEAVE (" BAD: no backend: sess=%p book-id=%s",
310 this, new_uri);
311 return;
312 }
313
314 /* If there's a begin method, call that. */
315 m_backend->session_begin(this, m_uri.c_str(), mode);
316 PINFO ("Done running session_begin on backend");
317 QofBackendError const err {m_backend->get_error()};
318 auto msg (m_backend->get_message());
319 if (err != ERR_BACKEND_NO_ERR)
320 {
321 m_uri = {};
322 push_error (err, msg);
323 LEAVE (" backend error %d %s", err, msg.empty() ? "(null)" : msg.c_str());
324 return;
325 }
326 if (!msg.empty())
327 {
328 PWARN("%s", msg.c_str());
329 }
330
331 LEAVE (" sess=%p book-id=%s", this, new_uri);
332}
QofBackendError
The errors that can be reported to the GUI & other front-end users.
Definition qofbackend.h:58
@ ERR_BACKEND_BAD_URL
Can't parse url.
Definition qofbackend.h:62
@ SESSION_NEW_STORE
Open will fail if the URI doesn't exist or is locked.
Definition qofsession.h:124
@ SESSION_NEW_OVERWRITE
Create a new store at the URI.
Definition qofsession.h:126
#define PINFO(format, args...)
Print an informational note.
Definition qoflog.h:256
#define PWARN(format, args...)
Log a warning.
Definition qoflog.h:250
virtual void session_begin(QofSession *session, const char *new_uri, SessionOpenMode mode)=0
Open the file or connect to the server.
const std::string && get_message()
Retrieve and clear the stored error message.
QofBackendError get_error()
Retrieve the currently-stored error and clear it.
gchar * gnc_uri_get_path(const gchar *uri)
Extracts the path part from a uri.
QofBackendError get_error() noexcept
Returns and clears the local cached error.

◆ clear_error()

void QofSession::clear_error ( )
noexcept

Definition at line 348 of file qofsession.cpp.

349{
350 m_last_err = ERR_BACKEND_NO_ERR;
351 m_error_message = {};
352
353 /* pop the stack on the backend as well. */
354 if (auto backend = qof_book_get_backend (m_book))
355 {
356 QofBackendError err = ERR_BACKEND_NO_ERR;
357 do
358 err = backend->get_error();
359 while (err != ERR_BACKEND_NO_ERR);
360 }
361}
QofBackend * qof_book_get_backend(const QofBook *book)
Retrieve the backend used by this book.
Definition qofbook.cpp:440

◆ destroy_backend()

void QofSession::destroy_backend ( )
noexcept

Definition at line 153 of file qofsession.cpp.

154{
155 if (m_backend)
156 {
157 clear_error ();
158 delete m_backend;
159 m_backend = nullptr;
160 qof_book_set_backend (m_book, nullptr);
161 }
162}

◆ end()

void QofSession::end ( )
noexcept

Terminates the current backend.

Definition at line 335 of file qofsession.cpp.

336{
337 ENTER ("sess=%p uri=%s", this, m_uri.c_str ());
338 if (m_backend != nullptr)
339 m_backend->session_end();
340 clear_error ();
341 m_uri.clear();
342 LEAVE ("sess=%p uri=%s", this, m_uri.c_str ());
343}

◆ ensure_all_data_loaded()

void QofSession::ensure_all_data_loaded ( )
noexcept

Definition at line 495 of file qofsession.cpp.

496{
497 if (!(m_backend && m_book)) return;
498 if (qof_book_get_backend (m_book) != m_backend)
499 qof_book_set_backend (m_book, m_backend);
500 m_backend->load(m_book, LOAD_TYPE_LOAD_ALL);
501 push_error (m_backend->get_error(), {});
502}
virtual void load(QofBook *, QofBackendLoadType)=0
Load the minimal set of application data needed for the application to be operable at initial startup...

◆ events_pending()

bool QofSession::events_pending ( ) const
noexcept

Definition at line 519 of file qofsession.cpp.

520{
521 return false;
522}

◆ export_session()

bool QofSession::export_session ( QofSessionImpl real_session,
QofPercentageFunc  percentage_func 
)
noexcept

Definition at line 535 of file qofsession.cpp.

537{
538 auto real_book = real_session.get_book ();
539 ENTER ("tmp_session=%p real_session=%p book=%p uri=%s",
540 this, &real_session, real_book, m_uri.c_str ());
541
542 /* There must be a backend or else. (It should always be the file
543 * backend too.)
544 */
545 if (!m_backend) return false;
546
547 m_backend->set_percentage(percentage_func);
548
549 m_backend->export_coa(real_book);
550 auto err = m_backend->get_error();
551 if (err != ERR_BACKEND_NO_ERR)
552 return false;
553 return true;
554}
void set_percentage(QofBePercentageFunc pctfn)
Store and retrieve a backend-specific function for determining the progress in completing a long oper...
virtual void export_coa(QofBook *)
Extract the chart of accounts from the current database and create a new database with it.

◆ get_book()

QofBook * QofSession::get_book ( ) const
noexcept

Definition at line 400 of file qofsession.cpp.

401{
402 if (!m_book) return nullptr;
403 if (qof_book_is_open (m_book))
404 return m_book;
405 return nullptr;
406}

◆ get_error()

QofBackendError QofSession::get_error ( )
noexcept

Returns and clears the local cached error.

If there is no local error, we check for an error in the backend.

Definition at line 371 of file qofsession.cpp.

372{
373 /* if we have a local error, return that. */
374 if (m_last_err != ERR_BACKEND_NO_ERR)
375 return m_last_err;
376 auto qof_be = qof_book_get_backend (m_book);
377 if (qof_be == nullptr) return ERR_BACKEND_NO_ERR;
378
379 m_last_err = qof_be->get_error();
380 return m_last_err;
381}

◆ get_error_message()

const std::string & QofSession::get_error_message ( ) const
noexcept

Definition at line 384 of file qofsession.cpp.

385{
386 return m_error_message;
387}

◆ get_file_path()

const std::string & QofSession::get_file_path ( ) const
noexcept

Definition at line 415 of file qofsession.cpp.

416{
417 auto backend = qof_book_get_backend (m_book);
418 if (!backend) return empty_string;
419 return backend->get_uri();
420}

◆ get_uri()

std::string const & QofSession::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 to C code.

Definition at line 423 of file qofsession.cpp.

424{
425 return m_uri;
426}

◆ is_saving()

bool QofSession::is_saving ( ) const
noexcept

Definition at line 429 of file qofsession.cpp.

430{
431 return m_saving;
432}

◆ load()

void QofSession::load ( QofPercentageFunc  percentage_func)
noexcept

Definition at line 199 of file qofsession.cpp.

200{
201 /* We must have an empty book to load into or bad things will happen. */
202 g_return_if_fail(m_book && qof_book_empty(m_book));
203
204 if (!m_uri.size ()) return;
205 ENTER ("sess=%p uri=%s", this, m_uri.c_str ());
206
207 /* At this point, we should are supposed to have a valid book
208 * id and a lock on the file. */
209 clear_error ();
210
211 /* This code should be sufficient to initialize *any* backend,
212 * whether http, postgres, or anything else that might come along.
213 * Basically, the idea is that by now, a backend has already been
214 * created & set up. At this point, we only need to get the
215 * top-level account group out of the backend, and that is a
216 * generic, backend-independent operation.
217 */
218 qof_book_set_backend (m_book, m_backend);
219
220 /* Starting the session should result in a bunch of accounts
221 * and currencies being downloaded, but probably no transactions;
222 * The GUI will need to do a query for that.
223 */
224 if (m_backend)
225 {
226 m_backend->set_percentage(percentage_func);
227 m_backend->load (m_book, LOAD_TYPE_INITIAL_LOAD);
228 push_error (m_backend->get_error(), {});
229 }
230
231 auto err = get_error ();
232 if ((err != ERR_BACKEND_NO_ERR) &&
233 (err != ERR_FILEIO_FILE_TOO_OLD) &&
234 (err != ERR_FILEIO_NO_ENCODING) &&
235 (err != ERR_FILEIO_FILE_UPGRADE) &&
236 (err != ERR_SQL_DB_TOO_OLD) &&
237 (err != ERR_SQL_DB_TOO_NEW))
238 {
239 // Something failed, delete and restore new ones.
240 destroy_backend();
241 qof_book_destroy (m_book);
242 m_book = qof_book_new();
243 LEAVE ("error from backend %d", get_error ());
244 return;
245 }
246
247 LEAVE ("sess = %p, uri=%s", this, m_uri.c_str ());
248}
@ ERR_FILEIO_NO_ENCODING
file does not specify encoding
Definition qofbackend.h:99
@ ERR_SQL_DB_TOO_OLD
database is old and needs upgrading
Definition qofbackend.h:113
@ ERR_SQL_DB_TOO_NEW
database is newer, we can't write to it
Definition qofbackend.h:114
@ ERR_FILEIO_FILE_UPGRADE
file will be upgraded and not be able to be read by prior versions - warn users
Definition qofbackend.h:103
@ ERR_FILEIO_FILE_TOO_OLD
file version so old we can't read it
Definition qofbackend.h:93
QofBook * qof_book_new(void)
Allocate, initialise and return a new QofBook.
Definition qofbook.cpp:290
gboolean qof_book_empty(const QofBook *book)
Check if the book has had anything loaded into it.
Definition qofbook.cpp:511

◆ pop_error()

QofBackendError QofSession::pop_error ( )
noexcept

Definition at line 390 of file qofsession.cpp.

391{
392 QofBackendError err {get_error ()};
393 clear_error ();
394 return err;
395}

◆ process_events()

bool QofSession::process_events ( ) const
noexcept

Definition at line 525 of file qofsession.cpp.

526{
527 return false;
528}

◆ safe_save()

void QofSession::safe_save ( QofPercentageFunc  percentage_func)
noexcept

Definition at line 478 of file qofsession.cpp.

479{
480 if (!(m_backend && m_book)) return;
481 if (qof_book_get_backend (m_book) != m_backend)
482 qof_book_set_backend (m_book, m_backend);
483 m_backend->set_percentage(percentage_func);
484 m_backend->safe_sync(get_book ());
485 auto err = m_backend->get_error();
486 auto msg = m_backend->get_message();
487 if (err != ERR_BACKEND_NO_ERR)
488 {
489 m_uri = "";
490 push_error (err, msg);
491 }
492}
virtual void safe_sync(QofBook *)=0
Perform a sync in a way that prevents data loss on a DBI backend.

◆ save()

void QofSession::save ( QofPercentageFunc  percentage_func)
noexcept

Definition at line 437 of file qofsession.cpp.

438{
439 if (!qof_book_session_not_saved (m_book)) //Clean book, nothing to do.
440 return;
441 m_saving = true;
442 ENTER ("sess=%p uri=%s", this, m_uri.c_str ());
443
444 /* If there is a backend, the book is dirty, and the backend is reachable
445 * (i.e. we can communicate with it), then synchronize with the backend. If
446 * we cannot contact the backend (e.g. because we've gone offline, the
447 * network has crashed, etc.) then raise an error so that the controlling
448 * dialog can offer the user a chance to save in a different way.
449 */
450 if (m_backend)
451 {
452 /* if invoked as SaveAs(), then backend not yet set */
453 if (qof_book_get_backend (m_book) != m_backend)
454 qof_book_set_backend (m_book, m_backend);
455 m_backend->set_percentage(percentage_func);
456 m_backend->sync(m_book);
457 auto err = m_backend->get_error();
458 if (err != ERR_BACKEND_NO_ERR)
459 {
460 push_error (err, {});
461 m_saving = false;
462 return;
463 }
464 /* If we got to here, then the backend saved everything
465 * just fine, and we are done. So return. */
466 clear_error ();
467 LEAVE("Success");
468 }
469 else
470 {
471 push_error (ERR_BACKEND_NO_HANDLER, "failed to load backend");
472 LEAVE("error -- No backend!");
473 }
474 m_saving = false;
475}
@ ERR_BACKEND_NO_HANDLER
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:375
virtual void sync(QofBook *)=0
Synchronizes the engine contents to the backend.

◆ swap_books()

void QofSession::swap_books ( QofSessionImpl other)
noexcept

Swap books with another session.

Definition at line 505 of file qofsession.cpp.

506{
507 ENTER ("sess1=%p sess2=%p", this, &other);
508 // don't swap (that is, double-swap) read_only flags
509 if (m_book && other.m_book)
510 qof_book_swap_books_readonly (m_book, other.m_book);
511 std::swap (m_book, other.m_book);
512 auto mybackend = qof_book_get_backend (m_book);
513 qof_book_set_backend (m_book, qof_book_get_backend (other.m_book));
514 qof_book_set_backend (other.m_book, mybackend);
515 LEAVE (" ");
516}

Friends And Related Symbol Documentation

◆ qof_session_load_backend

void qof_session_load_backend ( QofSession *  session,
const char *  access_method 
)
friend

Definition at line 688 of file qofsession.cpp.

689{
690 session->load_backend (access_method);
691}

◆ qof_session_set_uri

void qof_session_set_uri ( QofSession *  session,
char const *  uri 
)
friend

Definition at line 705 of file qofsession.cpp.

706{
707 if (!uri)
708 session->m_uri = "";
709 else
710 session->m_uri = uri;
711}

The documentation for this struct was generated from the following files: