GnuCash  4.11-517-g41de4cefce
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 extern "C"
28 {
29 #include <qof.h>
30 #include <Account.h>
31 }
32 #include <memory>
33 #include <exception>
34 #include <sstream>
35 #include <vector>
36 #include <qof-backend.hpp>
37 
39 using GncSqlColumnTableEntryPtr = std::shared_ptr<GncSqlColumnTableEntry>;
40 using EntryVec = std::vector<GncSqlColumnTableEntryPtr>;
42 using GncSqlObjectBackendPtr = std::shared_ptr<GncSqlObjectBackend>;
43 using OBEEntry = std::tuple<std::string, GncSqlObjectBackendPtr>;
44 using OBEVec = std::vector<OBEEntry>;
45 class GncSqlConnection;
46 class GncSqlStatement;
47 using GncSqlStatementPtr = std::unique_ptr<GncSqlStatement>;
48 class GncSqlResult;
50 using VersionPair = std::pair<const std::string, unsigned int>;
51 using VersionVec = std::vector<VersionPair>;
52 using uint_t = unsigned int;
53 
54 typedef enum
55 {
56  OP_DB_INSERT,
57  OP_DB_UPDATE,
58  OP_DB_DELETE
59 } E_DB_OPERATION;
60 
65 class GncSqlBackend : public QofBackend
66 {
67 public:
68  GncSqlBackend(GncSqlConnection *conn, QofBook* book);
69  virtual ~GncSqlBackend();
75  void load(QofBook*, QofBackendLoadType) override;
81  void sync(QofBook*) override;
87  void begin(QofInstance*) override;
93  void commit(QofInstance*) override;
99  void rollback(QofInstance*) override;
104  void connect(GncSqlConnection *conn) noexcept;
108  void init_version_info() noexcept;
109  bool reset_version_info() noexcept;
113  void finalize_version_info() noexcept;
114  /* FIXME: These are just pass-throughs of m_conn functions. */
115  GncSqlStatementPtr create_statement_from_sql(const std::string& str) const noexcept;
123  GncSqlResultPtr execute_select_statement(const GncSqlStatementPtr& stmt) const noexcept;
124  int execute_nonselect_statement(const GncSqlStatementPtr& stmt) const noexcept;
125  std::string quote_string(const std::string&) const noexcept;
133  bool create_table(const std::string& table_name, const EntryVec& col_table) const noexcept;
142  bool create_table(const std::string& table_name, int table_version,
143  const EntryVec& col_table) noexcept;
147  void create_tables() noexcept;
148 
157  bool create_index(const std::string& index_name,
158  const std::string& table_name,
159  const EntryVec& col_table) const noexcept;
167  bool add_columns_to_table(const std::string& table_name,
168  const EntryVec& col_table) const noexcept;
180  void upgrade_table (const std::string& table_name,
181  const EntryVec& col_table) noexcept;
188  uint_t get_table_version(const std::string& table_name) const noexcept;
189  bool set_table_version (const std::string& table_name, uint_t version) noexcept;
196  void commodity_for_postload_processing(gnc_commodity*);
204  GncSqlObjectBackendPtr get_object_backend(const std::string& type) const noexcept;
214  bool object_in_db (const char* table_name, QofIdTypeConst obj_name,
215  const gpointer pObject, const EntryVec& table ) const noexcept;
226  bool do_db_operation (E_DB_OPERATION op, const char* table_name,
227  QofIdTypeConst obj_name, gpointer pObject,
228  const EntryVec& table) const noexcept;
236  bool save_commodity(gnc_commodity* comm) noexcept;
237  QofBook* book() const noexcept { return m_book; }
238  void set_loading(bool loading) noexcept { m_loading = loading; }
239  bool pristine() const noexcept { return m_is_pristine_db; }
240  void update_progress(double pct) const noexcept;
241  void finish_progress() const noexcept;
242 
243 protected:
245  QofBook* m_book = nullptr;
246  bool m_loading;
247  bool m_in_query;
249  const char* m_time_format = nullptr;
250  VersionVec m_versions;
251 private:
252  bool write_account_tree(Account*);
253  bool write_accounts();
254  bool write_transactions();
255  bool write_template_transactions();
256  bool write_schedXactions();
257  GncSqlStatementPtr build_insert_statement (const char* table_name,
258  QofIdTypeConst obj_name,
259  gpointer pObject,
260  const EntryVec& table) const noexcept;
261  GncSqlStatementPtr build_update_statement (const gchar* table_name,
262  QofIdTypeConst obj_name,
263  gpointer pObject,
264  const EntryVec& table) const noexcept;
265  GncSqlStatementPtr build_delete_statement (const char* table_name,
266  QofIdTypeConst obj_name,
267  gpointer pObject,
268  const EntryVec& table) const noexcept;
269 
270  class ObjectBackendRegistry
271  {
272  public:
273  ObjectBackendRegistry();
274  ObjectBackendRegistry(const ObjectBackendRegistry&) = delete;
275  ObjectBackendRegistry(const ObjectBackendRegistry&&) = delete;
276  ObjectBackendRegistry operator=(const ObjectBackendRegistry&) = delete;
277  ObjectBackendRegistry operator=(const ObjectBackendRegistry&&) = delete;
278  ~ObjectBackendRegistry() = default;
279  void register_backend(OBEEntry&& entry) noexcept;
280  void register_backend(GncSqlObjectBackendPtr obe) noexcept;
281  GncSqlObjectBackendPtr get_object_backend(const std::string& type) const;
282  void load_remaining(GncSqlBackend*);
283  OBEVec::iterator begin() { return m_registry.begin(); }
284  OBEVec::iterator end() { return m_registry.end(); }
285  OBEVec::size_type size() { return m_registry.size(); }
286  private:
287  OBEVec m_registry;
288  };
289  ObjectBackendRegistry m_backend_registry;
290  std::vector<gnc_commodity*> m_postload_commodities;
291 };
292 
293 #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:87
VersionVec m_versions
Version number for each table.
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:94
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.