LCOV - code coverage report
Current view: top level - libgnucash/backend/sql - gnc-sql-backend.hpp (source / functions) Coverage Total Hit
Test: gnucash.info Lines: 85.7 % 7 6
Test Date: 2026-11-02 18:19:43 Functions: 85.7 % 7 6
Legend: Lines:     hit not hit

            Line data    Source code
       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              : 
      36              : class GncSqlColumnTableEntry;
      37              : using GncSqlColumnTableEntryPtr = std::shared_ptr<GncSqlColumnTableEntry>;
      38              : using EntryVec = std::vector<GncSqlColumnTableEntryPtr>;
      39              : class GncSqlObjectBackend;
      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;
      47              : using GncSqlResultPtr = 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              : 
      59              : /**
      60              :  *
      61              :  * Main SQL backend structure.
      62              :  */
      63              : class GncSqlBackend : public QofBackend
      64              : {
      65              : public:
      66              :     GncSqlBackend(GncSqlConnection *conn, QofBook* book);
      67              :     virtual ~GncSqlBackend();
      68              :     /**
      69              :      * Load the contents of an SQL database into a book.
      70              :      *
      71              :      * @param book Book to be loaded
      72              :      */
      73              :     void load(QofBook*, QofBackendLoadType) override;
      74              :     /**
      75              :      * Save the contents of a book to an SQL database.
      76              :      *
      77              :      * @param book Book to be saved
      78              :      */
      79              :     void sync(QofBook*) override;
      80              :     /**
      81              :      * An object is about to be edited.
      82              :      *
      83              :      * @param inst Object being edited
      84              :      */
      85              :     void begin(QofInstance*) override;
      86              :     /**
      87              :      * Object editing is complete and the object should be saved.
      88              :      *
      89              :      * @param inst Object being edited
      90              :      */
      91              :     void commit(QofInstance*) override;
      92              :     /**
      93              :      * Object editing has been cancelled.
      94              :      *
      95              :      * @param inst Object being edited
      96              :      */
      97              :     void rollback(QofInstance*) override;
      98              :     /** Connect the backend to a GncSqlConnection.
      99              :      * Sets up version info. Calling with nullptr clears the connection and
     100              :      * destroys the version info.
     101              :      */
     102              :     void connect(GncSqlConnection *conn) noexcept;
     103              :     /**
     104              :      * Initializes DB table version information.
     105              :      */
     106              :     void init_version_info() noexcept;
     107              :     bool reset_version_info() noexcept;
     108              :     /**
     109              :      * Finalizes DB table version information.
     110              :      */
     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;
     114              :     /** Executes an SQL SELECT statement and returns the result rows.  If an
     115              :      * error occurs, an entry is added to the log, an error status is returned
     116              :      * to qof and nullptr is returned.
     117              :      *
     118              :      * @param statement Statement
     119              :      * @return Results, or nullptr if an error has occurred
     120              :      */
     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;
     124              :     /**
     125              :      * Creates a table in the database
     126              :      *
     127              :      * @param table_name Table name
     128              :      * @param col_table DB table description
     129              :      * @return TRUE if successful, FALSE if unsuccessful
     130              :      */
     131              :     bool create_table(const std::string& table_name, const EntryVec& col_table) const noexcept;
     132              :     /**
     133              :      * Creates a table in the database and sets its version
     134              :      *
     135              :      * @param table_name Table name
     136              :      * @param table_version Table version
     137              :      * @param col_table DB table description
     138              :      * @return TRUE if successful, FALSE if unsuccessful
     139              :      */
     140              :     bool create_table(const std::string& table_name, int table_version,
     141              :                       const EntryVec& col_table) noexcept;
     142              :     /**
     143              :      * Create/update all tables in the database
     144              :      */
     145              :     void create_tables() noexcept;
     146              : 
     147              :     /**
     148              :      * Creates an index in the database
     149              :      *
     150              :      * @param index_name Index name
     151              :      * @param table_name Table name
     152              :      * @param col_table Columns that the index should index
     153              :      * @return TRUE if successful, FALSE if unsuccessful
     154              :      */
     155              :     bool create_index(const std::string& index_name,
     156              :                       const std::string& table_name,
     157              :                       const EntryVec& col_table) const noexcept;
     158              :     /**
     159              :      * Adds one or more columns to an existing table.
     160              :      *
     161              :      * @param table_name SQL table name
     162              :      * @param new_col_table Column table for new columns
     163              :      * @return TRUE if successful, FALSE if unsuccessful
     164              :      */
     165              :     bool add_columns_to_table(const std::string& table_name,
     166              :                               const EntryVec& col_table) const noexcept;
     167              :     /**
     168              :      * Upgrades a table to a new structure.
     169              :      *
     170              :      * The upgrade is done by creating a new table with the new structure,
     171              :      * SELECTing the old data into the new table, deleting the old table, then
     172              :      * renaming the new table.  Therefore, this will only work if the new table
     173              :      * structure is similar enough to the old table that the SELECT will work.
     174              :      *
     175              :      * @param table_name SQL table name
     176              :      * @param col_table Column table
     177              :      */
     178              :     void upgrade_table (const std::string& table_name,
     179              :                         const EntryVec& col_table) noexcept;
     180              :     /**
     181              :      * Returns the version number for a DB table.
     182              :      *
     183              :      * @param table_name Table name
     184              :      * @return Version number, or 0 if the table does not exist
     185              :      */
     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;
     188              :     /**
     189              :      * Register a commodity to be committed after loading is complete.
     190              :      *
     191              :      * Necessary to save corrections made while loading.
     192              :      * @param comm The commodity item to be committed.
     193              :      */
     194              :     void commodity_for_postload_processing(gnc_commodity*);
     195              :     /**
     196              :      * Get the GncSqlObjectBackend for the indicated type.
     197              :      *
     198              :      * Required because we need to pass a pointer to this to a callback via a C
     199              :      * function.
     200              :      * @param type: The QofInstance type constant to select the object backend.
     201              :      */
     202              :     GncSqlObjectBackendPtr get_object_backend(const std::string& type) const noexcept;
     203              :     /**
     204              :      * Checks whether an object is in the database or not.
     205              :      *
     206              :      * @param table_name DB table name
     207              :      * @param obj_name QOF object type name
     208              :      * @param pObject Object to be checked
     209              :      * @param table DB table description
     210              :      * @return TRUE if the object is in the database, FALSE otherwise
     211              :      */
     212              :     bool object_in_db (const char* table_name, QofIdTypeConst obj_name,
     213              :                        const gpointer pObject, const EntryVec& table ) const noexcept;
     214              :     /**
     215              :      * Performs an operation on the database.
     216              :      *
     217              :      * @param op Operation type
     218              :      * @param table_name SQL table name
     219              :      * @param obj_name QOF object type name
     220              :      * @param pObject Gnucash object
     221              :      * @param table DB table description
     222              :      * @return TRUE if successful, FALSE if not
     223              :      */
     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;
     227              :     /**
     228              :      * Ensure that a commodity referenced in another object is in fact saved
     229              :      * in the database.
     230              :      *
     231              :      * @param comm The commodity in question
     232              :      * @return true if the commodity needed to be saved.
     233              :      */
     234              :     bool save_commodity(gnc_commodity* comm) noexcept;
     235          508 :     QofBook* book() const noexcept { return m_book; }
     236            0 :     void set_loading(bool loading) noexcept { m_loading = loading; }
     237          214 :     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:
     242              :     GncSqlConnection* m_conn = nullptr;  /**< SQL connection */
     243              :     QofBook* m_book = nullptr;           /**< The primary, main open book */
     244              :     bool m_loading;        /**< We are performing an initial load */
     245              :     bool m_in_query;       /**< We are processing a query */
     246              :     bool m_is_pristine_db; /**< Are we saving to a new pristine db? */
     247              :     const char* m_time_format = nullptr; /**< Server-specific date-time string format */
     248              :     VersionVec m_versions;    /**< Version number for each table */
     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           15 :         ~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           19 :         OBEVec::iterator begin() { return m_registry.begin(); }
     282           19 :         OBEVec::iterator end() { return m_registry.end(); }
     283            7 :         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__
        

Generated by: LCOV version 2.0-1