Line data Source code
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
49 451 : QofBackend::commit(QofInstance* instance)
50 : {
51 451 : if (qof_instance_is_dirty(instance))
52 432 : qof_instance_mark_clean(instance);
53 451 : }
54 :
55 : void
56 24 : QofBackend::set_error(QofBackendError err)
57 : {
58 : /* use stack-push semantics. Only the earliest error counts */
59 24 : if (m_last_err != ERR_BACKEND_NO_ERR) return;
60 24 : m_last_err = err;
61 : }
62 :
63 : QofBackendError
64 29923 : QofBackend::get_error()
65 : {
66 : /* use 'stack-pop' semantics */
67 29923 : auto err = m_last_err;
68 29923 : m_last_err = ERR_BACKEND_NO_ERR;
69 29923 : return err;
70 : }
71 :
72 : bool
73 1 : QofBackend::check_error()
74 : {
75 1 : return m_last_err != ERR_BACKEND_NO_ERR;
76 : }
77 :
78 : void
79 2 : QofBackend::set_message (std::string&& msg)
80 : {
81 2 : m_error_msg = msg;
82 2 : }
83 :
84 : const std::string&&
85 59 : QofBackend::get_message ()
86 : {
87 118 : return std::move(m_error_msg);
88 : }
89 :
90 : bool
91 124 : QofBackend::register_backend(const char* directory, const char* module_name)
92 : {
93 124 : if (!g_module_supported ())
94 : {
95 0 : PWARN("Modules not supported.");
96 0 : return false;
97 : }
98 :
99 124 : auto absdir = directory;
100 124 : auto pkgdir = gnc_path_get_pkglibdir ();
101 124 : if (!absdir || !g_path_is_absolute(absdir))
102 124 : absdir = pkgdir;
103 124 : auto fullpath = g_module_build_path (absdir, module_name);
104 : /* Darwin modules can have either .so or .dylib for a suffix */
105 222 : if (!g_file_test (fullpath, G_FILE_TEST_EXISTS) &&
106 98 : g_strcmp0 (G_MODULE_SUFFIX, "so") == 0)
107 : {
108 98 : auto modname = g_strdup_printf ("lib%s.dylib", module_name);
109 98 : g_free (fullpath);
110 98 : fullpath = g_build_filename (absdir, modname, nullptr);
111 98 : g_free (modname);
112 : }
113 124 : auto backend = g_module_open (fullpath, G_MODULE_BIND_LAZY);
114 124 : g_free (fullpath);
115 124 : g_free (pkgdir);
116 124 : if (!backend)
117 : {
118 98 : PINFO ("%s: %s\n", PROJECT_NAME, g_module_error ());
119 98 : return false;
120 : }
121 : void (*module_init_func)(void);
122 26 : if (g_module_symbol (backend, "qof_backend_module_init",
123 : reinterpret_cast<void**>(&module_init_func)))
124 26 : module_init_func ();
125 :
126 26 : g_module_make_resident (backend);
127 26 : c_be_registry.push_back(backend);
128 26 : return TRUE;
129 : }
130 :
131 : void
132 43 : QofBackend::release_backends()
133 : {
134 90 : for (auto backend : c_be_registry)
135 : {
136 : void (*module_finalize_func)(void);
137 4 : if (g_module_symbol(backend, "qof_backend_module_finalize",
138 : reinterpret_cast<void**>(&module_finalize_func)))
139 0 : module_finalize_func();
140 : }
141 43 : }
142 : /***********************************************************************/
143 : QofBackendError
144 17 : qof_backend_get_error (QofBackend* qof_be)
145 : {
146 17 : if (qof_be == nullptr) return ERR_BACKEND_NO_ERR;
147 17 : return ((QofBackend*)qof_be)->get_error();
148 : }
149 :
150 : void
151 2 : qof_backend_set_error (QofBackend* qof_be, QofBackendError err)
152 : {
153 2 : if (qof_be == nullptr) return;
154 2 : ((QofBackend*)qof_be)->set_error(err);
155 : }
156 :
157 : gboolean
158 13 : qof_backend_can_rollback (QofBackend* qof_be)
159 : {
160 13 : if (qof_be == nullptr) return FALSE;
161 8 : return true;
162 : }
163 :
164 : void
165 8 : qof_backend_rollback_instance (QofBackend* qof_be, QofInstance* inst)
166 : {
167 8 : if (qof_be == nullptr) return;
168 8 : ((QofBackend*)qof_be)->rollback(inst);
169 : }
170 :
171 : gboolean
172 124 : qof_load_backend_library (const char *directory, const char* module_name)
173 : {
174 124 : return QofBackend::register_backend(directory, module_name);
175 : }
176 :
177 : void
178 0 : qof_finalize_backend_libraries(void)
179 : {
180 0 : QofBackend::release_backends();
181 0 : }
182 :
183 : /************************* END OF FILE ********************************/
|