1 /********************************************************************
2 * gnc-backend-dbi.hpp: load and save data to SQL via libdbi *
3 * *
4 * This program is free software; you can redistribute it and/or *
5 * modify it under the terms of the GNU General Public License as *
6 * published by the Free Software Foundation; either version 2 of *
7 * the License, or (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License*
15 * along with this program; if not, contact: *
16 * *
17 * Free Software Foundation Voice: +1-617-542-5942 *
18 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
19 * Boston, MA 02110-1301, USA gnu@gnu.org *
20 \********************************************************************/
21
22 /* Private structures and variables for gnc-backend-dbi.c and its unit tests */
23 #ifndef GNC_BACKEND_DBI_HPP
24 #define GNC_BACKEND_DBI_HPP
25 extern "C"
26 {
27 #include <dbi/dbi.h>
28 #ifdef G_OS_WIN32
29 #include <winsock2.h>
30 #define GETPID() GetCurrentProcessId()
31 #else
32 #include <limits.h>
33 #include <unistd.h>
34 #define GETPID() getpid()
35 #endif
36 }
37 #include <gnc-sql-backend.hpp>
38 #include <gnc-sql-connection.hpp>
39
40 class GncSqlRow;
41
42 #define GNC_HOST_NAME_MAX 255
43
44 /**
45 * Options to conn_table_operation
46 * @var drop Drop (remove without recourse) the table from the database
47 * @var empty Delete all of the records from the table
48 * @var backup Rename the table "name" to "name_back"
49 * @var rollback drop the name table if it exists and rename name_back to name
50 * @var drop_backup Drop the backup table
51 */
52 enum TableOpType
53 {
54 backup = 0,
55 rollback,
56 drop_backup,
57 recover
58 };
59
60 /**
61 * Return values from conn_test_dbi_library
62 * @var GNC_DBI_PASS Did not find the large numbers bug
63 * @var GNC_DBI_FAIL_SETUP Could not completed the test
64 * @var GNC_DBI_FAIL_TEST Found the large numbers bug
65 */
66 typedef enum
67 {
68 GNC_DBI_PASS = 0,
69 GNC_DBI_FAIL_SETUP,
70 GNC_DBI_FAIL_TEST
71 } GncDbiTestResult;
72
73 /**
74 * Supported Dbi Backends.
75 */
76 enum class DbType
77 {
78 DBI_SQLITE, /**< Sqlite3 */
79 DBI_MYSQL, /**< MySQL and probably MariaDB */
80 DBI_PGSQL /**< Postgresql */
81 };
82
83 /**
84 * Implementations of GncSqlBackend.
85 */
86 struct UriStrings;
87
88 template <DbType Type>
89 class GncDbiBackend : public GncSqlBackend
90 {
91 public:
GncDbiBackend(GncSqlConnection * conn,QofBook * book)92 GncDbiBackend(GncSqlConnection *conn, QofBook* book) :
93 GncSqlBackend(conn, book), m_exists{false} {}
94 ~GncDbiBackend();
95 void session_begin(QofSession*, const char*, SessionOpenMode) override;
96 void session_end() override;
97 void load(QofBook*, QofBackendLoadType) override;
98 void safe_sync(QofBook*) override;
connected() const99 bool connected() const noexcept { return m_conn != nullptr; }
100 /** FIXME: Just a pass-through to m_conn: */
set_dbi_error(QofBackendError error,unsigned int repeat,bool retry)101 void set_dbi_error(QofBackendError error, unsigned int repeat,
102 bool retry) noexcept
103 {
104 m_conn->set_error(error, repeat, retry);
105 }
retry_connection(const char * msg) const106 void retry_connection(const char* msg) const noexcept
107 {
108 m_conn->retry_connection(msg);
109 }
110 /*-----*/
exists()111 bool exists() { return m_exists; }
set_exists(bool exists)112 void set_exists(bool exists) { m_exists = exists; }
113 private:
114 dbi_conn conn_setup(PairVec& options, UriStrings& uri);
115 bool conn_test_dbi_library(dbi_conn conn);
116 bool set_standard_connection_options(dbi_conn conn, const UriStrings& uri);
117 bool create_database(dbi_conn conn, const char* db);
118 bool m_exists; // Does the database exist?
119 };
120
121 /* locale-stack */
122 inline std::string
gnc_push_locale(const int category,const std::string locale)123 gnc_push_locale(const int category, const std::string locale)
124 {
125 std::string retval(setlocale(category, nullptr));
126 setlocale(category, locale.c_str());
127 return retval;
128 }
129
130 inline void
gnc_pop_locale(const int category,std::string locale)131 gnc_pop_locale(const int category, std::string locale)
132 {
133 setlocale(category, locale.c_str());
134 }
135
136 /* external access required for tests */
137 std::string adjust_sql_options_string(const std::string&);
138
139
140
141 #endif //GNC_BACKEND_DBI_HPP
142