GnuCash  5.6-150-g038405b370+
gnc-sql-backend.hpp
1 /***********************************************************************\
2  * gnc-sql-backend.hpp: Qof Backend for SQL Databases *
3  * *
4  * Copyright 2016 John Ralls <jralls@ceridwen.us> *
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 #ifndef __GNC_SQL_BACKEND_HPP__
25 #define __GNC_SQL_BACKEND_HPP__
26 
27 #include <qof.h>
28 #include <Account.h>
29 
30 #include <memory>
31 #include <exception>
32 #include <sstream>
33 #include <vector>
34 #include <qof-backend.hpp>
35 
37 using GncSqlColumnTableEntryPtr = std::shared_ptr<GncSqlColumnTableEntry>;
38 using EntryVec = std::vector<GncSqlColumnTableEntryPtr>;
40 using GncSqlObjectBackendPtr = std::shared_ptr<GncSqlObjectBackend>;
41 using OBEEntry = std::tuple<std::string, GncSqlObjectBackendPtr>;
42 using OBEVec = std::vector<OBEEntry>;
43 class GncSqlConnection;
44 class GncSqlStatement;
45 using GncSqlStatementPtr = std::unique_ptr<GncSqlStatement>;
46 class GncSqlResult;
48 using VersionPair = std::pair<const std::string, unsigned int>;
49 using VersionVec = std::vector<VersionPair>;
50 using uint_t = unsigned int;
51 
52 typedef enum
53 {
54  OP_DB_INSERT,
55  OP_DB_UPDATE,
56  OP_DB_DELETE
57 } E_DB_OPERATION;
58 
63 class GncSqlBackend : public QofBackend
64 {
65 public:
66  GncSqlBackend(GncSqlConnection *conn, QofBook* book);
67  virtual ~GncSqlBackend();
73  void load(QofBook*, QofBackendLoadType) override;
79  void sync(QofBook*) override;
85  void begin(QofInstance*) override;
91  void commit(QofInstance*) override;
97  void rollback(QofInstance*) override;
102  void connect(GncSqlConnection *conn) noexcept;
106  void init_version_info() noexcept;
107  bool reset_version_info() noexcept;
111  void finalize_version_info() noexcept;
112  /* FIXME: These are just pass-throughs of m_conn functions. */
113  GncSqlStatementPtr create_statement_from_sql(const std::string& str) const noexcept;
121  GncSqlResultPtr execute_select_statement(const GncSqlStatementPtr& stmt) const noexcept;
122  int execute_nonselect_statement(const GncSqlStatementPtr& stmt) const noexcept;
123  std::string quote_string(const std::string&) const noexcept;
131  bool create_table(const std::string& table_name, const EntryVec& col_table) const noexcept;
140  bool create_table(const std::string& table_name, int table_version,
141  const EntryVec& col_table) noexcept;
145  void create_tables() noexcept;
146 
155  bool create_index(const std::string& index_name,
156  const std::string& table_name,
157  const EntryVec& col_table) const noexcept;
165  bool add_columns_to_table(const std::string& table_name,
166  const EntryVec& col_table) const noexcept;
178  void upgrade_table (const std::string& table_name,
179  const EntryVec& col_table) noexcept;
186  uint_t get_table_version(const std::string& table_name) const noexcept;
187  bool set_table_version (const std::string& table_name, uint_t version) noexcept;
194  void commodity_for_postload_processing(gnc_commodity*);
202  GncSqlObjectBackendPtr get_object_backend(const std::string& type) const noexcept;
212  bool object_in_db (const char* table_name, QofIdTypeConst obj_name,
213  const gpointer pObject, const EntryVec& table ) const noexcept;
224  bool do_db_operation (E_DB_OPERATION op, const char* table_name,
225  QofIdTypeConst obj_name, gpointer pObject,
226  const EntryVec& table) const noexcept;
234  bool save_commodity(gnc_commodity* comm) noexcept;
235  QofBook* book() const noexcept { return m_book; }
236  void set_loading(bool loading) noexcept { m_loading = loading; }
237  bool pristine() const noexcept { return m_is_pristine_db; }
238  void update_progress(double pct) const noexcept;
239  void finish_progress() const noexcept;
240 
241 protected:
243  QofBook* m_book = nullptr;
244  bool m_loading;
245  bool m_in_query;
247  const char* m_time_format = nullptr;
248  VersionVec m_versions;
249 private:
250  bool write_account_tree(Account*);
251  bool write_accounts();
252  bool write_transactions();
253  bool write_template_transactions();
254  bool write_schedXactions();
255  GncSqlStatementPtr build_insert_statement (const char* table_name,
256  QofIdTypeConst obj_name,
257  gpointer pObject,
258  const EntryVec& table) const noexcept;
259  GncSqlStatementPtr build_update_statement (const gchar* table_name,
260  QofIdTypeConst obj_name,
261  gpointer pObject,
262  const EntryVec& table) const noexcept;
263  GncSqlStatementPtr build_delete_statement (const char* table_name,
264  QofIdTypeConst obj_name,
265  gpointer pObject,
266  const EntryVec& table) const noexcept;
267 
268  class ObjectBackendRegistry
269  {
270  public:
271  ObjectBackendRegistry();
272  ObjectBackendRegistry(const ObjectBackendRegistry&) = delete;
273  ObjectBackendRegistry(const ObjectBackendRegistry&&) = delete;
274  ObjectBackendRegistry operator=(const ObjectBackendRegistry&) = delete;
275  ObjectBackendRegistry operator=(const ObjectBackendRegistry&&) = delete;
276  ~ObjectBackendRegistry() = default;
277  void register_backend(OBEEntry&& entry) noexcept;
278  void register_backend(GncSqlObjectBackendPtr obe) noexcept;
279  GncSqlObjectBackendPtr get_object_backend(const std::string& type) const;
280  void load_remaining(GncSqlBackend*);
281  OBEVec::iterator begin() { return m_registry.begin(); }
282  OBEVec::iterator end() { return m_registry.end(); }
283  OBEVec::size_type size() { return m_registry.size(); }
284  private:
285  OBEVec m_registry;
286  };
287  ObjectBackendRegistry m_backend_registry;
288  std::vector<gnc_commodity*> m_postload_commodities;
289 };
290 
291 #endif //__GNC_SQL_BACKEND_HPP__
bool do_db_operation(E_DB_OPERATION op, const char *table_name, QofIdTypeConst obj_name, gpointer pObject, const EntryVec &table) const noexcept
Performs an operation on the database.
bool add_columns_to_table(const std::string &table_name, const EntryVec &col_table) const noexcept
Adds one or more columns to an existing table.
bool create_table(const std::string &table_name, const EntryVec &col_table) const noexcept
Creates a table in the database.
bool set_table_version(const std::string &table_name, uint_t version) noexcept
Registers the version for a table.
const char * m_time_format
Server-specific date-time string format.
GncSqlResultPtr execute_select_statement(const GncSqlStatementPtr &stmt) const noexcept
Executes an SQL SELECT statement and returns the result rows.
const gchar * QofIdTypeConst
QofIdTypeConst declaration.
Definition: qofid.h:82
VersionVec m_versions
Version number for each table.
STRUCTS.
void rollback(QofInstance *) override
Object editing has been cancelled.
SQL statement provider.
void commit(QofInstance *) override
Object editing is complete and the object should be saved.
void create_tables() noexcept
Create/update all tables in the database.
bool m_loading
We are performing an initial load.
void commodity_for_postload_processing(gnc_commodity *)
Register a commodity to be committed after loading is complete.
GncSqlConnection * m_conn
SQL connection.
void load(QofBook *, QofBackendLoadType) override
Load the contents of an SQL database into a book.
void sync(QofBook *) override
Save the contents of a book to an SQL database.
bool object_in_db(const char *table_name, QofIdTypeConst obj_name, const gpointer pObject, const EntryVec &table) const noexcept
Checks whether an object is in the database or not.
Account handling public routines.
bool m_in_query
We are processing a query.
bool save_commodity(gnc_commodity *comm) noexcept
Ensure that a commodity referenced in another object is in fact saved in the database.
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 upgrade_table(const std::string &table_name, const EntryVec &col_table) noexcept
Upgrades a table to a new structure.
QofBook * m_book
The primary, main open book.
GncSqlObjectBackendPtr get_object_backend(const std::string &type) const noexcept
Get the GncSqlObjectBackend for the indicated type.
void init_version_info() noexcept
Initializes DB table version information.
Encapsulates per-class table schema with functions to load, create a table, commit a changed front-en...
void begin(QofInstance *) override
An object is about to be edited.
Encapsulate the connection to the database.
bool create_index(const std::string &index_name, const std::string &table_name, const EntryVec &col_table) const noexcept
Creates an index in the database.
void connect(GncSqlConnection *conn) noexcept
Connect the backend to a GncSqlConnection.
bool m_is_pristine_db
Are we saving to a new pristine db?
Pure virtual class to iterate over a query result set.
Contains all of the information required to copy information between an object and the database for a...
bool reset_version_info() noexcept
Resets the version table information by removing all version table info.
uint_t get_table_version(const std::string &table_name) const noexcept
Returns the version number for a DB table.
Main SQL backend structure.
void finalize_version_info() noexcept
Finalizes DB table version information.