GnuCash  5.6-150-g038405b370+
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 
37 G_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 
46 GModuleVec QofBackend::c_be_registry{};
47 
48 void
50 {
51  if (qof_instance_is_dirty(instance))
52  qof_instance_mark_clean(instance);
53 }
54 
55 void
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 
72 bool
74 {
75  return m_last_err != ERR_BACKEND_NO_ERR;
76 }
77 
78 void
79 QofBackend::set_message (std::string&& msg)
80 {
81  m_error_msg = msg;
82 }
83 
84 const std::string&&
86 {
87  return std::move(m_error_msg);
88 }
89 
90 bool
91 QofBackend::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 
131 void
132 QofBackend::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 
150 void
152 {
153  if (qof_be == nullptr) return;
154  ((QofBackend*)qof_be)->set_error(err);
155 }
156 
157 gboolean
158 qof_backend_can_rollback (QofBackend* qof_be)
159 {
160  if (qof_be == nullptr) return FALSE;
161  return true;
162 }
163 
164 void
165 qof_backend_rollback_instance (QofBackend* qof_be, QofInstance* inst)
166 {
167  if (qof_be == nullptr) return;
168  ((QofBackend*)qof_be)->rollback(inst);
169 }
170 
171 gboolean
172 qof_load_backend_library (const char *directory, const char* module_name)
173 {
174  return QofBackend::register_backend(directory, module_name);
175 }
176 
177 void
179 {
180  QofBackend::release_backends();
181 }
182 
183 /************************* END OF FILE ********************************/
#define qof_instance_is_dirty
Return value of is_dirty flag.
Definition: qofinstance.h:166
const std::string && get_message()
Retrieve and clear the stored error message.
Definition: qof-backend.cpp:85
void set_message(std::string &&)
Set a descriptive message that can be displayed to the user when there&#39;s an error.
Definition: qof-backend.cpp:79
#define PINFO(format, args...)
Print an informational note.
Definition: qoflog.h:256
QofBackendError
The errors that can be reported to the GUI & other front-end users.
Definition: qofbackend.h:57
void qof_backend_set_error(QofBackend *qof_be, QofBackendError err)
Set the error on the specified QofBackend.
QofBackendError qof_backend_get_error(QofBackend *qof_be)
Get the last backend error.
virtual void commit(QofInstance *)
Commits the changes from the engine to the backend data storage.
Definition: qof-backend.cpp:49
#define PWARN(format, args...)
Log a warning.
Definition: qoflog.h:250
static bool register_backend(const char *, const char *)
Class methods for dynamically loading the several backends and for freeing them at shutdown...
Definition: qof-backend.cpp:91
void qof_finalize_backend_libraries(void)
Finalize all loaded backend shareable libraries.
gboolean qof_load_backend_library(const gchar *directory, const gchar *module_name)
Load a QOF-compatible backend shared library.
bool check_error()
Report if there is an error.
Definition: qof-backend.cpp:73
void set_error(QofBackendError err)
Set the error value only if there isn&#39;t already an error already.
Definition: qof-backend.cpp:56
QofBackendError get_error()
Retrieve the currently-stored error and clear it.
Definition: qof-backend.cpp:64