GnuCash c935c2f+
Loading...
Searching...
No Matches
qof-backend.cpp
1/********************************************************************\
2 * qofbackend.c -- utility routines for dealing with the data backend *
3 * Copyright (C) 2000 Linas Vepstas <linas@linas.org> *
4 * Copyright (C) 2004-5 Neil Williams <linux@codehelp.co.uk> *
5 * *
6 * This program is free software; you can redistribute it and/or *
7 * modify it under the terms of the GNU General Public License as *
8 * published by the Free Software Foundation; either version 2 of *
9 * the License, or (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License*
17 * along with this program; if not, contact: *
18 * *
19 * Free Software Foundation Voice: +1-617-542-5942 *
20 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
21 * Boston, MA 02110-1301, USA gnu@gnu.org *
22 * *
23\********************************************************************/
24
25
26#include <config.h>
27#include "qof.h"
28#include <gnc-path.h>
29#include "gncla-dir.h"
30
31#include <string>
32#include <algorithm>
33#include <vector>
34
35#include "qof-backend.hpp"
36
37G_GNUC_UNUSED static QofLogModule log_module = QOF_MOD_BACKEND;
38
39#define QOF_CONFIG_DESC "desc"
40#define QOF_CONFIG_TIP "tip"
41
42/* *******************************************************************\
43 * error handling *
44\********************************************************************/
45
46GModuleVec QofBackend::c_be_registry{};
47
48void
50{
51 if (qof_instance_is_dirty(instance))
52 qof_instance_mark_clean(instance);
53}
54
55void
57{
58 /* use stack-push semantics. Only the earliest error counts */
59 if (m_last_err != ERR_BACKEND_NO_ERR) return;
60 m_last_err = err;
61}
62
65{
66 /* use 'stack-pop' semantics */
67 auto err = m_last_err;
68 m_last_err = ERR_BACKEND_NO_ERR;
69 return err;
70}
71
72bool
74{
75 return m_last_err != ERR_BACKEND_NO_ERR;
76}
77
78void
79QofBackend::set_message (std::string&& msg)
80{
81 m_error_msg = msg;
82}
83
84const std::string&&
86{
87 return std::move(m_error_msg);
88}
89
90bool
91QofBackend::register_backend(const char* directory, const char* module_name)
92{
93 if (!g_module_supported ())
94 {
95 PWARN("Modules not supported.");
96 return false;
97 }
98
99 auto absdir = directory;
100 auto pkgdir = gnc_path_get_pkglibdir ();
101 if (!absdir || !g_path_is_absolute(absdir))
102 absdir = pkgdir;
103 auto fullpath = g_module_build_path (absdir, module_name);
104/* Darwin modules can have either .so or .dylib for a suffix */
105 if (!g_file_test (fullpath, G_FILE_TEST_EXISTS) &&
106 g_strcmp0 (G_MODULE_SUFFIX, "so") == 0)
107 {
108 auto modname = g_strdup_printf ("lib%s.dylib", module_name);
109 g_free (fullpath);
110 fullpath = g_build_filename (absdir, modname, nullptr);
111 g_free (modname);
112 }
113 auto backend = g_module_open (fullpath, G_MODULE_BIND_LAZY);
114 g_free (fullpath);
115 g_free (pkgdir);
116 if (!backend)
117 {
118 PINFO ("%s: %s\n", PROJECT_NAME, g_module_error ());
119 return false;
120 }
121 void (*module_init_func)(void);
122 if (g_module_symbol (backend, "qof_backend_module_init",
123 reinterpret_cast<void**>(&module_init_func)))
124 module_init_func ();
125
126 g_module_make_resident (backend);
127 c_be_registry.push_back(backend);
128 return TRUE;
129}
130
131void
132QofBackend::release_backends()
133{
134 for (auto backend : c_be_registry)
135 {
136 void (*module_finalize_func)(void);
137 if (g_module_symbol(backend, "qof_backend_module_finalize",
138 reinterpret_cast<void**>(&module_finalize_func)))
139 module_finalize_func();
140 }
141}
142/***********************************************************************/
145{
146 if (qof_be == nullptr) return ERR_BACKEND_NO_ERR;
147 return ((QofBackend*)qof_be)->get_error();
148}
149
150void
152{
153 if (qof_be == nullptr) return;
154 ((QofBackend*)qof_be)->set_error(err);
155}
156
157gboolean
158qof_backend_can_rollback (QofBackend* qof_be)
159{
160 if (qof_be == nullptr) return FALSE;
161 return true;
162}
163
164void
165qof_backend_rollback_instance (QofBackend* qof_be, QofInstance* inst)
166{
167 if (qof_be == nullptr) return;
168 ((QofBackend*)qof_be)->rollback(inst);
169}
170
171gboolean
172qof_load_backend_library (const char *directory, const char* module_name)
173{
174 return QofBackend::register_backend(directory, module_name);
175}
176
177void
179{
180 QofBackend::release_backends();
181}
182
183/************************* END OF FILE ********************************/
void qof_backend_set_error(QofBackend *qof_be, QofBackendError err)
Set the error on the specified QofBackend.
QofBackendError
The errors that can be reported to the GUI & other front-end users.
Definition qofbackend.h:58
QofBackendError qof_backend_get_error(QofBackend *qof_be)
Get the last backend error.
void qof_finalize_backend_libraries(void)
Finalize all loaded backend shareable libraries.
#define qof_instance_is_dirty
Return value of is_dirty flag.
#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 commit(QofInstance *)
Commits the changes from the engine to the backend data storage.
void set_message(std::string &&)
Set a descriptive message that can be displayed to the user when there's an error.
static bool register_backend(const char *, const char *)
Class methods for dynamically loading the several backends and for freeing them at shutdown.
bool check_error()
Report if there is an error.
const std::string && get_message()
Retrieve and clear the stored error message.
QofBackendError get_error()
Retrieve the currently-stored error and clear it.
void set_error(QofBackendError err)
Set the error value only if there isn't already an error already.