2005-11-07 09:45:58 -06:00
|
|
|
/********************************************************************\
|
2016-06-05 12:14:45 -05:00
|
|
|
* qofsesssion.cpp -- session access (connection to backend) *
|
2005-11-07 09:45:58 -06:00
|
|
|
* *
|
|
|
|
* This program is free software; you can redistribute it and/or *
|
|
|
|
* modify it under the terms of the GNU General Public License as *
|
|
|
|
* published by the Free Software Foundation; either version 2 of *
|
|
|
|
* the License, or (at your option) any later version. *
|
|
|
|
* *
|
|
|
|
* This program is distributed in the hope that it will be useful, *
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
|
|
* GNU General Public License for more details. *
|
|
|
|
* *
|
|
|
|
* You should have received a copy of the GNU General Public License*
|
|
|
|
* along with this program; if not, contact: *
|
|
|
|
* *
|
|
|
|
* Free Software Foundation Voice: +1-617-542-5942 *
|
2005-11-16 23:35:02 -06:00
|
|
|
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
|
|
|
|
* Boston, MA 02110-1301, USA gnu@gnu.org *
|
2005-11-07 09:45:58 -06:00
|
|
|
\********************************************************************/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @file qofsession.c
|
|
|
|
* @brief Encapsulate a connection to a storage backend.
|
|
|
|
*
|
|
|
|
* HISTORY:
|
|
|
|
* Created by Linas Vepstas December 1998
|
|
|
|
|
|
|
|
@author Copyright (c) 1998-2004 Linas Vepstas <linas@linas.org>
|
|
|
|
@author Copyright (c) 2000 Dave Peticolas
|
|
|
|
@author Copyright (c) 2005 Neil Williams <linux@codehelp.co.uk>
|
2016-06-05 12:14:45 -05:00
|
|
|
@author Copyright (c) 2016 Aaron Laws
|
2005-11-07 12:23:46 -06:00
|
|
|
*/
|
2005-11-07 09:45:58 -06:00
|
|
|
|
2016-02-16 19:11:55 -06:00
|
|
|
extern "C"
|
|
|
|
{
|
|
|
|
|
2017-10-26 04:14:21 -05:00
|
|
|
#include <config.h>
|
2005-11-07 09:45:58 -06:00
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
2010-02-24 11:38:14 -06:00
|
|
|
#ifdef HAVE_UNISTD_H
|
|
|
|
# include <unistd.h>
|
|
|
|
#else
|
|
|
|
# ifdef __GNUC__
|
|
|
|
# warning "<unistd.h> required."
|
|
|
|
# endif
|
|
|
|
#endif
|
2005-11-07 09:45:58 -06:00
|
|
|
|
|
|
|
#include <glib.h>
|
2006-01-08 11:51:29 -06:00
|
|
|
#include "qof.h"
|
|
|
|
#include "qofobject-p.h"
|
2005-11-07 09:45:58 -06:00
|
|
|
|
|
|
|
static QofLogModule log_module = QOF_MOD_SESSION;
|
2016-02-16 19:11:55 -06:00
|
|
|
} //extern 'C'
|
|
|
|
|
2017-10-05 11:48:37 -05:00
|
|
|
#include "qofbook-p.h"
|
2016-11-27 16:12:43 -06:00
|
|
|
#include "qof-backend.hpp"
|
2016-06-05 12:14:45 -05:00
|
|
|
#include "qofsession.hpp"
|
2016-02-16 19:11:55 -06:00
|
|
|
#include "gnc-backend-prov.hpp"
|
2005-11-07 09:45:58 -06:00
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
#include <vector>
|
|
|
|
#include <boost/algorithm/string.hpp>
|
2016-02-16 19:11:55 -06:00
|
|
|
#include <vector>
|
|
|
|
#include <algorithm>
|
|
|
|
#include <string>
|
|
|
|
#include <sstream>
|
|
|
|
|
|
|
|
using ProviderVec = std::vector<QofBackendProvider_ptr>;
|
|
|
|
static ProviderVec s_providers;
|
2012-01-09 17:09:47 -06:00
|
|
|
/*
|
|
|
|
* These getters are used in tests to reach static vars from outside
|
|
|
|
* They should be removed when no longer needed
|
|
|
|
*/
|
|
|
|
|
2016-02-16 19:11:55 -06:00
|
|
|
ProviderVec& get_providers (void );
|
|
|
|
bool get_providers_initialized (void );
|
2012-01-09 17:09:47 -06:00
|
|
|
|
2016-02-16 19:11:55 -06:00
|
|
|
ProviderVec&
|
|
|
|
get_providers (void)
|
2012-03-16 15:27:09 -05:00
|
|
|
{
|
2016-02-16 19:11:55 -06:00
|
|
|
return s_providers;
|
2012-03-16 15:27:09 -05:00
|
|
|
}
|
2012-01-09 17:09:47 -06:00
|
|
|
|
2016-02-16 19:11:55 -06:00
|
|
|
bool
|
|
|
|
get_providers_initialized (void)
|
2012-03-16 15:27:09 -05:00
|
|
|
{
|
2016-02-16 19:11:55 -06:00
|
|
|
return !s_providers.empty();
|
2012-03-16 15:27:09 -05:00
|
|
|
}
|
2012-01-09 17:09:47 -06:00
|
|
|
|
|
|
|
void
|
2016-06-05 12:14:45 -05:00
|
|
|
qof_backend_register_provider (QofBackendProvider_ptr&& prov)
|
2012-01-09 17:09:47 -06:00
|
|
|
{
|
2016-06-05 12:14:45 -05:00
|
|
|
s_providers.emplace_back(std::move(prov));
|
2012-01-09 17:09:47 -06:00
|
|
|
}
|
|
|
|
|
2005-11-07 09:45:58 -06:00
|
|
|
void
|
2016-06-05 12:14:45 -05:00
|
|
|
qof_backend_unregister_all_providers ()
|
2005-11-07 09:45:58 -06:00
|
|
|
{
|
2016-06-05 12:14:45 -05:00
|
|
|
s_providers.clear ();
|
2005-11-07 09:45:58 -06:00
|
|
|
}
|
|
|
|
|
2016-02-16 19:11:55 -06:00
|
|
|
/* Called from C so we have to keep the GList for now. */
|
2008-08-01 11:02:07 -05:00
|
|
|
GList*
|
|
|
|
qof_backend_get_registered_access_method_list(void)
|
|
|
|
{
|
2009-09-18 14:40:57 -05:00
|
|
|
GList* list = NULL;
|
2016-02-16 19:11:55 -06:00
|
|
|
std::for_each(s_providers.begin(), s_providers.end(),
|
|
|
|
[&list](QofBackendProvider_ptr& provider) {
|
|
|
|
gpointer method = reinterpret_cast<gpointer>(const_cast<char*>(provider->access_method));
|
|
|
|
list = g_list_prepend(list, method);
|
|
|
|
});
|
2009-09-18 14:40:57 -05:00
|
|
|
return list;
|
2008-08-01 11:02:07 -05:00
|
|
|
}
|
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
/* QofSessionImpl */
|
2005-11-07 09:45:58 -06:00
|
|
|
/* ====================================================================== */
|
2016-06-05 12:14:45 -05:00
|
|
|
/* Constructor/Destructor ----------------------------------*/
|
2005-11-07 09:45:58 -06:00
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
QofSessionImpl::QofSessionImpl () noexcept
|
|
|
|
: m_book {qof_book_new ()},
|
|
|
|
m_book_id {},
|
|
|
|
m_saving {false},
|
2016-11-28 12:27:09 -06:00
|
|
|
m_last_err {},
|
2016-06-05 12:14:45 -05:00
|
|
|
m_error_message {}
|
2005-11-07 09:45:58 -06:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
QofSessionImpl::~QofSessionImpl () noexcept
|
2005-11-07 09:45:58 -06:00
|
|
|
{
|
2016-06-05 12:14:45 -05:00
|
|
|
ENTER ("sess=%p book_id=%s", this, m_book_id.c_str ());
|
|
|
|
end ();
|
|
|
|
destroy_backend ();
|
|
|
|
qof_book_set_backend (m_book, nullptr);
|
|
|
|
qof_book_destroy (m_book);
|
|
|
|
m_book = nullptr;
|
|
|
|
LEAVE ("sess=%p", this);
|
2005-11-07 09:45:58 -06:00
|
|
|
}
|
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
void
|
|
|
|
qof_session_destroy (QofSession * session)
|
2005-11-07 09:45:58 -06:00
|
|
|
{
|
2016-06-05 12:14:45 -05:00
|
|
|
delete session;
|
2005-11-07 09:45:58 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
QofSession *
|
|
|
|
qof_session_new (void)
|
|
|
|
{
|
2016-06-05 12:14:45 -05:00
|
|
|
return new QofSessionImpl;
|
2005-11-07 09:45:58 -06:00
|
|
|
}
|
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
void
|
|
|
|
QofSessionImpl::destroy_backend () noexcept
|
2005-11-07 09:45:58 -06:00
|
|
|
{
|
2016-06-05 12:14:45 -05:00
|
|
|
auto backend = qof_book_get_backend (m_book);
|
|
|
|
if (backend)
|
2009-09-18 14:40:57 -05:00
|
|
|
{
|
2016-06-05 12:14:45 -05:00
|
|
|
clear_error ();
|
2016-11-28 12:27:09 -06:00
|
|
|
delete backend;
|
2016-06-05 12:14:45 -05:00
|
|
|
qof_book_set_backend (m_book, nullptr);
|
2009-09-18 14:40:57 -05:00
|
|
|
}
|
2005-11-07 09:45:58 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ====================================================================== */
|
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
void
|
|
|
|
QofSessionImpl::load_backend (std::string access_method) noexcept
|
2005-11-07 09:45:58 -06:00
|
|
|
{
|
2017-03-14 23:23:12 -05:00
|
|
|
std::ostringstream s;
|
|
|
|
s << " list=" << s_providers.size();
|
|
|
|
ENTER ("%s", s.str().c_str());
|
2016-06-05 12:14:45 -05:00
|
|
|
for (auto const & prov : s_providers)
|
2009-09-18 14:40:57 -05:00
|
|
|
{
|
2016-06-05 12:14:45 -05:00
|
|
|
if (!boost::iequals (access_method, prov->access_method))
|
|
|
|
{
|
|
|
|
PINFO ("The provider providers access_method, %s, but we're loading for access_method, %s. Skipping.",
|
|
|
|
prov->access_method, access_method.c_str ());
|
2016-02-16 19:11:55 -06:00
|
|
|
continue;
|
2016-06-05 12:14:45 -05:00
|
|
|
}
|
|
|
|
PINFO (" Selected provider %s", prov->provider_name);
|
2018-07-06 15:00:08 -05:00
|
|
|
// Only do a type check when trying to open an existing file
|
|
|
|
// When saving over an existing file the contents of the original file don't matter
|
|
|
|
if (!m_creating && !prov->type_check (m_book_id.c_str ()))
|
2009-09-18 14:40:57 -05:00
|
|
|
{
|
2016-06-05 12:14:45 -05:00
|
|
|
PINFO("Provider, %s, reported not being usable for book, %s.",
|
|
|
|
prov->provider_name, m_book_id.c_str ());
|
2016-02-16 19:11:55 -06:00
|
|
|
continue;
|
2009-09-18 14:40:57 -05:00
|
|
|
}
|
2016-06-05 12:14:45 -05:00
|
|
|
auto backend = prov->create_backend();
|
|
|
|
qof_book_set_backend (m_book, backend);
|
2016-02-16 19:11:55 -06:00
|
|
|
LEAVE (" ");
|
|
|
|
return;
|
2009-09-18 14:40:57 -05:00
|
|
|
}
|
2016-06-05 12:14:45 -05:00
|
|
|
std::string msg {"failed to get_backend using access method \"" + access_method + "\""};
|
|
|
|
push_error (ERR_BACKEND_NO_HANDLER, msg);
|
2009-09-18 14:40:57 -05:00
|
|
|
LEAVE (" ");
|
2005-11-07 09:45:58 -06:00
|
|
|
}
|
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
void
|
|
|
|
QofSessionImpl::load (QofPercentageFunc percentage_func) noexcept
|
2005-11-07 09:45:58 -06:00
|
|
|
{
|
2018-09-23 18:30:30 -05:00
|
|
|
/* We must have an empty book to load into or bad things will happen. */
|
|
|
|
g_return_if_fail(m_book && qof_book_empty(m_book));
|
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
if (!m_book_id.size ()) return;
|
|
|
|
ENTER ("sess=%p book_id=%s", this, m_book_id.c_str ());
|
2005-11-07 09:45:58 -06:00
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
/* At this point, we should are supposed to have a valid book
|
|
|
|
* id and a lock on the file. */
|
|
|
|
clear_error ();
|
2018-09-23 18:30:30 -05:00
|
|
|
auto be (qof_book_get_backend(m_book));
|
2016-06-05 12:14:45 -05:00
|
|
|
if (be)
|
|
|
|
{
|
2016-11-28 12:27:09 -06:00
|
|
|
be->set_percentage(percentage_func);
|
2018-09-23 18:30:30 -05:00
|
|
|
be->load (m_book, LOAD_TYPE_INITIAL_LOAD);
|
2016-11-28 12:27:09 -06:00
|
|
|
push_error (be->get_error(), {});
|
2005-11-07 09:45:58 -06:00
|
|
|
}
|
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
auto err = get_error ();
|
|
|
|
if ((err != ERR_BACKEND_NO_ERR) &&
|
|
|
|
(err != ERR_FILEIO_FILE_TOO_OLD) &&
|
|
|
|
(err != ERR_FILEIO_NO_ENCODING) &&
|
|
|
|
(err != ERR_FILEIO_FILE_UPGRADE) &&
|
|
|
|
(err != ERR_SQL_DB_TOO_OLD) &&
|
|
|
|
(err != ERR_SQL_DB_TOO_NEW))
|
|
|
|
{
|
2018-10-04 17:44:32 -05:00
|
|
|
auto old_book = m_book;
|
2018-09-23 18:30:30 -05:00
|
|
|
m_book = qof_book_new();
|
2018-10-04 17:44:32 -05:00
|
|
|
qof_book_destroy(old_book);
|
2016-06-05 12:14:45 -05:00
|
|
|
LEAVE ("error from backend %d", get_error ());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
LEAVE ("sess = %p, book_id=%s", this, m_book_id.c_str ());
|
2005-11-07 09:45:58 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2016-11-28 12:27:09 -06:00
|
|
|
QofSessionImpl::begin (std::string new_book_id, bool ignore_lock,
|
|
|
|
bool create, bool force) noexcept
|
2005-11-07 09:45:58 -06:00
|
|
|
{
|
2009-09-18 14:40:57 -05:00
|
|
|
ENTER (" sess=%p ignore_lock=%d, book-id=%s",
|
2016-06-05 12:14:45 -05:00
|
|
|
this, ignore_lock, new_book_id.c_str ());
|
|
|
|
clear_error ();
|
2009-09-18 14:40:57 -05:00
|
|
|
/* Check to see if this session is already open */
|
2016-06-05 12:14:45 -05:00
|
|
|
if (m_book_id.size ())
|
2009-09-18 14:40:57 -05:00
|
|
|
{
|
2016-06-05 12:14:45 -05:00
|
|
|
if (ERR_BACKEND_NO_ERR != get_error ())
|
|
|
|
push_error (ERR_BACKEND_LOCKED, {});
|
2009-09-18 14:40:57 -05:00
|
|
|
LEAVE("push error book is already open ");
|
|
|
|
return;
|
|
|
|
}
|
2005-11-07 09:45:58 -06:00
|
|
|
|
2009-09-18 14:40:57 -05:00
|
|
|
/* seriously invalid */
|
2016-06-05 12:14:45 -05:00
|
|
|
if (!new_book_id.size ())
|
2009-09-18 14:40:57 -05:00
|
|
|
{
|
2016-06-05 12:14:45 -05:00
|
|
|
if (ERR_BACKEND_NO_ERR != get_error ())
|
|
|
|
push_error (ERR_BACKEND_BAD_URL, {});
|
|
|
|
LEAVE("push error missing new_book_id");
|
2009-09-18 14:40:57 -05:00
|
|
|
return;
|
|
|
|
}
|
2016-06-05 12:14:45 -05:00
|
|
|
|
|
|
|
char * scheme {g_uri_parse_scheme (new_book_id.c_str ())};
|
|
|
|
char * filename {nullptr};
|
Handle specifying a directory as a dataset file.
The file chooser dialog would return a directory if the user selected
one and clicked "Open"; then, or if the users specified a directory on
the command line, Gnucash would present the rather misleading error "No
backend found".
So, first, if the user selects a directory and clicks open, the chooser
will now open the directory for browsing, just as if she had
double-clicked on the directory name in the tree view.
Next, if a directory is presented to qof_session_begin it will detect
that and set ERR_BACKEND_BAD_URL, which gnc_post_file_open will detect
and re-present the file chooser, open to that directory. (To prevent
confusion, gnc_post_file_open will put up the error dialog for BAD_URL;
the new file chooser dialog will open after that's dismissed. Since
there are other possible causes of a BAD_URL, if the filename isn't a
directory the chooser will open to the registered default directory from
GConf.)
BP
git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@21459 57a11ea4-9604-0410-9ed3-97b8803252fd
2011-10-18 19:02:59 -05:00
|
|
|
if (g_strcmp0 (scheme, "file") == 0)
|
2016-06-05 12:14:45 -05:00
|
|
|
filename = g_filename_from_uri (new_book_id.c_str (), nullptr, nullptr);
|
Handle specifying a directory as a dataset file.
The file chooser dialog would return a directory if the user selected
one and clicked "Open"; then, or if the users specified a directory on
the command line, Gnucash would present the rather misleading error "No
backend found".
So, first, if the user selects a directory and clicks open, the chooser
will now open the directory for browsing, just as if she had
double-clicked on the directory name in the tree view.
Next, if a directory is presented to qof_session_begin it will detect
that and set ERR_BACKEND_BAD_URL, which gnc_post_file_open will detect
and re-present the file chooser, open to that directory. (To prevent
confusion, gnc_post_file_open will put up the error dialog for BAD_URL;
the new file chooser dialog will open after that's dismissed. Since
there are other possible causes of a BAD_URL, if the filename isn't a
directory the chooser will open to the registered default directory from
GConf.)
BP
git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@21459 57a11ea4-9604-0410-9ed3-97b8803252fd
2011-10-18 19:02:59 -05:00
|
|
|
else if (!scheme)
|
2016-06-05 12:14:45 -05:00
|
|
|
filename = g_strdup (new_book_id.c_str ());
|
Handle specifying a directory as a dataset file.
The file chooser dialog would return a directory if the user selected
one and clicked "Open"; then, or if the users specified a directory on
the command line, Gnucash would present the rather misleading error "No
backend found".
So, first, if the user selects a directory and clicks open, the chooser
will now open the directory for browsing, just as if she had
double-clicked on the directory name in the tree view.
Next, if a directory is presented to qof_session_begin it will detect
that and set ERR_BACKEND_BAD_URL, which gnc_post_file_open will detect
and re-present the file chooser, open to that directory. (To prevent
confusion, gnc_post_file_open will put up the error dialog for BAD_URL;
the new file chooser dialog will open after that's dismissed. Since
there are other possible causes of a BAD_URL, if the filename isn't a
directory the chooser will open to the registered default directory from
GConf.)
BP
git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@21459 57a11ea4-9604-0410-9ed3-97b8803252fd
2011-10-18 19:02:59 -05:00
|
|
|
|
|
|
|
if (filename && g_file_test (filename, G_FILE_TEST_IS_DIR))
|
|
|
|
{
|
2016-06-05 12:14:45 -05:00
|
|
|
if (ERR_BACKEND_NO_ERR == get_error ())
|
|
|
|
push_error (ERR_BACKEND_BAD_URL, {});
|
2012-01-01 14:36:46 -06:00
|
|
|
g_free (filename);
|
|
|
|
g_free (scheme);
|
Handle specifying a directory as a dataset file.
The file chooser dialog would return a directory if the user selected
one and clicked "Open"; then, or if the users specified a directory on
the command line, Gnucash would present the rather misleading error "No
backend found".
So, first, if the user selects a directory and clicks open, the chooser
will now open the directory for browsing, just as if she had
double-clicked on the directory name in the tree view.
Next, if a directory is presented to qof_session_begin it will detect
that and set ERR_BACKEND_BAD_URL, which gnc_post_file_open will detect
and re-present the file chooser, open to that directory. (To prevent
confusion, gnc_post_file_open will put up the error dialog for BAD_URL;
the new file chooser dialog will open after that's dismissed. Since
there are other possible causes of a BAD_URL, if the filename isn't a
directory the chooser will open to the registered default directory from
GConf.)
BP
git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@21459 57a11ea4-9604-0410-9ed3-97b8803252fd
2011-10-18 19:02:59 -05:00
|
|
|
LEAVE("Can't open a directory");
|
|
|
|
return;
|
|
|
|
}
|
2009-09-18 14:40:57 -05:00
|
|
|
/* destroy the old backend */
|
2016-06-05 12:14:45 -05:00
|
|
|
destroy_backend ();
|
2009-09-18 14:40:57 -05:00
|
|
|
/* Store the session URL */
|
2016-06-05 12:14:45 -05:00
|
|
|
m_book_id = new_book_id;
|
2018-07-06 15:00:08 -05:00
|
|
|
m_creating = create;
|
Handle specifying a directory as a dataset file.
The file chooser dialog would return a directory if the user selected
one and clicked "Open"; then, or if the users specified a directory on
the command line, Gnucash would present the rather misleading error "No
backend found".
So, first, if the user selects a directory and clicks open, the chooser
will now open the directory for browsing, just as if she had
double-clicked on the directory name in the tree view.
Next, if a directory is presented to qof_session_begin it will detect
that and set ERR_BACKEND_BAD_URL, which gnc_post_file_open will detect
and re-present the file chooser, open to that directory. (To prevent
confusion, gnc_post_file_open will put up the error dialog for BAD_URL;
the new file chooser dialog will open after that's dismissed. Since
there are other possible causes of a BAD_URL, if the filename isn't a
directory the chooser will open to the registered default directory from
GConf.)
BP
git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@21459 57a11ea4-9604-0410-9ed3-97b8803252fd
2011-10-18 19:02:59 -05:00
|
|
|
if (filename)
|
2016-06-05 12:14:45 -05:00
|
|
|
load_backend ("file");
|
Use a normalized uri format internally to refer to data stores.
Data stores for GC can be a file (xml or sqlite3) or a database
one some server (mysql or postgres).
Wherever it makes sense internally, data stores will be referred to
via a normalized uri:
protocol://user:password@host:port/path
Depending on the context and story type some of these parts are optional or unused.
To achieve this, a new utility interface has been setup:
gnc_uri_<xxx>_<yyy>
that can be used to manipulate the uris or convert from non-normalized
formats to normalized and back.
For example, when the user selects a file in the Open or Save As dialog,
gnc_uri_get_normalized_uri will convert the file into a normalized uri.
Or when the actual filename is needed this can be extracted with
gnc_uri_get_path.
You can also test if a uri defines a file or something else with
gnc_uri_is_file_uri.
For the complete documentation, see src/core-utils/gnc-uri-uitls.h
This commit installs gnc-uri-utils and modifies the source where it makes
sense to use its convenience functions. This concerns all functions that
had to deal with file access in some way or another, the history module
and the functions that generate the history menu list and the window titles.
Note that gnc-uri-utils replaces xaccResolveFilePath and xaccResolveUrl in all cases.
xaccResolveUrl has been removed, because gnc-uri-utils fully replaces its functionality.
xaccResolveFilePath is used internally in gnc-uri-utils to ensure an absolute path
is always returned (in case of a file uri, not for db uris). But it has been renamed to
gnc_resolve_file_path to be more consistent with the other functions.
Lastly, this commit also adds a first implementation to work with a keyring to
store and retrieve passwords, althoug
git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@18842 57a11ea4-9604-0410-9ed3-97b8803252fd
2010-03-05 14:15:31 -06:00
|
|
|
else /* access method found, load appropriate backend */
|
2016-06-05 12:14:45 -05:00
|
|
|
load_backend (scheme);
|
Handle specifying a directory as a dataset file.
The file chooser dialog would return a directory if the user selected
one and clicked "Open"; then, or if the users specified a directory on
the command line, Gnucash would present the rather misleading error "No
backend found".
So, first, if the user selects a directory and clicks open, the chooser
will now open the directory for browsing, just as if she had
double-clicked on the directory name in the tree view.
Next, if a directory is presented to qof_session_begin it will detect
that and set ERR_BACKEND_BAD_URL, which gnc_post_file_open will detect
and re-present the file chooser, open to that directory. (To prevent
confusion, gnc_post_file_open will put up the error dialog for BAD_URL;
the new file chooser dialog will open after that's dismissed. Since
there are other possible causes of a BAD_URL, if the filename isn't a
directory the chooser will open to the registered default directory from
GConf.)
BP
git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@21459 57a11ea4-9604-0410-9ed3-97b8803252fd
2011-10-18 19:02:59 -05:00
|
|
|
g_free (filename);
|
|
|
|
g_free (scheme);
|
2009-09-18 14:40:57 -05:00
|
|
|
|
|
|
|
/* No backend was found. That's bad. */
|
2016-11-28 12:27:09 -06:00
|
|
|
auto backend = qof_book_get_backend (m_book);
|
|
|
|
if (backend == nullptr)
|
2006-09-02 14:18:27 -05:00
|
|
|
{
|
2016-06-05 12:14:45 -05:00
|
|
|
m_book_id = {};
|
|
|
|
if (ERR_BACKEND_NO_ERR == get_error ())
|
|
|
|
push_error (ERR_BACKEND_BAD_URL, {});
|
2009-09-18 14:40:57 -05:00
|
|
|
LEAVE (" BAD: no backend: sess=%p book-id=%s",
|
2016-06-05 12:14:45 -05:00
|
|
|
this, new_book_id.c_str ());
|
2009-09-18 14:40:57 -05:00
|
|
|
return;
|
|
|
|
}
|
2006-09-05 08:38:41 -05:00
|
|
|
|
2009-09-18 14:40:57 -05:00
|
|
|
/* If there's a begin method, call that. */
|
2016-11-28 12:27:09 -06:00
|
|
|
backend->session_begin(this, m_book_id.c_str(), ignore_lock, create, force);
|
|
|
|
PINFO ("Done running session_begin on backend");
|
|
|
|
QofBackendError const err {backend->get_error()};
|
|
|
|
auto msg (backend->get_message());
|
|
|
|
if (err != ERR_BACKEND_NO_ERR)
|
2009-09-18 14:40:57 -05:00
|
|
|
{
|
2016-11-28 12:27:09 -06:00
|
|
|
m_book_id = {};
|
|
|
|
push_error (err, msg);
|
|
|
|
LEAVE (" backend error %d %s", err, msg.empty() ? "(null)" : msg.c_str());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (!msg.empty())
|
|
|
|
{
|
|
|
|
PWARN("%s", msg.c_str());
|
2006-09-02 14:18:27 -05:00
|
|
|
}
|
2016-11-28 12:27:09 -06:00
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
LEAVE (" sess=%p book-id=%s", this, new_book_id.c_str ());
|
|
|
|
}
|
2009-09-18 14:40:57 -05:00
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
void
|
|
|
|
QofSessionImpl::end () noexcept
|
|
|
|
{
|
|
|
|
ENTER ("sess=%p book_id=%s", this, m_book_id.c_str ());
|
|
|
|
auto backend = qof_book_get_backend (m_book);
|
2016-11-28 12:27:09 -06:00
|
|
|
if (backend != nullptr)
|
|
|
|
backend->session_end();
|
2016-06-05 12:14:45 -05:00
|
|
|
clear_error ();
|
2016-11-28 12:27:09 -06:00
|
|
|
m_book_id.clear();
|
2016-06-05 12:14:45 -05:00
|
|
|
LEAVE ("sess=%p book_id=%s", this, m_book_id.c_str ());
|
2005-11-07 09:45:58 -06:00
|
|
|
}
|
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
/* error handling functions --------------------------------*/
|
2005-11-07 09:45:58 -06:00
|
|
|
|
|
|
|
void
|
2016-06-05 12:14:45 -05:00
|
|
|
QofSessionImpl::clear_error () noexcept
|
2005-11-07 09:45:58 -06:00
|
|
|
{
|
2016-06-05 12:14:45 -05:00
|
|
|
m_last_err = ERR_BACKEND_NO_ERR;
|
|
|
|
m_error_message = {};
|
2009-09-18 14:40:57 -05:00
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
/* pop the stack on the backend as well. */
|
2016-11-28 12:27:09 -06:00
|
|
|
if (auto backend = qof_book_get_backend (m_book))
|
2016-06-05 12:14:45 -05:00
|
|
|
{
|
2016-11-28 12:27:09 -06:00
|
|
|
QofBackendError err = ERR_BACKEND_NO_ERR;
|
2016-06-05 12:14:45 -05:00
|
|
|
do
|
2016-11-28 12:27:09 -06:00
|
|
|
err = backend->get_error();
|
|
|
|
while (err != ERR_BACKEND_NO_ERR);
|
2016-06-05 12:14:45 -05:00
|
|
|
}
|
|
|
|
}
|
2009-09-18 14:40:57 -05:00
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
void
|
|
|
|
QofSessionImpl::push_error (QofBackendError const err, std::string message) noexcept
|
|
|
|
{
|
|
|
|
m_last_err = err;
|
|
|
|
m_error_message = message;
|
|
|
|
}
|
2009-09-18 14:40:57 -05:00
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
QofBackendError
|
|
|
|
QofSessionImpl::get_error () noexcept
|
|
|
|
{
|
|
|
|
/* if we have a local error, return that. */
|
2016-11-28 12:27:09 -06:00
|
|
|
if (m_last_err != ERR_BACKEND_NO_ERR)
|
2016-06-05 12:14:45 -05:00
|
|
|
return m_last_err;
|
2016-11-28 12:27:09 -06:00
|
|
|
auto qof_be = qof_book_get_backend (m_book);
|
|
|
|
if (qof_be == nullptr) return ERR_BACKEND_NO_ERR;
|
2009-09-18 14:40:57 -05:00
|
|
|
|
2016-11-28 12:27:09 -06:00
|
|
|
m_last_err = qof_be->get_error();
|
2016-06-05 12:14:45 -05:00
|
|
|
return m_last_err;
|
|
|
|
}
|
2009-09-18 14:40:57 -05:00
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
std::string
|
|
|
|
QofSessionImpl::get_error_message () const noexcept
|
|
|
|
{
|
|
|
|
return m_error_message;
|
|
|
|
}
|
2009-09-18 14:40:57 -05:00
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
QofBackendError
|
|
|
|
QofSessionImpl::pop_error () noexcept
|
|
|
|
{
|
|
|
|
QofBackendError err {get_error ()};
|
|
|
|
clear_error ();
|
|
|
|
return err;
|
|
|
|
}
|
2009-09-18 14:40:57 -05:00
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
/* Accessors (getters/setters) -----------------------------*/
|
2009-09-18 14:40:57 -05:00
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
QofBook *
|
|
|
|
QofSessionImpl::get_book () const noexcept
|
|
|
|
{
|
|
|
|
if (!m_book) return nullptr;
|
|
|
|
if ('y' == m_book->book_open)
|
|
|
|
return m_book;
|
|
|
|
return nullptr;
|
|
|
|
}
|
2009-09-18 14:40:57 -05:00
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
QofBackend *
|
|
|
|
QofSession::get_backend () const noexcept
|
|
|
|
{
|
|
|
|
return qof_book_get_backend (m_book);
|
2005-11-07 09:45:58 -06:00
|
|
|
}
|
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
std::string
|
|
|
|
QofSessionImpl::get_file_path () const noexcept
|
|
|
|
{
|
2016-11-28 12:27:09 -06:00
|
|
|
auto backend = qof_book_get_backend (m_book);
|
|
|
|
if (!backend) return nullptr;
|
|
|
|
return backend->get_uri();
|
2016-06-05 12:14:45 -05:00
|
|
|
}
|
2005-11-07 09:45:58 -06:00
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
std::string const &
|
|
|
|
QofSessionImpl::get_book_id () const noexcept
|
2005-11-07 09:45:58 -06:00
|
|
|
{
|
2016-06-05 12:14:45 -05:00
|
|
|
return m_book_id;
|
|
|
|
}
|
2009-09-18 14:40:57 -05:00
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
bool
|
|
|
|
QofSessionImpl::is_saving () const noexcept
|
|
|
|
{
|
|
|
|
return m_saving;
|
2005-11-07 09:45:58 -06:00
|
|
|
}
|
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
/* Manipulators (save, load, etc.) -------------------------*/
|
|
|
|
|
2005-11-07 09:45:58 -06:00
|
|
|
void
|
2016-06-05 12:14:45 -05:00
|
|
|
QofSessionImpl::save (QofPercentageFunc percentage_func) noexcept
|
2005-11-07 09:45:58 -06:00
|
|
|
{
|
2018-07-14 19:09:22 -05:00
|
|
|
if (!qof_book_session_not_saved (m_book)) //Clean book, nothing to do.
|
|
|
|
return;
|
2016-06-05 12:14:45 -05:00
|
|
|
m_saving = true;
|
|
|
|
ENTER ("sess=%p book_id=%s", this, m_book_id.c_str ());
|
2014-12-30 18:19:21 -06:00
|
|
|
|
2018-07-14 19:09:22 -05:00
|
|
|
/* If there is a backend, the book is dirty, and the backend is reachable
|
|
|
|
* (i.e. we can communicate with it), then synchronize with the backend. If
|
|
|
|
* we cannot contact the backend (e.g. because we've gone offline, the
|
|
|
|
* network has crashed, etc.) then raise an error so that the controlling
|
|
|
|
* dialog can offer the user a chance to save in a different way.
|
|
|
|
*/
|
2016-06-05 12:14:45 -05:00
|
|
|
auto backend = qof_book_get_backend (m_book);
|
|
|
|
if (backend)
|
2009-09-18 14:40:57 -05:00
|
|
|
{
|
2018-07-14 19:09:22 -05:00
|
|
|
|
2016-11-28 12:27:09 -06:00
|
|
|
backend->set_percentage(percentage_func);
|
|
|
|
backend->sync(m_book);
|
|
|
|
auto err = backend->get_error();
|
|
|
|
if (err != ERR_BACKEND_NO_ERR)
|
2009-09-18 14:40:57 -05:00
|
|
|
{
|
2016-11-28 12:27:09 -06:00
|
|
|
push_error (err, {});
|
|
|
|
m_saving = false;
|
|
|
|
return;
|
2009-09-18 14:40:57 -05:00
|
|
|
}
|
|
|
|
/* If we got to here, then the backend saved everything
|
|
|
|
* just fine, and we are done. So return. */
|
2016-06-05 12:14:45 -05:00
|
|
|
clear_error ();
|
2009-09-18 14:40:57 -05:00
|
|
|
LEAVE("Success");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-07-06 15:00:08 -05:00
|
|
|
push_error (ERR_BACKEND_NO_HANDLER, "failed to load backend");
|
2016-06-05 12:14:45 -05:00
|
|
|
LEAVE("error -- No backend!");
|
2009-09-18 14:40:57 -05:00
|
|
|
}
|
2016-06-05 12:14:45 -05:00
|
|
|
m_saving = false;
|
2005-11-07 09:45:58 -06:00
|
|
|
}
|
|
|
|
|
2011-01-14 17:25:27 -06:00
|
|
|
void
|
2016-06-05 12:14:45 -05:00
|
|
|
QofSessionImpl::safe_save (QofPercentageFunc percentage_func) noexcept
|
|
|
|
{
|
|
|
|
auto backend = qof_book_get_backend (m_book);
|
|
|
|
if (!backend) return;
|
2016-11-28 12:27:09 -06:00
|
|
|
backend->set_percentage(percentage_func);
|
|
|
|
backend->safe_sync(get_book ());
|
|
|
|
auto err = backend->get_error();
|
|
|
|
auto msg = backend->get_message();
|
2011-01-14 17:25:27 -06:00
|
|
|
if (err != ERR_BACKEND_NO_ERR)
|
|
|
|
{
|
2016-11-28 12:27:09 -06:00
|
|
|
m_book_id = nullptr;
|
|
|
|
push_error (err, msg);
|
2011-01-14 17:25:27 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
void
|
|
|
|
QofSessionImpl::ensure_all_data_loaded () noexcept
|
2006-12-02 16:13:13 -06:00
|
|
|
{
|
2016-06-05 12:14:45 -05:00
|
|
|
auto backend = qof_book_get_backend (m_book);
|
|
|
|
if (!backend) return;
|
2016-11-28 12:27:09 -06:00
|
|
|
backend->load(m_book, LOAD_TYPE_LOAD_ALL);
|
|
|
|
push_error (backend->get_error(), {});
|
2006-12-02 16:13:13 -06:00
|
|
|
}
|
2005-11-07 09:45:58 -06:00
|
|
|
|
|
|
|
void
|
2016-06-05 12:14:45 -05:00
|
|
|
QofSessionImpl::swap_books (QofSessionImpl & other) noexcept
|
|
|
|
{
|
|
|
|
ENTER ("sess1=%p sess2=%p", this, &other);
|
|
|
|
// don't swap (that is, double-swap) read_only flags
|
|
|
|
std::swap (m_book->read_only, other.m_book->read_only);
|
|
|
|
std::swap (m_book, other.m_book);
|
|
|
|
auto mybackend = qof_book_get_backend (m_book);
|
|
|
|
qof_book_set_backend (m_book, qof_book_get_backend (other.m_book));
|
|
|
|
qof_book_set_backend (other.m_book, mybackend);
|
|
|
|
LEAVE (" ");
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
QofSessionImpl::events_pending () const noexcept
|
2005-11-07 09:45:58 -06:00
|
|
|
{
|
2016-07-18 11:49:41 -05:00
|
|
|
return false;
|
2016-06-05 12:14:45 -05:00
|
|
|
}
|
2005-11-07 09:45:58 -06:00
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
bool
|
|
|
|
QofSessionImpl::process_events () const noexcept
|
|
|
|
{
|
2016-07-18 11:49:41 -05:00
|
|
|
return false;
|
2016-06-05 12:14:45 -05:00
|
|
|
}
|
2005-11-07 09:45:58 -06:00
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
/* XXX This exports the list of accounts to a file. It does not
|
|
|
|
* export any transactions. It's a place-holder until full
|
|
|
|
* book-closing is implemented.
|
|
|
|
*/
|
|
|
|
bool
|
2016-11-28 12:27:09 -06:00
|
|
|
QofSessionImpl::export_session (QofSessionImpl & real_session,
|
|
|
|
QofPercentageFunc percentage_func) noexcept
|
2016-06-05 12:14:45 -05:00
|
|
|
{
|
|
|
|
auto real_book = real_session.get_book ();
|
|
|
|
ENTER ("tmp_session=%p real_session=%p book=%p book_id=%s",
|
|
|
|
this, &real_session, real_book, m_book_id.c_str ());
|
2005-11-07 09:45:58 -06:00
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
/* There must be a backend or else. (It should always be the file
|
|
|
|
* backend too.)
|
|
|
|
*/
|
|
|
|
auto backend2 = qof_book_get_backend(m_book);
|
|
|
|
if (!backend2) return false;
|
2005-11-07 09:45:58 -06:00
|
|
|
|
2016-11-28 12:27:09 -06:00
|
|
|
backend2->set_percentage(percentage_func);
|
2005-11-07 09:45:58 -06:00
|
|
|
|
2016-11-28 12:27:09 -06:00
|
|
|
backend2->export_coa(real_book);
|
|
|
|
auto err = backend2->get_error();
|
|
|
|
if (err != ERR_BACKEND_NO_ERR)
|
2016-06-05 12:14:45 -05:00
|
|
|
return false;
|
|
|
|
return true;
|
2005-11-07 09:45:58 -06:00
|
|
|
}
|
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
/* C Wrapper Functions */
|
|
|
|
/* ====================================================================== */
|
2005-11-07 09:45:58 -06:00
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
const char *
|
|
|
|
qof_session_get_error_message (const QofSession * session)
|
|
|
|
{
|
|
|
|
if (!session) return "";
|
|
|
|
return session->get_error_message ().c_str ();
|
|
|
|
}
|
2005-11-07 09:45:58 -06:00
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
QofBackendError
|
|
|
|
qof_session_pop_error (QofSession * session)
|
|
|
|
{
|
|
|
|
if (!session) return ERR_BACKEND_NO_BACKEND;
|
|
|
|
return session->pop_error ();
|
|
|
|
}
|
2005-11-07 09:45:58 -06:00
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
QofBook *
|
|
|
|
qof_session_get_book (const QofSession *session)
|
|
|
|
{
|
|
|
|
if (!session) return NULL;
|
|
|
|
return session->get_book ();
|
|
|
|
}
|
2005-11-07 09:45:58 -06:00
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
const char *
|
|
|
|
qof_session_get_file_path (const QofSession *session)
|
|
|
|
{
|
|
|
|
if (!session) return NULL;
|
|
|
|
return session->get_file_path ().c_str ();
|
|
|
|
}
|
2005-11-07 09:45:58 -06:00
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
void
|
|
|
|
qof_session_ensure_all_data_loaded (QofSession *session)
|
|
|
|
{
|
|
|
|
if (session == nullptr) return;
|
|
|
|
return session->ensure_all_data_loaded ();
|
|
|
|
}
|
2005-11-07 09:45:58 -06:00
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
const char *
|
|
|
|
qof_session_get_url (const QofSession *session)
|
|
|
|
{
|
|
|
|
if (!session) return NULL;
|
|
|
|
return session->get_book_id ().c_str ();
|
2005-11-07 09:45:58 -06:00
|
|
|
}
|
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
QofBackend *
|
|
|
|
qof_session_get_backend (const QofSession *session)
|
|
|
|
{
|
|
|
|
if (!session) return NULL;
|
|
|
|
return session->get_backend ();
|
|
|
|
}
|
2005-11-07 09:45:58 -06:00
|
|
|
|
|
|
|
void
|
2016-06-05 12:14:45 -05:00
|
|
|
qof_session_begin (QofSession *session, const char * book_id,
|
|
|
|
gboolean ignore_lock, gboolean create, gboolean force)
|
2005-11-07 09:45:58 -06:00
|
|
|
{
|
2016-06-05 12:14:45 -05:00
|
|
|
if (!session) return;
|
|
|
|
session->begin((book_id ? book_id : ""), ignore_lock, create, force);
|
|
|
|
}
|
2005-11-07 09:45:58 -06:00
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
void
|
|
|
|
qof_session_load (QofSession *session,
|
|
|
|
QofPercentageFunc percentage_func)
|
|
|
|
{
|
|
|
|
if (!session) return;
|
|
|
|
session->load (percentage_func);
|
|
|
|
}
|
2005-11-07 09:45:58 -06:00
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
void
|
|
|
|
qof_session_save (QofSession *session,
|
|
|
|
QofPercentageFunc percentage_func)
|
|
|
|
{
|
|
|
|
if (!session) return;
|
|
|
|
session->save (percentage_func);
|
|
|
|
}
|
2011-12-29 16:14:43 -06:00
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
void
|
|
|
|
qof_session_safe_save(QofSession *session, QofPercentageFunc percentage_func)
|
|
|
|
{
|
|
|
|
if (!session) return;
|
|
|
|
session->safe_save (percentage_func);
|
|
|
|
}
|
2005-11-07 09:45:58 -06:00
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
gboolean
|
|
|
|
qof_session_save_in_progress(const QofSession *session)
|
|
|
|
{
|
|
|
|
if (!session) return false;
|
|
|
|
return session->is_saving ();
|
|
|
|
}
|
2005-11-07 09:45:58 -06:00
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
void
|
|
|
|
qof_session_end (QofSession *session)
|
|
|
|
{
|
|
|
|
if (!session) return;
|
|
|
|
session->end ();
|
2005-11-07 09:45:58 -06:00
|
|
|
}
|
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
void
|
|
|
|
qof_session_swap_data (QofSession *session_1, QofSession *session_2)
|
|
|
|
{
|
|
|
|
if (session_1 == session_2) return;
|
|
|
|
if (!session_1 || !session_2) return;
|
|
|
|
session_1->swap_books (*session_2);
|
|
|
|
}
|
2005-11-07 09:45:58 -06:00
|
|
|
|
|
|
|
gboolean
|
2007-12-29 13:40:28 -06:00
|
|
|
qof_session_events_pending (const QofSession *session)
|
2005-11-07 09:45:58 -06:00
|
|
|
{
|
2016-06-05 12:14:45 -05:00
|
|
|
if (!session) return false;
|
|
|
|
return session->events_pending ();
|
2005-11-07 09:45:58 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
qof_session_process_events (QofSession *session)
|
|
|
|
{
|
2009-09-18 14:40:57 -05:00
|
|
|
if (!session) return FALSE;
|
2016-06-05 12:14:45 -05:00
|
|
|
return session->process_events ();
|
2005-11-07 09:45:58 -06:00
|
|
|
}
|
|
|
|
|
2006-05-25 19:10:35 -05:00
|
|
|
gboolean
|
|
|
|
qof_session_export (QofSession *tmp_session,
|
|
|
|
QofSession *real_session,
|
|
|
|
QofPercentageFunc percentage_func)
|
|
|
|
{
|
2009-09-18 14:40:57 -05:00
|
|
|
if ((!tmp_session) || (!real_session)) return FALSE;
|
2016-06-05 12:14:45 -05:00
|
|
|
return tmp_session->export_session (*real_session, percentage_func);
|
|
|
|
}
|
2009-09-18 14:40:57 -05:00
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
/* ================= Static function access for testing ================= */
|
2006-05-25 19:10:35 -05:00
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
void init_static_qofsession_pointers (void);
|
2006-05-25 19:10:35 -05:00
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
void qof_session_load_backend (QofSession * session, const char * access_method)
|
|
|
|
{
|
|
|
|
session->load_backend (access_method);
|
|
|
|
}
|
2006-05-25 19:10:35 -05:00
|
|
|
|
2017-12-26 15:01:50 -06:00
|
|
|
static void
|
|
|
|
qof_session_clear_error (QofSession * session)
|
2016-06-05 12:14:45 -05:00
|
|
|
{
|
|
|
|
session->clear_error ();
|
2006-05-25 19:10:35 -05:00
|
|
|
}
|
|
|
|
|
2017-12-26 15:01:50 -06:00
|
|
|
static void
|
|
|
|
qof_session_destroy_backend (QofSession * session)
|
2016-06-05 12:14:45 -05:00
|
|
|
{
|
|
|
|
session->destroy_backend ();
|
|
|
|
}
|
2012-01-09 17:09:47 -06:00
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
void qof_session_set_book_id (QofSession * session, char const * book_id)
|
|
|
|
{
|
|
|
|
if (!book_id)
|
|
|
|
session->m_book_id = "";
|
|
|
|
else
|
|
|
|
session->m_book_id = book_id;
|
|
|
|
}
|
2012-01-09 17:09:47 -06:00
|
|
|
|
2016-06-05 12:14:45 -05:00
|
|
|
void (*p_qof_session_load_backend) (QofSession *, const char * access_method);
|
|
|
|
void (*p_qof_session_clear_error) (QofSession *);
|
|
|
|
void (*p_qof_session_destroy_backend) (QofSession *);
|
|
|
|
void (*p_qof_session_set_book_id) (QofSession *, char const * book_id);
|
2012-01-09 17:09:47 -06:00
|
|
|
|
|
|
|
void
|
|
|
|
init_static_qofsession_pointers (void)
|
|
|
|
{
|
2016-06-05 12:14:45 -05:00
|
|
|
p_qof_session_load_backend = &qof_session_load_backend;
|
|
|
|
p_qof_session_clear_error = &qof_session_clear_error;
|
|
|
|
p_qof_session_destroy_backend = &qof_session_destroy_backend;
|
|
|
|
p_qof_session_set_book_id = &qof_session_set_book_id;
|
|
|
|
}
|
|
|
|
|
|
|
|
QofBackendError
|
|
|
|
qof_session_get_error (QofSession * session)
|
|
|
|
{
|
|
|
|
if (!session) return ERR_BACKEND_NO_BACKEND;
|
|
|
|
return session->get_error();
|
2012-01-09 17:09:47 -06:00
|
|
|
}
|