diff --git a/src/backend/dbi/gnc-backend-dbi.cpp b/src/backend/dbi/gnc-backend-dbi.cpp index 2d70f7a9fe..6aa5c0d1f2 100644 --- a/src/backend/dbi/gnc-backend-dbi.cpp +++ b/src/backend/dbi/gnc-backend-dbi.cpp @@ -294,12 +294,9 @@ create_tables(const OBEEntry& entry, GncDbiBackend* be) std::string type; GncSqlObjectBackendPtr obe = nullptr; std::tie(type, obe) = entry; - g_return_if_fail(obe->version == GNC_SQL_BACKEND_VERSION); + g_return_if_fail(obe->is_version (GNC_SQL_BACKEND_VERSION)); - if (obe->create_tables != nullptr) - { - (obe->create_tables)(&be->sql_be); - } + obe->create_tables (&be->sql_be); } static void @@ -1926,9 +1923,12 @@ init_sql_backend (GncDbiBackend* dbi_be) be->sync = gnc_dbi_safe_sync_all; be->safe_sync = gnc_dbi_safe_sync_all; - be->compile_query = gnc_sql_compile_query; - be->run_query = gnc_sql_run_query; - be->free_query = gnc_sql_free_query; +// be->compile_query = gnc_sql_compile_query; +// be->run_query = gnc_sql_run_query; +// be->free_query = gnc_sql_free_query; + be->compile_query = nullptr; + be->run_query = nullptr; + be->free_query = nullptr; be->export_fn = NULL; diff --git a/src/backend/sql/gnc-account-sql.cpp b/src/backend/sql/gnc-account-sql.cpp index a9f3149dc6..bdb3bff121 100644 --- a/src/backend/sql/gnc-account-sql.cpp +++ b/src/backend/sql/gnc-account-sql.cpp @@ -91,6 +91,18 @@ static EntryVec parent_col_table "parent_guid", 0, 0, nullptr, (QofSetterFunc)set_parent_guid), }); +class GncSqlAccountBackend : public GncSqlObjectBackend +{ +public: + GncSqlAccountBackend(int version, const std::string& type, + const std::string& table, const EntryVec& vec) : + GncSqlObjectBackend(version, type, table, vec) {} + void load_all(GncSqlBackend*) override; + bool commit(GncSqlBackend*, QofInstance*) override; +}; + + + typedef struct { Account* pAccount; @@ -198,8 +210,8 @@ load_single_account (GncSqlBackend* be, GncSqlRow& row, return pAccount; } -static void -load_all_accounts (GncSqlBackend* be) +void +GncSqlAccountBackend::load_all (GncSqlBackend* be) { GncSqlStatement* stmt = NULL; QofBook* pBook; @@ -308,23 +320,8 @@ load_all_accounts (GncSqlBackend* be) } /* ================================================================= */ -static void -create_account_tables (GncSqlBackend* be) -{ - gint version; - - g_return_if_fail (be != NULL); - - version = gnc_sql_get_table_version (be, TABLE_NAME); - if (version == 0) - { - (void)gnc_sql_create_table (be, TABLE_NAME, TABLE_VERSION, col_table); - } -} - -/* ================================================================= */ -gboolean -gnc_sql_save_account (GncSqlBackend* be, QofInstance* inst) +bool +GncSqlAccountBackend::commit (GncSqlBackend* be, QofInstance* inst) { Account* pAcc = GNC_ACCOUNT (inst); const GncGUID* guid; @@ -425,19 +422,8 @@ GncSqlColumnTableEntryImpl::add_to_query(const GncSqlBackend* be, void gnc_sql_init_account_handler (void) { - static GncSqlObjectBackend be_data = - { - GNC_SQL_BACKEND_VERSION, - GNC_ID_ACCOUNT, - gnc_sql_save_account, /* commit */ - load_all_accounts, /* initial_load */ - create_account_tables, /* create_tables */ - NULL, /* compile_query */ - NULL, /* run_query */ - NULL, /* free_query */ - NULL /* write */ - }; - + static GncSqlAccountBackend be_data{ + GNC_SQL_BACKEND_VERSION, GNC_ID_ACCOUNT, TABLE_NAME, col_table}; gnc_sql_register_backend(&be_data); } /* ========================== END OF FILE ===================== */ diff --git a/src/backend/sql/gnc-backend-sql.cpp b/src/backend/sql/gnc-backend-sql.cpp index d03ca2983c..b4b3042293 100644 --- a/src/backend/sql/gnc-backend-sql.cpp +++ b/src/backend/sql/gnc-backend-sql.cpp @@ -136,7 +136,7 @@ gnc_sql_register_backend(OBEEntry&& entry) void gnc_sql_register_backend(GncSqlObjectBackendPtr obe) { - backend_registry.emplace_back(make_tuple(std::string{obe->type_name}, obe)); + backend_registry.emplace_back(make_tuple(std::string{obe->type()}, obe)); } const OBEVec& @@ -144,6 +144,21 @@ gnc_sql_get_backend_registry() { return backend_registry; } + +GncSqlObjectBackendPtr +gnc_sql_get_object_backend(const std::string& type) +{ + auto entry = std::find_if(backend_registry.begin(), + backend_registry.end(), + [type](const OBEEntry& entry){ + return type == std::get<0>(entry); + }); + auto obe = std::get<1>(*entry); + if (entry != backend_registry.end()) + return obe; + return nullptr; +} + void gnc_sql_init(GncSqlBackend* be) { @@ -164,13 +179,9 @@ create_tables(const OBEEntry& entry, GncSqlBackend* be) std::string type; GncSqlObjectBackendPtr obe = nullptr; std::tie(type, obe) = entry; - g_return_if_fail (obe->version == GNC_SQL_BACKEND_VERSION); - - if (obe->create_tables != nullptr) - { - update_progress(be); - (obe->create_tables)(be); - } + g_return_if_fail (obe->is_version (GNC_SQL_BACKEND_VERSION)); + update_progress(be); + obe->create_tables(be); } /* ================================================================= */ @@ -195,7 +206,7 @@ initial_load(const OBEEntry& entry, GncSqlBackend* be) std::string type; GncSqlObjectBackendPtr obe = nullptr; std::tie(type, obe) = entry; - g_return_if_fail(obe->version == GNC_SQL_BACKEND_VERSION); + g_return_if_fail(obe->is_version (GNC_SQL_BACKEND_VERSION)); /* Don't need to load anything if it has already been loaded with * the fixed order. @@ -205,8 +216,7 @@ initial_load(const OBEEntry& entry, GncSqlBackend* be) if (std::find(other_load_order.begin(), other_load_order.end(), type) != other_load_order.end()) return; - if (obe->initial_load != nullptr) - (obe->initial_load)(be); + obe->load_all (be); } void @@ -243,34 +253,20 @@ gnc_sql_load (GncSqlBackend* be, QofBook* book, QofBackendLoadType loadType) /* Load any initial stuff. Some of this needs to happen in a certain order */ for (auto type : fixed_load_order) { - auto entry = std::find_if(backend_registry.begin(), - backend_registry.end(), - [type](const OBEEntry& entry){ - return type == std::get<0>(entry); - }); - auto obe = std::get<1>(*entry); - if (entry != backend_registry.end() && - obe->initial_load != nullptr) + auto obe = gnc_sql_get_object_backend(type); + if (obe) { update_progress(be); - (obe->initial_load)(be); + obe->load_all (be); } } for (auto type : other_load_order) { - auto entry = std::find_if(backend_registry.begin(), - backend_registry.end(), - [type](const OBEEntry& entry){ - return type == std::get<0>(entry); - }); - if (entry == backend_registry.end()) - continue; - auto obe = std::get<1>(*entry); - if (entry != backend_registry.end() && - obe->initial_load != nullptr) + auto obe = gnc_sql_get_object_backend(type); + if (obe) { update_progress(be); - (obe->initial_load)(be); + obe->load_all (be); } } @@ -287,7 +283,8 @@ gnc_sql_load (GncSqlBackend* be, QofBook* book, QofBackendLoadType loadType) else if (loadType == LOAD_TYPE_LOAD_ALL) { // Load all transactions - gnc_sql_transaction_load_all_tx (be); + auto obe = gnc_sql_get_object_backend (GNC_ID_TRANS); + obe->load_all (be); } be->loading = FALSE; @@ -315,13 +312,14 @@ write_account_tree (GncSqlBackend* be, Account* root) g_return_val_if_fail (be != NULL, FALSE); g_return_val_if_fail (root != NULL, FALSE); - is_ok = gnc_sql_save_account (be, QOF_INSTANCE (root)); + auto obe = gnc_sql_get_object_backend (GNC_ID_ACCOUNT); + is_ok = obe->commit (be, QOF_INSTANCE (root)); if (is_ok) { descendants = gnc_account_get_descendants (root); for (node = descendants; node != NULL && is_ok; node = g_list_next (node)) { - is_ok = gnc_sql_save_account (be, QOF_INSTANCE (GNC_ACCOUNT (node->data))); + is_ok = obe->commit(be, QOF_INSTANCE (GNC_ACCOUNT (node->data))); if (!is_ok) break; } g_list_free (descendants); @@ -349,36 +347,34 @@ write_accounts (GncSqlBackend* be) return is_ok; } -static int +static gboolean write_tx (Transaction* tx, gpointer data) { - write_objects_t* s = (write_objects_t*)data; + auto s = static_cast(data); g_return_val_if_fail (tx != NULL, 0); g_return_val_if_fail (data != NULL, 0); - s->is_ok = gnc_sql_save_transaction (s->be, QOF_INSTANCE (tx)); + s->commit (QOF_INSTANCE (tx)); + auto splitbe = gnc_sql_get_object_backend (GNC_ID_SPLIT); + for (auto split_node = xaccTransGetSplitList (tx); + split_node != nullptr && s->is_ok; + split_node = g_list_next (split_node)) + { + s->is_ok = splitbe->commit(s->be, QOF_INSTANCE(split_node->data)); + } update_progress (s->be); - - if (s->is_ok) - { - return 0; - } - else - { - return 1; - } + return (s->is_ok ? 0 : 1); } static gboolean write_transactions (GncSqlBackend* be) { - write_objects_t data; - g_return_val_if_fail (be != NULL, FALSE); - data.be = be; - data.is_ok = TRUE; + auto obe = gnc_sql_get_object_backend(GNC_ID_TRANS); + write_objects_t data{be, true, obe}; + (void)xaccAccountTreeForEachTransaction ( gnc_book_get_root_account (be->book), write_tx, &data); update_progress (be); @@ -388,14 +384,11 @@ write_transactions (GncSqlBackend* be) static gboolean write_template_transactions (GncSqlBackend* be) { - Account* ra; - write_objects_t data; - g_return_val_if_fail (be != NULL, FALSE); - data.is_ok = TRUE; - data.be = be; - ra = gnc_book_get_template_root (be->book); + auto obe = gnc_sql_get_object_backend(GNC_ID_TRANS); + write_objects_t data{be, true, obe}; + auto ra = gnc_book_get_template_root (be->book); if (gnc_account_n_descendants (ra) > 0) { (void)xaccAccountTreeForEachTransaction (ra, write_tx, &data); @@ -415,32 +408,18 @@ write_schedXactions (GncSqlBackend* be) g_return_val_if_fail (be != NULL, FALSE); schedXactions = gnc_book_get_schedxactions (be->book)->sx_list; + auto obe = gnc_sql_get_object_backend(GNC_ID_SCHEDXACTION); for (; schedXactions != NULL && is_ok; schedXactions = schedXactions->next) { tmpSX = static_cast (schedXactions->data); - is_ok = gnc_sql_save_schedxaction (be, QOF_INSTANCE (tmpSX)); + is_ok = obe->commit (be, QOF_INSTANCE (tmpSX)); } update_progress (be); return is_ok; } -static void -write(const OBEEntry& entry, GncSqlBackend* be) -{ - std::string type; - GncSqlObjectBackendPtr obe = nullptr; - std::tie(type, obe) = entry; - g_return_if_fail (obe->version == GNC_SQL_BACKEND_VERSION); - - if (obe->write != nullptr) - { - (void)(obe->write)(be); - update_progress(be); - } -} - static void update_progress (GncSqlBackend* be) { @@ -486,7 +465,8 @@ gnc_sql_sync_all (GncSqlBackend* be, QofBook* book) //write_commodities( be, book ); if (is_ok) { - is_ok = gnc_sql_save_book (be, QOF_INSTANCE (book)); + auto obe = gnc_sql_get_object_backend(GNC_ID_BOOK); + is_ok = obe->commit (be, QOF_INSTANCE (book)); } if (is_ok) { @@ -507,7 +487,7 @@ gnc_sql_sync_all (GncSqlBackend* be, QofBook* book) if (is_ok) { for (auto entry : backend_registry) - write(entry, be); + std::get<1>(entry)->write (be); } if (is_ok) { @@ -561,7 +541,7 @@ commit(const OBEEntry& entry, sql_backend* be_data) std::string type; GncSqlObjectBackendPtr obe= nullptr; std::tie(type, obe) = entry; - g_return_if_fail (obe->version == GNC_SQL_BACKEND_VERSION); + g_return_if_fail (obe->is_version (GNC_SQL_BACKEND_VERSION)); /* If this has already been handled, or is not the correct * handler, return @@ -569,11 +549,8 @@ commit(const OBEEntry& entry, sql_backend* be_data) if (type != std::string{be_data->inst->e_type}) return; if (be_data->is_known) return; - if (obe->commit != nullptr) - { - be_data->is_ok = (obe->commit)(be_data->be, be_data->inst); - be_data->is_known = TRUE; - } + be_data->is_ok = obe->commit (be_data->be, be_data->inst); + be_data->is_known = TRUE; } /* Commit_edit handler - find the correct backend handler for this object @@ -823,26 +800,23 @@ handle_and_term (QofQueryTerm* pTerm, GString* sql) g_string_append (sql, ")"); } - +#if 0 //The query compilation code was never tested so it isn't implemnted for GncSqlObjectBackend. static void compile_query(const OBEEntry& entry, sql_backend* be_data) { std::string type; GncSqlObjectBackendPtr obe = nullptr; std::tie(type, obe) = entry; - g_return_if_fail (obe->version == GNC_SQL_BACKEND_VERSION); + g_return_if_fail (obe->is_version (GNC_SQL_BACKEND_VERSION)); // Is this the right item? if (type != std::string{be_data->pQueryInfo->searchObj}) return; if (be_data->is_ok) return; - if (obe->compile_query != nullptr) - { - be_data->pQueryInfo->pCompiledQuery = (obe->compile_query)( - be_data->be, - be_data->pQuery); - be_data->is_ok = TRUE; - } + be_data->pQueryInfo->pCompiledQuery = (obe->compile_query)( + be_data->be, + be_data->pQuery); + be_data->is_ok = TRUE; } gchar* gnc_sql_compile_query_to_sql (GncSqlBackend* be, QofQuery* query); @@ -1052,7 +1026,7 @@ gnc_sql_run_query (QofBackend* pBEnd, gpointer pQuery) LEAVE (""); } - +#endif //if 0: query creation isn't used yet, code never tested. /* ================================================================= */ /* Order in which business objects need to be loaded */ static const StrVec business_fixed_load_order = @@ -2199,10 +2173,8 @@ build_delete_statement (GncSqlBackend* be, } /* ================================================================= */ -gboolean -gnc_sql_commit_standard_item (GncSqlBackend* be, QofInstance* inst, - const gchar* tableName, QofIdTypeConst obj_name, - const EntryVec& col_table) +bool +GncSqlObjectBackend::commit (GncSqlBackend* be, QofInstance* inst) { const GncGUID* guid; gboolean is_infant; @@ -2222,7 +2194,8 @@ gnc_sql_commit_standard_item (GncSqlBackend* be, QofInstance* inst, { op = OP_DB_UPDATE; } - is_ok = gnc_sql_do_db_operation (be, op, tableName, obj_name, inst, col_table); + is_ok = gnc_sql_do_db_operation (be, op, m_table_name.c_str(), + m_type_name.c_str(), inst, m_col_table); if (is_ok) { @@ -2280,6 +2253,19 @@ gnc_sql_create_table (GncSqlBackend* be, const char* table_name, return ok; } +void +GncSqlObjectBackend::create_tables (GncSqlBackend* be) +{ + g_return_if_fail (be != nullptr); + int version = gnc_sql_get_table_version (be, m_table_name.c_str()); + if (version == 0) //No tables, otherwise version will be >= 1. + gnc_sql_create_table (be, m_table_name.c_str(), + m_version, m_col_table); + else if (version != m_version) + PERR("Version mismatch in table %s, expecting %d but backend is %d." + "Table creation aborted.", m_table_name.c_str(), m_version, version); +} + gboolean gnc_sql_create_temp_table (const GncSqlBackend* be, const gchar* table_name, const EntryVec& col_table) diff --git a/src/backend/sql/gnc-backend-sql.h b/src/backend/sql/gnc-backend-sql.h index 5cb0279ab8..78fc33961f 100644 --- a/src/backend/sql/gnc-backend-sql.h +++ b/src/backend/sql/gnc-backend-sql.h @@ -282,51 +282,100 @@ inline bool operator==(const GncSqlRow& lr, const GncSqlRow& rr) { return !(lr != rr); } -/** - * @struct GncSqlObjectBackend - * - * Struct used to handle a specific engine object type for an SQL backend. - * This handler should be registered with gnc_sql_register_backend(). - * - * commit() - commit an object to the db - * initial_load() - load stuff when new db opened - * create_tables() - create any db tables - * compile_query() - compile a backend object query - * run_query() - run a compiled query - * free_query() - free a compiled query - * write() - write all objects - */ -typedef struct -{ - int version; /**< Backend version number */ - const std::string type_name; /**< Engine object type name */ - /** Commit an instance of this object to the database - * @return TRUE if successful, FALSE if error - */ - gboolean (*commit) (GncSqlBackend* be, QofInstance* inst); - /** Load all objects of this type from the database */ - void (*initial_load) (GncSqlBackend* be); - /** Create database tables for this object */ - void (*create_tables) (GncSqlBackend* be); - /** Compile a query on these objects */ - gpointer (*compile_query) (GncSqlBackend* be, QofQuery* pQuery); - /** Run a query on these objects */ - void (*run_query) (GncSqlBackend* be, gpointer pQuery); - /** Free a query on these objects */ - void (*free_query) (GncSqlBackend* be, gpointer pQuery); - /** Write all objects of this type to the database - * @return TRUE if successful, FALSE if error - */ - gboolean (*write) (GncSqlBackend* be); -} GncSqlObjectBackend; #define GNC_SQL_BACKEND "gnc:sql:1" #define GNC_SQL_BACKEND_VERSION 1 + +/** + * Encapsulates per-class table schema with functions to load, create a table, + * commit a changed front-end object (note that database transaction semantics + * are not yet implemented; edit/commit applies to the front-end object!) and + * write all front-end objects of the type to the database. Additional functions + * for creating and runing queries existed but were unused and untested. They've + * been temporarily removed until the front end is ready to use them. + */ +class GncSqlObjectBackend +{ +public: + GncSqlObjectBackend (int version, const std::string& type, + const std::string& table, const EntryVec& vec) : + m_table_name{table}, m_version{version}, m_type_name{type}, + m_col_table{vec} {} + /** + * Load all objects of m_type in the database into memory. + * @param be The GncSqlBackend containing the database connection. + */ + virtual void load_all (GncSqlBackend*) = 0; + /** + * Conditionally create or update a database table from m_col_table. The + * condition is the version returned by querying the database's version + * table: If it's 0 then the table wasn't found and will be created; All + * tables areat least version 1. If the database's version is less than the + * compiled version then the table schema is upgraded but the data isn't, + * that's the engine's responsibility when the object is loaded. If the + * version is greater than the compiled version then nothing is touched. + * @param be The GncSqlBackend containing the database connection. + */ + virtual void create_tables (GncSqlBackend*); + /** + * UPDATE/INSERT a single instance of m_type_name into the database. + * @param be The GncSqlBackend containing the database. + * @param inst The QofInstance to be written out. + */ + virtual bool commit (GncSqlBackend* be, QofInstance* inst); + /** + * Write all objects of m_type_name to the database. + * @param be The GncSqlBackend containing the database. + * @return true if the objects were successfully written, false otherwise. + */ + virtual bool write (GncSqlBackend*) { return true; } + /** + * Return the m_type_name for the class. This value is created at + * compilation time and is called QofIdType or QofIdTypeConst in other parts + * of GnuCash. Most values are defined in src/engine/gnc-engine.h. + * @return m_type_name. + */ + const char* type () const noexcept { return m_type_name.c_str(); } + /** + * Compare a version with the compiled version (m_version). + * @return true if they match. + */ + const bool is_version (int version) const noexcept { + return version == m_version; + } +protected: + const std::string m_table_name; + const int m_version; + const std::string m_type_name; /// The front-end QofIdType + const EntryVec& m_col_table; /// The ORM table definition. +}; + using GncSqlObjectBackendPtr = GncSqlObjectBackend*; + using OBEEntry = std::tuple; using OBEVec = std::vector; void gnc_sql_register_backend(OBEEntry&&); void gnc_sql_register_backend(GncSqlObjectBackendPtr); const OBEVec& gnc_sql_get_backend_registry(); +GncSqlObjectBackendPtr gnc_sql_get_object_backend(const std::string& table_name); + +/** + * Data-passing struct for callbacks to qof_object_foreach() used in + * GncSqlObjectBackend::write(). Once QofCollection is rewritten to use C++ + * containers we'll use std::foreach() and lambdas instead of callbacks and this + * can go away. + */ +struct write_objects_t +{ + write_objects_t() = default; + write_objects_t (GncSqlBackend* b, bool o, GncSqlObjectBackendPtr e) : + be{b}, is_ok{o}, obe{e} {} + void commit (QofInstance* inst) { + if (is_ok) is_ok = obe->commit (be, inst); + } + GncSqlBackend* be; + bool is_ok; + GncSqlObjectBackendPtr obe; +}; /** * Basic column type @@ -959,12 +1008,6 @@ gpointer gnc_sql_compile_query (QofBackend* pBEnd, QofQuery* pQuery); void gnc_sql_free_query (QofBackend* pBEnd, gpointer pQuery); void gnc_sql_run_query (QofBackend* pBEnd, gpointer pQuery); -typedef struct -{ - GncSqlBackend* be; - gboolean is_ok; -} write_objects_t; - template T GncSqlColumnTableEntry::get_row_value_from_object(QofIdTypeConst obj_name, const gpointer pObject) const diff --git a/src/backend/sql/gnc-bill-term-sql.cpp b/src/backend/sql/gnc-bill-term-sql.cpp index 718fec1803..af06bd2fb9 100644 --- a/src/backend/sql/gnc-bill-term-sql.cpp +++ b/src/backend/sql/gnc-bill-term-sql.cpp @@ -95,6 +95,17 @@ static EntryVec billterm_parent_col_table bt_set_parent_guid), }; +class GncSqlBillTermBackend : public GncSqlObjectBackend +{ +public: + GncSqlBillTermBackend(int version, const std::string& type, + const std::string& table, const EntryVec& vec) : + GncSqlObjectBackend(version, type, table, vec) {} + void load_all(GncSqlBackend*) override; + void create_tables(GncSqlBackend*) override; + bool write(GncSqlBackend*) override; +}; + typedef struct { GncBillTerm* billterm; @@ -221,8 +232,8 @@ load_single_billterm (GncSqlBackend* be, GncSqlRow& row, return pBillTerm; } -static void -load_all_billterms (GncSqlBackend* be) +void +GncSqlBillTermBackend::load_all (GncSqlBackend* be) { GncSqlStatement* stmt; @@ -278,7 +289,8 @@ load_all_billterms (GncSqlBackend* be) typedef struct { GncSqlBackend* be; - gboolean is_ok; + GncSqlBillTermBackend* btbe; + bool is_ok; } write_billterms_t; static void @@ -288,26 +300,24 @@ do_save_billterm (QofInstance* inst, gpointer p2) if (data->is_ok) { - data->is_ok = gnc_sql_save_billterm (data->be, inst); + data->is_ok = data->btbe->commit (data->be, inst); } } -static gboolean -write_billterms (GncSqlBackend* be) +bool +GncSqlBillTermBackend::write (GncSqlBackend* be) { - write_billterms_t data; + write_billterms_t data {be, this, true}; g_return_val_if_fail (be != NULL, FALSE); - data.be = be; - data.is_ok = TRUE; qof_object_foreach (GNC_ID_BILLTERM, be->book, do_save_billterm, &data); return data.is_ok; } /* ================================================================= */ -static void -create_billterm_tables (GncSqlBackend* be) +void +GncSqlBillTermBackend::create_tables (GncSqlBackend* be) { gint version; @@ -329,18 +339,6 @@ create_billterm_tables (GncSqlBackend* be) } } -/* ================================================================= */ -gboolean -gnc_sql_save_billterm (GncSqlBackend* be, QofInstance* inst) -{ - g_return_val_if_fail (inst != NULL, FALSE); - g_return_val_if_fail (GNC_IS_BILLTERM (inst), FALSE); - g_return_val_if_fail (be != NULL, FALSE); - - return gnc_sql_commit_standard_item (be, inst, TABLE_NAME, GNC_ID_BILLTERM, - col_table); -} - /* ================================================================= */ template<> void @@ -374,17 +372,8 @@ GncSqlColumnTableEntryImpl::add_to_query(const GncSqlBackend* be void gnc_billterm_sql_initialize (void) { - static GncSqlObjectBackend be_data = - { - GNC_SQL_BACKEND_VERSION, - GNC_ID_BILLTERM, - gnc_sql_save_billterm, /* commit */ - load_all_billterms, /* initial_load */ - create_billterm_tables, /* create_tables */ - NULL, NULL, NULL, - write_billterms /* write */ - }; - + static GncSqlBillTermBackend be_data { + GNC_SQL_BACKEND_VERSION, GNC_ID_BILLTERM, TABLE_NAME, col_table}; gnc_sql_register_backend(&be_data); } /* ========================== END OF FILE ===================== */ diff --git a/src/backend/sql/gnc-bill-term-sql.h b/src/backend/sql/gnc-bill-term-sql.h index 442e1cf1ea..af6cced1b3 100644 --- a/src/backend/sql/gnc-bill-term-sql.h +++ b/src/backend/sql/gnc-bill-term-sql.h @@ -36,6 +36,5 @@ extern "C" #include "qof.h" } void gnc_billterm_sql_initialize (void); -gboolean gnc_sql_save_billterm (GncSqlBackend* be, QofInstance* inst); #endif /* GNC_BILLTERM_SQL_H */ diff --git a/src/backend/sql/gnc-book-sql.cpp b/src/backend/sql/gnc-book-sql.cpp index ea30076fdf..2145172b21 100644 --- a/src/backend/sql/gnc-book-sql.cpp +++ b/src/backend/sql/gnc-book-sql.cpp @@ -68,6 +68,15 @@ static const EntryVec col_table set_root_template_guid) }; +class GncSqlBookBackend : public GncSqlObjectBackend +{ +public: + GncSqlBookBackend(int version, const std::string& type, + const std::string& table, const EntryVec& vec) : + GncSqlObjectBackend(version, type, table, vec) {} + void load_all(GncSqlBackend*) override; +}; + /* ================================================================= */ static gpointer get_root_account_guid (gpointer pObject) @@ -157,8 +166,8 @@ load_single_book (GncSqlBackend* be, GncSqlRow& row) qof_instance_mark_clean (QOF_INSTANCE (pBook)); } -static void -load_all_books (GncSqlBackend* be) +void +GncSqlBookBackend::load_all (GncSqlBackend* be) { GncSqlStatement* stmt; @@ -177,7 +186,7 @@ load_all_books (GncSqlBackend* be) if (row == result->end()) { be->loading = FALSE; - (void)gnc_sql_save_book (be, QOF_INSTANCE (be->book)); + commit(be, QOF_INSTANCE (be->book)); be->loading = TRUE; } else @@ -188,54 +197,12 @@ load_all_books (GncSqlBackend* be) } } -/* ================================================================= */ -static void -create_book_tables (GncSqlBackend* be) -{ - gint version; - - g_return_if_fail (be != NULL); - - version = gnc_sql_get_table_version (be, BOOK_TABLE); - if (version == 0) - { - (void)gnc_sql_create_table (be, BOOK_TABLE, TABLE_VERSION, col_table); - } -} - -/* ================================================================= */ -gboolean -gnc_sql_save_book (GncSqlBackend* be, QofInstance* inst) -{ - gboolean status; - - g_return_val_if_fail (be != NULL, FALSE); - g_return_val_if_fail (inst != NULL, FALSE); - g_return_val_if_fail (QOF_IS_BOOK (inst), FALSE); - - status = gnc_sql_commit_standard_item (be, inst, BOOK_TABLE, GNC_ID_BOOK, - col_table); - - return status; -} - /* ================================================================= */ void gnc_sql_init_book_handler (void) { - static GncSqlObjectBackend be_data = - { - GNC_SQL_BACKEND_VERSION, - GNC_ID_BOOK, - gnc_sql_save_book, /* commit */ - load_all_books, /* initial_load */ - create_book_tables, /* create_tables */ - NULL, /* compile_query */ - NULL, /* run_query */ - NULL, /* free_query */ - NULL /* write */ - }; - + static GncSqlBookBackend be_data { + GNC_SQL_BACKEND_VERSION, GNC_ID_BOOK, BOOK_TABLE, col_table}; gnc_sql_register_backend(&be_data); } /* ========================== END OF FILE ===================== */ diff --git a/src/backend/sql/gnc-book-sql.h b/src/backend/sql/gnc-book-sql.h index 5a5c1f73cb..b1afb3eeb4 100644 --- a/src/backend/sql/gnc-book-sql.h +++ b/src/backend/sql/gnc-book-sql.h @@ -35,6 +35,5 @@ extern "C" #include "qof.h" } void gnc_sql_init_book_handler (void); -gboolean gnc_sql_save_book (GncSqlBackend* be, QofInstance* inst); #endif /* GNC_BOOK_SQL_H */ diff --git a/src/backend/sql/gnc-budget-sql.cpp b/src/backend/sql/gnc-budget-sql.cpp index 231851305e..beb87c27ea 100644 --- a/src/backend/sql/gnc-budget-sql.cpp +++ b/src/backend/sql/gnc-budget-sql.cpp @@ -76,6 +76,20 @@ static void set_period_num (gpointer pObj, gpointer val); static gnc_numeric get_amount (gpointer pObj); static void set_amount (gpointer pObj, gnc_numeric value); +class GncSqlBudgetBackend : public GncSqlObjectBackend +{ +public: + GncSqlBudgetBackend(int version, const std::string& type, + const std::string& table, const EntryVec& vec) : + GncSqlObjectBackend(version, type, table, vec) {} + void load_all(GncSqlBackend*) override; + void create_tables(GncSqlBackend*) override; + bool commit (GncSqlBackend* be, QofInstance* inst) override; + bool write(GncSqlBackend*) override; +private: + static void save(QofInstance*, void*); +}; + typedef struct { GncBudget* budget; @@ -318,8 +332,8 @@ load_single_budget (GncSqlBackend* be, GncSqlRow& row) return pBudget; } -static void -load_all_budgets (GncSqlBackend* be) +void +GncSqlBudgetBackend::load_all (GncSqlBackend* be) { GncSqlStatement* stmt; GList* list = NULL; @@ -349,8 +363,8 @@ load_all_budgets (GncSqlBackend* be) } /* ================================================================= */ -static void -create_budget_tables (GncSqlBackend* be) +void +GncSqlBudgetBackend::create_tables (GncSqlBackend* be) { gint version; @@ -371,8 +385,8 @@ create_budget_tables (GncSqlBackend* be) } /* ================================================================= */ -static gboolean -save_budget (GncSqlBackend* be, QofInstance* inst) +bool +GncSqlBudgetBackend::commit (GncSqlBackend* be, QofInstance* inst) { GncBudget* pBudget = GNC_BUDGET (inst); const GncGUID* guid; @@ -435,18 +449,18 @@ save_budget (GncSqlBackend* be, QofInstance* inst) } static void -do_save_budget (QofInstance* inst, gpointer data) +do_save (QofInstance* inst, gpointer data) { write_objects_t* s = (write_objects_t*)data; if (s->is_ok) { - s->is_ok = save_budget (s->be, inst); + s->is_ok = s->obe->commit (s->be, inst); } } -static gboolean -write_budgets (GncSqlBackend* be) +bool +GncSqlBudgetBackend::write (GncSqlBackend* be) { write_objects_t data; @@ -454,8 +468,9 @@ write_budgets (GncSqlBackend* be) data.be = be; data.is_ok = TRUE; + data.obe = this; qof_collection_foreach (qof_book_get_collection (be->book, GNC_ID_BUDGET), - (QofInstanceForeachCB)do_save_budget, &data); + (QofInstanceForeachCB)do_save, &data); return data.is_ok; } @@ -492,19 +507,8 @@ GncSqlColumnTableEntryImpl::add_to_query(const GncSqlBackend* be, void gnc_sql_init_budget_handler (void) { - static GncSqlObjectBackend be_data = - { - GNC_SQL_BACKEND_VERSION, - GNC_ID_BUDGET, - save_budget, /* commit */ - load_all_budgets, /* initial_load */ - create_budget_tables, /* create_tables */ - NULL, /* compile_query */ - NULL, /* run_query */ - NULL, /* free_query */ - write_budgets /* write */ - }; - + static GncSqlBudgetBackend be_data { + GNC_SQL_BACKEND_VERSION, GNC_ID_BUDGET, BUDGET_TABLE, col_table}; gnc_sql_register_backend(&be_data); } /* ========================== END OF FILE ===================== */ diff --git a/src/backend/sql/gnc-commodity-sql.cpp b/src/backend/sql/gnc-commodity-sql.cpp index 82c2972c69..a77090d3d3 100644 --- a/src/backend/sql/gnc-commodity-sql.cpp +++ b/src/backend/sql/gnc-commodity-sql.cpp @@ -84,6 +84,16 @@ static const EntryVec col_table "quote_tz", COMMODITY_MAX_QUOTE_TZ_LEN, 0, "quote-tz"), }; +class GncSqlCommodityBackend : public GncSqlObjectBackend +{ +public: + GncSqlCommodityBackend(int version, const std::string& type, + const std::string& table, const EntryVec& vec) : + GncSqlObjectBackend(version, type, table, vec) {} + void load_all(GncSqlBackend*) override; + bool commit(GncSqlBackend*, QofInstance*) override; +}; + /* ================================================================= */ static gpointer @@ -130,8 +140,8 @@ load_single_commodity (GncSqlBackend* be, GncSqlRow& row) return pCommodity; } -static void -load_all_commodities (GncSqlBackend* be) +void +GncSqlCommodityBackend::load_all (GncSqlBackend* be) { GncSqlStatement* stmt; gnc_commodity_table* pTable; @@ -163,21 +173,6 @@ load_all_commodities (GncSqlBackend* be) g_free (sql); } } -/* ================================================================= */ -static void -create_commodities_tables (GncSqlBackend* be) -{ - gint version; - - g_return_if_fail (be != NULL); - - version = gnc_sql_get_table_version (be, COMMODITIES_TABLE); - if (version == 0) - { - (void)gnc_sql_create_table (be, COMMODITIES_TABLE, TABLE_VERSION, col_table); - } -} - /* ================================================================= */ static gboolean do_commit_commodity (GncSqlBackend* be, QofInstance* inst, @@ -221,8 +216,8 @@ do_commit_commodity (GncSqlBackend* be, QofInstance* inst, return is_ok; } -static gboolean -commit_commodity (GncSqlBackend* be, QofInstance* inst) +bool +GncSqlCommodityBackend::commit (GncSqlBackend* be, QofInstance* inst) { g_return_val_if_fail (be != NULL, FALSE); g_return_val_if_fail (inst != NULL, FALSE); @@ -298,19 +293,9 @@ GncSqlColumnTableEntryImpl::add_to_query(const GncSqlBackend* b void gnc_sql_init_commodity_handler (void) { - static GncSqlObjectBackend be_data = + static GncSqlCommodityBackend be_data = { - GNC_SQL_BACKEND_VERSION, - GNC_ID_COMMODITY, - commit_commodity, /* commit */ - load_all_commodities, /* initial_load */ - create_commodities_tables, /* create_tables */ - NULL, /* compile_query */ - NULL, /* run_query */ - NULL, /* free_query */ - NULL /* write */ - }; - + GNC_SQL_BACKEND_VERSION, GNC_ID_COMMODITY, COMMODITIES_TABLE, col_table}; gnc_sql_register_backend(&be_data); } /* ========================== END OF FILE ===================== */ diff --git a/src/backend/sql/gnc-customer-sql.cpp b/src/backend/sql/gnc-customer-sql.cpp index 583629fe23..c8b8c6ab09 100644 --- a/src/backend/sql/gnc-customer-sql.cpp +++ b/src/backend/sql/gnc-customer-sql.cpp @@ -90,6 +90,17 @@ static EntryVec col_table (QofSetterFunc)gncCustomerSetTaxTable), }); +class GncSqlCustomerBackend : public GncSqlObjectBackend +{ +public: + GncSqlCustomerBackend(int version, const std::string& type, + const std::string& table, const EntryVec& vec) : + GncSqlObjectBackend(version, type, table, vec) {} + void load_all(GncSqlBackend*) override; + void create_tables(GncSqlBackend*) override; + bool write(GncSqlBackend*) override; +}; + static GncCustomer* load_single_customer (GncSqlBackend* be, GncSqlRow& row) { @@ -110,8 +121,8 @@ load_single_customer (GncSqlBackend* be, GncSqlRow& row) return pCustomer; } -static void -load_all_customers (GncSqlBackend* be) +void +GncSqlCustomerBackend::load_all (GncSqlBackend* be) { GncSqlStatement* stmt; @@ -140,8 +151,8 @@ load_all_customers (GncSqlBackend* be) } /* ================================================================= */ -static void -create_customer_tables (GncSqlBackend* be) +void +GncSqlCustomerBackend::create_tables (GncSqlBackend* be) { gint version; @@ -164,24 +175,6 @@ create_customer_tables (GncSqlBackend* be) } /* ================================================================= */ -static gboolean -save_customer (GncSqlBackend* be, QofInstance* inst) -{ - g_return_val_if_fail (inst != NULL, FALSE); - g_return_val_if_fail (GNC_CUSTOMER (inst), FALSE); - g_return_val_if_fail (be != NULL, FALSE); - - return gnc_sql_commit_standard_item (be, inst, TABLE_NAME, GNC_ID_CUSTOMER, - col_table); -} - -/* ================================================================= */ -typedef struct -{ - GncSqlBackend* be; - gboolean is_ok; -} write_customers_t; - static gboolean customer_should_be_saved (GncCustomer* customer) { @@ -202,7 +195,7 @@ customer_should_be_saved (GncCustomer* customer) static void write_single_customer (QofInstance* term_p, gpointer data_p) { - write_customers_t* data = (write_customers_t*)data_p; + auto data = reinterpret_cast(data_p); g_return_if_fail (term_p != NULL); g_return_if_fail (GNC_IS_CUSTOMER (term_p)); @@ -210,19 +203,20 @@ write_single_customer (QofInstance* term_p, gpointer data_p) if (customer_should_be_saved (GNC_CUSTOMER (term_p)) && data->is_ok) { - data->is_ok = save_customer (data->be, term_p); + data->is_ok = data->obe->commit (data->be, term_p); } } -static gboolean -write_customers (GncSqlBackend* be) +bool +GncSqlCustomerBackend::write (GncSqlBackend* be) { - write_customers_t data; + write_objects_t data; g_return_val_if_fail (be != NULL, FALSE); data.be = be; data.is_ok = TRUE; + data.obe = this; qof_object_foreach (GNC_ID_CUSTOMER, be->book, write_single_customer, (gpointer)&data); return data.is_ok; @@ -232,17 +226,8 @@ write_customers (GncSqlBackend* be) void gnc_customer_sql_initialize (void) { - static GncSqlObjectBackend be_data = - { - GNC_SQL_BACKEND_VERSION, - GNC_ID_CUSTOMER, - save_customer, /* commit */ - load_all_customers, /* initial_load */ - create_customer_tables, /* create_tables */ - NULL, NULL, NULL, - write_customers /* write */ - }; - + static GncSqlCustomerBackend be_data { + GNC_SQL_BACKEND_VERSION, GNC_ID_CUSTOMER, TABLE_NAME, col_table}; gnc_sql_register_backend(&be_data); } /* ========================== END OF FILE ===================== */ diff --git a/src/backend/sql/gnc-employee-sql.cpp b/src/backend/sql/gnc-employee-sql.cpp index 20e2df7ed3..b66ba07c1f 100644 --- a/src/backend/sql/gnc-employee-sql.cpp +++ b/src/backend/sql/gnc-employee-sql.cpp @@ -75,6 +75,18 @@ static EntryVec col_table gnc_sql_make_table_entry("addr", 0, 0, "address"), }); +class GncSqlEmployeeBackend : public GncSqlObjectBackend +{ +public: + GncSqlEmployeeBackend(int version, const std::string& type, + const std::string& table, const EntryVec& vec) : + GncSqlObjectBackend(version, type, table, vec) {} + void load_all(GncSqlBackend*) override; + void create_tables(GncSqlBackend*) override; + bool commit(GncSqlBackend*, QofInstance*) override; + bool write(GncSqlBackend*) override; +}; + static GncEmployee* load_single_employee (GncSqlBackend* be, GncSqlRow& row) { @@ -95,8 +107,8 @@ load_single_employee (GncSqlBackend* be, GncSqlRow& row) return pEmployee; } -static void -load_all_employees (GncSqlBackend* be) +void +GncSqlEmployeeBackend::load_all (GncSqlBackend* be) { GncSqlStatement* stmt; @@ -126,8 +138,8 @@ load_all_employees (GncSqlBackend* be) } /* ================================================================= */ -static void -create_employee_tables (GncSqlBackend* be) +void +GncSqlEmployeeBackend::create_tables (GncSqlBackend* be) { gint version; @@ -150,8 +162,8 @@ create_employee_tables (GncSqlBackend* be) } /* ================================================================= */ -static gboolean -save_employee (GncSqlBackend* be, QofInstance* inst) +bool +GncSqlEmployeeBackend::commit (GncSqlBackend* be, QofInstance* inst) { GncEmployee* emp; const GncGUID* guid; @@ -236,12 +248,12 @@ write_single_employee (QofInstance* term_p, gpointer data_p) if (s->is_ok && employee_should_be_saved (GNC_EMPLOYEE (term_p))) { - s->is_ok = save_employee (s->be, term_p); + s->is_ok = s->obe->commit (s->be, term_p); } } -static gboolean -write_employees (GncSqlBackend* be) +bool +GncSqlEmployeeBackend::write (GncSqlBackend* be) { write_objects_t data; @@ -249,6 +261,7 @@ write_employees (GncSqlBackend* be) data.be = be; data.is_ok = TRUE; + data.obe = this; qof_object_foreach (GNC_ID_EMPLOYEE, be->book, write_single_employee, &data); return data.is_ok; @@ -258,17 +271,8 @@ write_employees (GncSqlBackend* be) void gnc_employee_sql_initialize (void) { - static GncSqlObjectBackend be_data = - { - GNC_SQL_BACKEND_VERSION, - GNC_ID_EMPLOYEE, - save_employee, /* commit */ - load_all_employees, /* initial_load */ - create_employee_tables, /* create_tables */ - NULL, NULL, NULL, - write_employees /* write */ - }; - + static GncSqlEmployeeBackend be_data { + GNC_SQL_BACKEND_VERSION, GNC_ID_EMPLOYEE, TABLE_NAME, col_table}; gnc_sql_register_backend(&be_data); } /* ========================== END OF FILE ===================== */ diff --git a/src/backend/sql/gnc-entry-sql.cpp b/src/backend/sql/gnc-entry-sql.cpp index 59b6bf891a..75195df86b 100644 --- a/src/backend/sql/gnc-entry-sql.cpp +++ b/src/backend/sql/gnc-entry-sql.cpp @@ -124,6 +124,17 @@ static EntryVec col_table (QofSetterFunc)gncEntrySetOrder), }); +class GncSqlEntryBackend : public GncSqlObjectBackend +{ +public: + GncSqlEntryBackend(int version, const std::string& type, + const std::string& table, const EntryVec& vec) : + GncSqlObjectBackend(version, type, table, vec) {} + void load_all(GncSqlBackend*) override; + void create_tables(GncSqlBackend*) override; + bool write(GncSqlBackend*) override; +}; + static void entry_set_invoice (gpointer pObject, gpointer val) { @@ -178,8 +189,8 @@ load_single_entry (GncSqlBackend* be, GncSqlRow& row) return pEntry; } -static void -load_all_entries (GncSqlBackend* be) +void +GncSqlEntryBackend::load_all (GncSqlBackend* be) { GncSqlStatement* stmt; @@ -207,8 +218,8 @@ load_all_entries (GncSqlBackend* be) } /* ================================================================= */ -static void -create_entry_tables (GncSqlBackend* be) +void +GncSqlEntryBackend::create_tables (GncSqlBackend* be) { gint version; @@ -233,18 +244,6 @@ create_entry_tables (GncSqlBackend* be) } } -/* ================================================================= */ -static gboolean -save_entry (GncSqlBackend* be, QofInstance* inst) -{ - g_return_val_if_fail (inst != NULL, FALSE); - g_return_val_if_fail (GNC_IS_ENTRY (inst), FALSE); - g_return_val_if_fail (be != NULL, FALSE); - - return gnc_sql_commit_standard_item (be, inst, TABLE_NAME, GNC_ID_ENTRY, - col_table); -} - /* ================================================================= */ static void write_single_entry (QofInstance* term_p, gpointer data_p) @@ -261,19 +260,16 @@ write_single_entry (QofInstance* term_p, gpointer data_p) gncEntryGetInvoice (entry) != NULL || gncEntryGetBill (entry) != NULL)) { - s->is_ok = save_entry (s->be, term_p); + s->commit (term_p); } } -static gboolean -write_entries (GncSqlBackend* be) +bool +GncSqlEntryBackend::write (GncSqlBackend* be) { - write_objects_t data; - g_return_val_if_fail (be != NULL, FALSE); + write_objects_t data{be, true, this}; - data.be = be; - data.is_ok = TRUE; qof_object_foreach (GNC_ID_ENTRY, be->book, write_single_entry, &data); return data.is_ok; @@ -283,17 +279,8 @@ write_entries (GncSqlBackend* be) void gnc_entry_sql_initialize (void) { - static GncSqlObjectBackend be_data = - { - GNC_SQL_BACKEND_VERSION, - GNC_ID_ENTRY, - save_entry, /* commit */ - load_all_entries, /* initial_load */ - create_entry_tables, /* create_tables */ - NULL, NULL, NULL, - write_entries /* write */ - }; - + static GncSqlEntryBackend be_data { + GNC_SQL_BACKEND_VERSION, GNC_ID_ENTRY, TABLE_NAME, col_table}; gnc_sql_register_backend(&be_data); } /* ========================== END OF FILE ===================== */ diff --git a/src/backend/sql/gnc-invoice-sql.cpp b/src/backend/sql/gnc-invoice-sql.cpp index fd8450dbce..71eb5938be 100644 --- a/src/backend/sql/gnc-invoice-sql.cpp +++ b/src/backend/sql/gnc-invoice-sql.cpp @@ -96,6 +96,18 @@ static EntryVec col_table (QofSetterFunc)gncInvoiceSetToChargeAmount), }); +class GncSqlInvoiceBackend : public GncSqlObjectBackend +{ +public: + GncSqlInvoiceBackend(int version, const std::string& type, + const std::string& table, const EntryVec& vec) : + GncSqlObjectBackend(version, type, table, vec) {} + void load_all(GncSqlBackend*) override; + void create_tables(GncSqlBackend*) override; + bool commit (GncSqlBackend* be, QofInstance* inst) override; + bool write(GncSqlBackend*) override; +}; + static GncInvoice* load_single_invoice (GncSqlBackend* be, GncSqlRow& row) { @@ -116,8 +128,8 @@ load_single_invoice (GncSqlBackend* be, GncSqlRow& row) return pInvoice; } -static void -load_all_invoices (GncSqlBackend* be) +void +GncSqlInvoiceBackend::load_all (GncSqlBackend* be) { GncSqlStatement* stmt; @@ -145,8 +157,8 @@ load_all_invoices (GncSqlBackend* be) } /* ================================================================= */ -static void -create_invoice_tables (GncSqlBackend* be) +void +GncSqlInvoiceBackend::create_tables (GncSqlBackend* be) { gint version; @@ -172,8 +184,8 @@ create_invoice_tables (GncSqlBackend* be) } /* ================================================================= */ -static gboolean -save_invoice (GncSqlBackend* be, QofInstance* inst) +bool +GncSqlInvoiceBackend::commit (GncSqlBackend* be, QofInstance* inst) { const GncGUID* guid; GncInvoice* invoice; @@ -250,7 +262,7 @@ invoice_should_be_saved (GncInvoice* invoice) static void write_single_invoice (QofInstance* term_p, gpointer data_p) { - write_objects_t* s = (write_objects_t*)data_p; + auto s = reinterpret_cast(data_p); g_return_if_fail (term_p != NULL); g_return_if_fail (GNC_IS_INVOICE (term_p)); @@ -258,19 +270,16 @@ write_single_invoice (QofInstance* term_p, gpointer data_p) if (s->is_ok && invoice_should_be_saved (GNC_INVOICE (term_p))) { - s->is_ok = save_invoice (s->be, term_p); + s->commit (term_p); } } -static gboolean -write_invoices (GncSqlBackend* be) +bool +GncSqlInvoiceBackend::write (GncSqlBackend* be) { - write_objects_t data; - g_return_val_if_fail (be != NULL, FALSE); + write_objects_t data{be, true, this}; - data.be = be; - data.is_ok = TRUE; qof_object_foreach (GNC_ID_INVOICE, be->book, write_single_invoice, &data); return data.is_ok; @@ -309,17 +318,8 @@ GncSqlColumnTableEntryImpl::add_to_query(const GncSqlBackend* be, void gnc_invoice_sql_initialize (void) { - static GncSqlObjectBackend be_data = - { - GNC_SQL_BACKEND_VERSION, - GNC_ID_INVOICE, - save_invoice, /* commit */ - load_all_invoices, /* initial_load */ - create_invoice_tables, /* create_tables */ - NULL, NULL, NULL, - write_invoices /* write */ - }; - + static GncSqlInvoiceBackend be_data { + GNC_SQL_BACKEND_VERSION, GNC_ID_INVOICE, TABLE_NAME, col_table}; gnc_sql_register_backend(&be_data); } /* ========================== END OF FILE ===================== */ diff --git a/src/backend/sql/gnc-job-sql.cpp b/src/backend/sql/gnc-job-sql.cpp index b57a867b7e..e7992e49b1 100644 --- a/src/backend/sql/gnc-job-sql.cpp +++ b/src/backend/sql/gnc-job-sql.cpp @@ -69,6 +69,17 @@ static EntryVec col_table (QofSetterFunc)gncJobSetOwner), }); +class GncSqlJobBackend : public GncSqlObjectBackend +{ +public: + GncSqlJobBackend(int version, const std::string& type, + const std::string& table, const EntryVec& vec) : + GncSqlObjectBackend(version, type, table, vec) {} + void load_all(GncSqlBackend*) override; + bool write(GncSqlBackend*) override; +}; + + static GncJob* load_single_job (GncSqlBackend* be, GncSqlRow& row) { @@ -89,8 +100,8 @@ load_single_job (GncSqlBackend* be, GncSqlRow& row) return pJob; } -static void -load_all_jobs (GncSqlBackend* be) +void +GncSqlJobBackend::load_all (GncSqlBackend* be) { GncSqlStatement* stmt; g_return_if_fail (be != NULL); @@ -116,33 +127,6 @@ load_all_jobs (GncSqlBackend* be) } } -/* ================================================================= */ -static void -create_job_tables (GncSqlBackend* be) -{ - gint version; - - g_return_if_fail (be != NULL); - - version = gnc_sql_get_table_version (be, TABLE_NAME); - if (version == 0) - { - gnc_sql_create_table (be, TABLE_NAME, TABLE_VERSION, col_table); - } -} - -/* ================================================================= */ -static gboolean -save_job (GncSqlBackend* be, QofInstance* inst) -{ - g_return_val_if_fail (inst != NULL, FALSE); - g_return_val_if_fail (GNC_IS_JOB (inst), FALSE); - g_return_val_if_fail (be != NULL, FALSE); - - return gnc_sql_commit_standard_item (be, inst, TABLE_NAME, GNC_ID_JOB, - col_table); -} - /* ================================================================= */ static gboolean job_should_be_saved (GncJob* job) @@ -164,7 +148,7 @@ job_should_be_saved (GncJob* job) static void write_single_job (QofInstance* term_p, gpointer data_p) { - write_objects_t* s = (write_objects_t*)data_p; + auto s = reinterpret_cast(data_p); g_return_if_fail (term_p != NULL); g_return_if_fail (GNC_IS_JOB (term_p)); @@ -172,19 +156,16 @@ write_single_job (QofInstance* term_p, gpointer data_p) if (s->is_ok && job_should_be_saved (GNC_JOB (term_p))) { - s->is_ok = save_job (s->be, term_p); + s->commit (term_p); } } -static gboolean -write_jobs (GncSqlBackend* be) +bool +GncSqlJobBackend::write (GncSqlBackend* be) { - write_objects_t data; - g_return_val_if_fail (be != NULL, FALSE); + write_objects_t data{be, true, this}; - data.be = be; - data.is_ok = TRUE; qof_object_foreach (GNC_ID_JOB, be->book, write_single_job, &data); return data.is_ok; @@ -194,17 +175,8 @@ write_jobs (GncSqlBackend* be) void gnc_job_sql_initialize (void) { - static GncSqlObjectBackend be_data = - { - GNC_SQL_BACKEND_VERSION, - GNC_ID_JOB, - save_job, /* commit */ - load_all_jobs, /* initial_load */ - create_job_tables, /* create_tables */ - NULL, NULL, NULL, - write_jobs /* write */ - }; - + static GncSqlJobBackend be_data { + GNC_SQL_BACKEND_VERSION, GNC_ID_JOB, TABLE_NAME, col_table}; gnc_sql_register_backend(&be_data); } /* ========================== END OF FILE ===================== */ diff --git a/src/backend/sql/gnc-lots-sql.cpp b/src/backend/sql/gnc-lots-sql.cpp index 42dfd9ec6e..5693459bcc 100644 --- a/src/backend/sql/gnc-lots-sql.cpp +++ b/src/backend/sql/gnc-lots-sql.cpp @@ -63,6 +63,17 @@ static const EntryVec col_table gnc_sql_make_table_entry("is_closed", 0, COL_NNUL, "is-closed") }); +class GncSqlLotsBackend : public GncSqlObjectBackend +{ +public: + GncSqlLotsBackend(int version, const std::string& type, + const std::string& table, const EntryVec& vec) : + GncSqlObjectBackend(version, type, table, vec) {} + void load_all(GncSqlBackend*) override; + void create_tables(GncSqlBackend*) override; + bool write(GncSqlBackend*) override; +}; + /* ================================================================= */ static gpointer get_lot_account (gpointer pObject) @@ -111,8 +122,8 @@ load_single_lot (GncSqlBackend* be, GncSqlRow& row) return lot; } -static void -load_all_lots (GncSqlBackend* be) +void +GncSqlLotsBackend::load_all (GncSqlBackend* be) { GncSqlStatement* stmt; g_return_if_fail (be != NULL); @@ -135,8 +146,8 @@ load_all_lots (GncSqlBackend* be) } /* ================================================================= */ -static void -create_lots_tables (GncSqlBackend* be) +void +GncSqlLotsBackend::create_tables (GncSqlBackend* be) { gint version; @@ -163,39 +174,23 @@ create_lots_tables (GncSqlBackend* be) } } -/* ================================================================= */ - -static gboolean -commit_lot (GncSqlBackend* be, QofInstance* inst) -{ - g_return_val_if_fail (be != NULL, FALSE); - g_return_val_if_fail (inst != NULL, FALSE); - g_return_val_if_fail (GNC_IS_LOT (inst), FALSE); - - return gnc_sql_commit_standard_item (be, inst, TABLE_NAME, GNC_ID_LOT, - col_table); -} - static void do_save_lot (QofInstance* inst, gpointer data) { - write_objects_t* s = (write_objects_t*)data; + auto s = reinterpret_cast(data); if (s->is_ok) { - s->is_ok = commit_lot (s->be, inst); + s->commit (inst); } } -static gboolean -write_lots (GncSqlBackend* be) +bool +GncSqlLotsBackend::write (GncSqlBackend* be) { - write_objects_t data; - g_return_val_if_fail (be != NULL, FALSE); + write_objects_t data{be, true, this}; - data.be = be; - data.is_ok = TRUE; qof_collection_foreach (qof_book_get_collection (be->book, GNC_ID_LOT), (QofInstanceForeachCB)do_save_lot, &data); return data.is_ok; @@ -233,17 +228,8 @@ GncSqlColumnTableEntryImpl::add_to_query(const GncSqlBackend* be, void gnc_sql_init_lot_handler (void) { - static GncSqlObjectBackend be_data = - { - GNC_SQL_BACKEND_VERSION, - GNC_ID_LOT, - commit_lot, /* commit */ - load_all_lots, /* initial_load */ - create_lots_tables, /* create tables */ - NULL, NULL, NULL, - write_lots /* save all */ - }; - + static GncSqlLotsBackend be_data { + GNC_SQL_BACKEND_VERSION, GNC_ID_LOT, TABLE_NAME, col_table}; gnc_sql_register_backend(&be_data); } diff --git a/src/backend/sql/gnc-order-sql.cpp b/src/backend/sql/gnc-order-sql.cpp index d931eb7ce1..57f695446c 100644 --- a/src/backend/sql/gnc-order-sql.cpp +++ b/src/backend/sql/gnc-order-sql.cpp @@ -70,6 +70,16 @@ static EntryVec col_table ORDER_OWNER, true), }); +class GncSqlOrderBackend : public GncSqlObjectBackend +{ +public: + GncSqlOrderBackend(int version, const std::string& type, + const std::string& table, const EntryVec& vec) : + GncSqlObjectBackend(version, type, table, vec) {} + void load_all(GncSqlBackend*) override; + bool write(GncSqlBackend*) override; +}; + static GncOrder* load_single_order (GncSqlBackend* be, GncSqlRow& row) { @@ -90,8 +100,8 @@ load_single_order (GncSqlBackend* be, GncSqlRow& row) return pOrder; } -static void -load_all_orders (GncSqlBackend* be) +void +GncSqlOrderBackend::load_all (GncSqlBackend* be) { GncSqlStatement* stmt; g_return_if_fail (be != NULL); @@ -117,33 +127,6 @@ load_all_orders (GncSqlBackend* be) } } -/* ================================================================= */ -static void -create_order_tables (GncSqlBackend* be) -{ - gint version; - - g_return_if_fail (be != NULL); - - version = gnc_sql_get_table_version (be, TABLE_NAME); - if (version == 0) - { - gnc_sql_create_table (be, TABLE_NAME, TABLE_VERSION, col_table); - } -} - -/* ================================================================= */ -static gboolean -save_order (GncSqlBackend* be, QofInstance* inst) -{ - g_return_val_if_fail (inst != NULL, FALSE); - g_return_val_if_fail (GNC_IS_ORDER (inst), FALSE); - g_return_val_if_fail (be != NULL, FALSE); - - return gnc_sql_commit_standard_item (be, inst, TABLE_NAME, GNC_ID_ORDER, - col_table); -} - /* ================================================================= */ static gboolean order_should_be_saved (GncOrder* order) @@ -165,7 +148,7 @@ order_should_be_saved (GncOrder* order) static void write_single_order (QofInstance* term_p, gpointer data_p) { - write_objects_t* s = (write_objects_t*)data_p; + auto s = reinterpret_cast(data_p); g_return_if_fail (term_p != NULL); g_return_if_fail (GNC_IS_ORDER (term_p)); @@ -173,19 +156,16 @@ write_single_order (QofInstance* term_p, gpointer data_p) if (s->is_ok && order_should_be_saved (GNC_ORDER (term_p))) { - s->is_ok = save_order (s->be, term_p); + s->commit (term_p); } } -static gboolean -write_orders (GncSqlBackend* be) +bool +GncSqlOrderBackend::write (GncSqlBackend* be) { - write_objects_t data; - g_return_val_if_fail (be != NULL, FALSE); + write_objects_t data{be, true, this}; - data.be = be; - data.is_ok = TRUE; qof_object_foreach (GNC_ID_ORDER, be->book, write_single_order, &data); return data.is_ok; @@ -223,16 +203,8 @@ GncSqlColumnTableEntryImpl::add_to_query(const GncSqlBackend* be, void gnc_order_sql_initialize (void) { - static GncSqlObjectBackend be_data = - { - GNC_SQL_BACKEND_VERSION, - GNC_ID_ORDER, - save_order, /* commit */ - load_all_orders, /* initial_load */ - create_order_tables, /* create_tables */ - NULL, NULL, NULL, - write_orders /* write */ - }; + static GncSqlOrderBackend be_data { + GNC_SQL_BACKEND_VERSION, GNC_ID_ORDER, TABLE_NAME, col_table}; gnc_sql_register_backend(&be_data); } diff --git a/src/backend/sql/gnc-price-sql.cpp b/src/backend/sql/gnc-price-sql.cpp index bea1c510da..f3c2f4e80e 100644 --- a/src/backend/sql/gnc-price-sql.cpp +++ b/src/backend/sql/gnc-price-sql.cpp @@ -67,6 +67,19 @@ static const EntryVec col_table gnc_sql_make_table_entry("value", 0, COL_NNUL, "value") }); +class GncSqlPriceBackend : public GncSqlObjectBackend +{ +public: + GncSqlPriceBackend(int version, const std::string& type, + const std::string& table, const EntryVec& vec) : + GncSqlObjectBackend(version, type, table, vec) {} + void load_all(GncSqlBackend*) override; + void create_tables(GncSqlBackend*) override; + bool commit (GncSqlBackend* be, QofInstance* inst) override; + bool write(GncSqlBackend*) override; +}; + + /* ================================================================= */ static GNCPrice* @@ -85,8 +98,8 @@ load_single_price (GncSqlBackend* be, GncSqlRow& row) return pPrice; } -static void -load_all_prices (GncSqlBackend* be) +void +GncSqlPriceBackend::load_all (GncSqlBackend* be) { GncSqlStatement* stmt; QofBook* pBook; @@ -103,7 +116,7 @@ load_all_prices (GncSqlBackend* be) delete stmt; if (result->begin() == result->end()) return; - + GNCPrice* pPrice; gchar* sql; @@ -127,8 +140,8 @@ load_all_prices (GncSqlBackend* be) } /* ================================================================= */ -static void -create_prices_tables (GncSqlBackend* be) +void +GncSqlPriceBackend::create_tables (GncSqlBackend* be) { gint version; @@ -151,8 +164,8 @@ create_prices_tables (GncSqlBackend* be) /* ================================================================= */ -static gboolean -save_price (GncSqlBackend* be, QofInstance* inst) +bool +GncSqlPriceBackend::commit (GncSqlBackend* be, QofInstance* inst) { GNCPrice* pPrice = GNC_PRICE (inst); E_DB_OPERATION op; @@ -193,34 +206,29 @@ save_price (GncSqlBackend* be, QofInstance* inst) return is_ok; } -static gboolean +gboolean write_price (GNCPrice* p, gpointer data) { - write_objects_t* s = (write_objects_t*)data; + auto s = reinterpret_cast(data); g_return_val_if_fail (p != NULL, FALSE); g_return_val_if_fail (data != NULL, FALSE); if (s->is_ok && gnc_price_get_source (p) != PRICE_SOURCE_TEMP) { - s->is_ok = save_price (s->be, QOF_INSTANCE (p)); + s->commit (QOF_INSTANCE(p)); } return s->is_ok; } -static gboolean -write_prices (GncSqlBackend* be) +bool +GncSqlPriceBackend::write (GncSqlBackend* be) { - GNCPriceDB* priceDB; - write_objects_t data; - g_return_val_if_fail (be != NULL, FALSE); + write_objects_t data{be, true, this}; - priceDB = gnc_pricedb_get_db (be->book); - - data.be = be; - data.is_ok = TRUE; + auto priceDB = gnc_pricedb_get_db (be->book); return gnc_pricedb_foreach_price (priceDB, write_price, &data, TRUE); } @@ -228,17 +236,8 @@ write_prices (GncSqlBackend* be) void gnc_sql_init_price_handler (void) { - static GncSqlObjectBackend be_data = - { - GNC_SQL_BACKEND_VERSION, - GNC_ID_PRICE, - save_price, /* commit */ - load_all_prices, /* initial_load */ - create_prices_tables, /* create tables */ - NULL, NULL, NULL, - write_prices /* write */ - }; - + static GncSqlPriceBackend be_data { + GNC_SQL_BACKEND_VERSION, GNC_ID_PRICE, TABLE_NAME, col_table}; gnc_sql_register_backend(&be_data); } diff --git a/src/backend/sql/gnc-recurrence-sql.cpp b/src/backend/sql/gnc-recurrence-sql.cpp index c56f560a27..44a1675f54 100644 --- a/src/backend/sql/gnc-recurrence-sql.cpp +++ b/src/backend/sql/gnc-recurrence-sql.cpp @@ -109,6 +109,21 @@ static const EntryVec weekend_adjust_col_table "recurrence_weekend_adjust", BUDGET_MAX_RECURRENCE_WEEKEND_ADJUST_LEN, 0) }); +/** + * Recurrences are neither loadable nor committable. Note that the default + * write() implementation is also a no-op. + */ +class GncSqlRecurrenceBackend : public GncSqlObjectBackend +{ +public: + GncSqlRecurrenceBackend(int version, const std::string& type, + const std::string& table, const EntryVec& vec) : + GncSqlObjectBackend(version, type, table, vec) {} + void load_all(GncSqlBackend*) override { return; } + void create_tables(GncSqlBackend*) override; + bool commit(GncSqlBackend*, QofInstance*) override { return false; } +}; + /* ================================================================= */ static gpointer @@ -389,8 +404,8 @@ upgrade_recurrence_table_1_2 (GncSqlBackend* be) } -static void -create_recurrence_tables (GncSqlBackend* be) +void +GncSqlRecurrenceBackend::create_tables (GncSqlBackend* be) { gint version; gboolean ok; @@ -421,19 +436,8 @@ create_recurrence_tables (GncSqlBackend* be) void gnc_sql_init_recurrence_handler (void) { - static GncSqlObjectBackend be_data = - { - GNC_SQL_BACKEND_VERSION, - GNC_ID_ACCOUNT, - NULL, /* commit - cannot occur */ - NULL, /* initial_load - cannot occur */ - create_recurrence_tables, /* create_tables */ - NULL, /* compile_query */ - NULL, /* run_query */ - NULL, /* free_query */ - NULL /* write */ - }; - + static GncSqlRecurrenceBackend be_data { + GNC_SQL_BACKEND_VERSION, GNC_ID_ACCOUNT, TABLE_NAME, col_table}; gnc_sql_register_backend(&be_data); } /* ========================== END OF FILE ===================== */ diff --git a/src/backend/sql/gnc-schedxaction-sql.cpp b/src/backend/sql/gnc-schedxaction-sql.cpp index 0f2fe6f4be..857507ad4d 100644 --- a/src/backend/sql/gnc-schedxaction-sql.cpp +++ b/src/backend/sql/gnc-schedxaction-sql.cpp @@ -81,6 +81,16 @@ static const EntryVec col_table "template_act_guid", 0, COL_NNUL, "template-account"), }); +class GncSqlSchedXactionBackend : public GncSqlObjectBackend +{ +public: + GncSqlSchedXactionBackend(int version, const std::string& type, + const std::string& table, const EntryVec& vec) : + GncSqlObjectBackend(version, type, table, vec) {} + void load_all(GncSqlBackend*) override; + bool commit (GncSqlBackend* be, QofInstance* inst) override; +}; + /* ================================================================= */ static SchedXaction* load_single_sx (GncSqlBackend* be, GncSqlRow& row) @@ -108,8 +118,8 @@ load_single_sx (GncSqlBackend* be, GncSqlRow& row) return pSx; } -static void -load_all_sxes (GncSqlBackend* be) +void +GncSqlSchedXactionBackend::load_all (GncSqlBackend* be) { GncSqlStatement* stmt = NULL; @@ -142,24 +152,10 @@ load_all_sxes (GncSqlBackend* be) } } -/* ================================================================= */ -static void -create_sx_tables (GncSqlBackend* be) -{ - gint version; - - g_return_if_fail (be != NULL); - - version = gnc_sql_get_table_version (be, SCHEDXACTION_TABLE); - if (version == 0) - { - (void)gnc_sql_create_table (be, SCHEDXACTION_TABLE, TABLE_VERSION, col_table); - } -} /* ================================================================= */ -gboolean -gnc_sql_save_schedxaction (GncSqlBackend* be, QofInstance* inst) +bool +GncSqlSchedXactionBackend::commit (GncSqlBackend* be, QofInstance* inst) { SchedXaction* pSx; const GncGUID* guid; @@ -218,19 +214,9 @@ gnc_sql_save_schedxaction (GncSqlBackend* be, QofInstance* inst) void gnc_sql_init_schedxaction_handler (void) { - static GncSqlObjectBackend be_data = - { - GNC_SQL_BACKEND_VERSION, - GNC_ID_SCHEDXACTION, - gnc_sql_save_schedxaction, /* commit */ - load_all_sxes, /* initial_load */ - create_sx_tables, /* create_tables */ - NULL, /* compile_query */ - NULL, /* run_query */ - NULL, /* free_query */ - NULL /* write */ - }; - + static GncSqlSchedXactionBackend be_data { + GNC_SQL_BACKEND_VERSION, GNC_ID_SCHEDXACTION, SCHEDXACTION_TABLE, + col_table}; gnc_sql_register_backend(&be_data); } /* ========================== END OF FILE ===================== */ diff --git a/src/backend/sql/gnc-slots-sql.cpp b/src/backend/sql/gnc-slots-sql.cpp index e6b159ec11..2a682a9fc2 100644 --- a/src/backend/sql/gnc-slots-sql.cpp +++ b/src/backend/sql/gnc-slots-sql.cpp @@ -160,6 +160,21 @@ static const EntryVec gdate_col_table gnc_sql_make_table_entry("gdate_val", 0, 0), }; +/** + * Slots are neither loadable nor committable. Note that the default + * write() implementation is also a no-op. + */ +class GncSqlSlotsBackend : public GncSqlObjectBackend +{ +public: + GncSqlSlotsBackend(int version, const std::string& type, + const std::string& table, const EntryVec& vec) : + GncSqlObjectBackend(version, type, table, vec) {} + void load_all(GncSqlBackend*) override { return; } + void create_tables(GncSqlBackend*) override; + bool commit(GncSqlBackend*, QofInstance*) override { return false; } +}; + /* ================================================================= */ static gchar* @@ -994,8 +1009,8 @@ void gnc_sql_slots_load_for_sql_subquery (GncSqlBackend* be, } /* ================================================================= */ -static void -create_slots_tables (GncSqlBackend* be) +void +GncSqlSlotsBackend::create_tables (GncSqlBackend* be) { gint version; gboolean ok; @@ -1048,23 +1063,8 @@ create_slots_tables (GncSqlBackend* be) void gnc_sql_init_slots_handler (void) { - static GncSqlObjectBackend be_data = - { - GNC_SQL_BACKEND_VERSION, -// This was GNC_ID_ACCOUNT. If somethine blows up, change it back, -// make the registry store a std::tuple, and check the first string against types -// in the functions that are called on each backend. - GNC_ID_ACCOUNT, - NULL, /* commit - cannot occur */ - NULL, /* initial_load - cannot occur */ - create_slots_tables, /* create_tables */ - NULL, /* compile_query */ - NULL, /* run_query */ - NULL, /* free_query */ - NULL /* write */ - }; - + static GncSqlSlotsBackend be_data { + GNC_SQL_BACKEND_VERSION, GNC_ID_ACCOUNT, TABLE_NAME, col_table}; gnc_sql_register_backend(std::make_tuple(std::string{TABLE_NAME}, &be_data)); } diff --git a/src/backend/sql/gnc-tax-table-sql.cpp b/src/backend/sql/gnc-tax-table-sql.cpp index 577eef06a3..f336ef2e4c 100644 --- a/src/backend/sql/gnc-tax-table-sql.cpp +++ b/src/backend/sql/gnc-tax-table-sql.cpp @@ -113,6 +113,18 @@ static EntryVec guid_col_table get_obj_guid, set_obj_guid), }); +class GncSqlTaxTableBackend : public GncSqlObjectBackend +{ +public: + GncSqlTaxTableBackend(int version, const std::string& type, + const std::string& table, const EntryVec& vec) : + GncSqlObjectBackend(version, type, table, vec) {} + void load_all(GncSqlBackend*) override; + void create_tables(GncSqlBackend*) override; + bool commit (GncSqlBackend* be, QofInstance* inst) override; + bool write(GncSqlBackend*) override; +}; + typedef struct { GncTaxTable* tt; @@ -278,8 +290,8 @@ load_single_taxtable (GncSqlBackend* be, GncSqlRow& row, qof_instance_mark_clean (QOF_INSTANCE (tt)); } -static void -load_all_taxtables (GncSqlBackend* be) +void +GncSqlTaxTableBackend::load_all (GncSqlBackend* be) { GncSqlStatement* stmt; @@ -319,8 +331,8 @@ load_all_taxtables (GncSqlBackend* be) } /* ================================================================= */ -static void -create_taxtable_tables (GncSqlBackend* be) +void +GncSqlTaxTableBackend::create_tables (GncSqlBackend* be) { gint version; @@ -396,8 +408,8 @@ save_tt_entries (GncSqlBackend* be, const GncGUID* guid, GList* entries) return is_ok; } -static gboolean -save_taxtable (GncSqlBackend* be, QofInstance* inst) +bool +GncSqlTaxTableBackend::commit (GncSqlBackend* be, QofInstance* inst) { GncTaxTable* tt; const GncGUID* guid; @@ -456,23 +468,20 @@ save_taxtable (GncSqlBackend* be, QofInstance* inst) static void save_next_taxtable (QofInstance* inst, gpointer data) { - write_objects_t* s = (write_objects_t*)data; + auto s = reinterpret_cast(data); if (s->is_ok) { - s->is_ok = save_taxtable (s->be, inst); + s->commit (inst); } } -static gboolean -write_taxtables (GncSqlBackend* be) +bool +GncSqlTaxTableBackend::write (GncSqlBackend* be) { - write_objects_t data; - g_return_val_if_fail (be != NULL, FALSE); + write_objects_t data{be, true, this}; - data.be = be; - data.is_ok = TRUE; qof_object_foreach (GNC_ID_TAXTABLE, be->book, save_next_taxtable, &data); return data.is_ok; @@ -511,17 +520,8 @@ GncSqlColumnTableEntryImpl::add_to_query(const GncSqlBackend* be void gnc_taxtable_sql_initialize (void) { - static GncSqlObjectBackend be_data = - { - GNC_SQL_BACKEND_VERSION, - GNC_ID_TAXTABLE, - save_taxtable, /* commit */ - load_all_taxtables, /* initial_load */ - create_taxtable_tables, /* create_tables */ - NULL, NULL, NULL, - write_taxtables /* write */ - }; - + static GncSqlTaxTableBackend be_data { + GNC_SQL_BACKEND_VERSION, GNC_ID_TAXTABLE, TT_TABLE_NAME, tt_col_table}; gnc_sql_register_backend(&be_data); } /* ========================== END OF FILE ===================== */ diff --git a/src/backend/sql/gnc-transaction-sql.cpp b/src/backend/sql/gnc-transaction-sql.cpp index 5baedef493..d64a797423 100644 --- a/src/backend/sql/gnc-transaction-sql.cpp +++ b/src/backend/sql/gnc-transaction-sql.cpp @@ -66,12 +66,14 @@ static QofLogModule log_module = G_LOG_DOMAIN; #define SPLIT_TABLE "splits" #define SPLIT_TABLE_VERSION 4 -typedef struct +struct split_info_t : public write_objects_t { - GncSqlBackend* be; + split_info_t () = default; + split_info_t (GncSqlBackend* be, bool o, + GncSqlObjectBackendPtr e, const GncGUID* g): + write_objects_t(be, o, e), guid{g} {} const GncGUID* guid; - gboolean is_ok; -} split_info_t; +}; #define TX_MAX_NUM_LEN 2048 #define TX_MAX_DESCRIPTION_LEN 2048 @@ -133,6 +135,36 @@ static const EntryVec tx_guid_col_table gnc_sql_make_table_entry("tx_guid", 0, 0, "guid"), }; +class GncSqlTransBackend : public GncSqlObjectBackend +{ +public: + GncSqlTransBackend(int version, const std::string& type, + const std::string& table, const EntryVec& vec) : + GncSqlObjectBackend(version, type, table, vec) {} + void load_all(GncSqlBackend*) override; + void create_tables(GncSqlBackend*) override; + bool commit (GncSqlBackend* be, QofInstance* inst) override; +}; + +class GncSqlSplitBackend : public GncSqlObjectBackend +{ +public: + GncSqlSplitBackend(int version, const std::string& type, + const std::string& table, const EntryVec& vec) : + GncSqlObjectBackend(version, type, table, vec) {} + void load_all(GncSqlBackend*) override { return; } // loaded by transaction. + void create_tables(GncSqlBackend*) override; + bool commit (GncSqlBackend* be, QofInstance* inst) override; +}; +static GncSqlSplitBackend be_data_split { + GNC_SQL_BACKEND_VERSION, GNC_ID_SPLIT, SPLIT_TABLE, split_col_table}; +/* These functions exist but have not been tested. + #if LOAD_TRANSACTIONS_AS_NEEDED + compile_split_query, + run_split_query, + free_split_query, +*/ + /* ================================================================= */ static gpointer @@ -447,15 +479,15 @@ query_transactions (GncSqlBackend* be, GncSqlStatement* stmt) * * @param be SQL backend */ -static void -create_transaction_tables (GncSqlBackend* be) +void +GncSqlTransBackend::create_tables (GncSqlBackend* be) { gint version; gboolean ok; g_return_if_fail (be != NULL); - version = gnc_sql_get_table_version (be, TRANSACTION_TABLE); + version = gnc_sql_get_table_version (be, m_table_name.c_str()); if (version == 0) { (void)gnc_sql_create_table (be, TRANSACTION_TABLE, TX_TABLE_VERSION, @@ -467,35 +499,35 @@ create_transaction_tables (GncSqlBackend* be) PERR ("Unable to create index\n"); } } - else if (version < TX_TABLE_VERSION) + else if (version < m_version) { /* Upgrade: 1->2: 64 bit int handling 2->3: allow dates to be NULL */ - gnc_sql_upgrade_table (be, TRANSACTION_TABLE, tx_col_table); - (void)gnc_sql_set_table_version (be, TRANSACTION_TABLE, TX_TABLE_VERSION); - PINFO ("Transactions table upgraded from version %d to version %d\n", version, - TX_TABLE_VERSION); + gnc_sql_upgrade_table (be, m_table_name.c_str(), tx_col_table); + (void)gnc_sql_set_table_version (be, m_table_name.c_str(), m_version); + PINFO ("Transactions table upgraded from version %d to version %d\n", + version, m_version); } +} +void +GncSqlSplitBackend::create_tables (GncSqlBackend* be) +{ + g_return_if_fail (be != nullptr); - version = gnc_sql_get_table_version (be, SPLIT_TABLE); + auto version = gnc_sql_get_table_version (be, m_table_name.c_str()); if (version == 0) { - (void)gnc_sql_create_table (be, SPLIT_TABLE, SPLIT_TABLE_VERSION, - split_col_table); - ok = gnc_sql_create_index (be, "splits_tx_guid_index", SPLIT_TABLE, - tx_guid_col_table); - if (!ok) - { + (void)gnc_sql_create_table (be, m_table_name.c_str(), + m_version, m_col_table); + if (!gnc_sql_create_index (be, "splits_tx_guid_index", + m_table_name.c_str(), tx_guid_col_table)) PERR ("Unable to create index\n"); - } - ok = gnc_sql_create_index (be, "splits_account_guid_index", SPLIT_TABLE, - account_guid_col_table); - if (!ok) - { + if (!gnc_sql_create_index (be, "splits_account_guid_index", + m_table_name.c_str(), + account_guid_col_table)) PERR ("Unable to create index\n"); - } } else if (version < SPLIT_TABLE_VERSION) { @@ -503,22 +535,18 @@ create_transaction_tables (GncSqlBackend* be) /* Upgrade: 1->2: 64 bit int handling 3->4: Split reconcile date can be NULL */ - gnc_sql_upgrade_table (be, SPLIT_TABLE, split_col_table); - ok = gnc_sql_create_index (be, "splits_tx_guid_index", SPLIT_TABLE, - tx_guid_col_table); - if (!ok) - { + gnc_sql_upgrade_table (be, m_table_name.c_str(), split_col_table); + if (!gnc_sql_create_index (be, "splits_tx_guid_index", + m_table_name.c_str(), + tx_guid_col_table)) PERR ("Unable to create index\n"); - } - ok = gnc_sql_create_index (be, "splits_account_guid_index", SPLIT_TABLE, - account_guid_col_table); - if (!ok) - { + if (!gnc_sql_create_index (be, "splits_account_guid_index", + m_table_name.c_str(), + account_guid_col_table)) PERR ("Unable to create index\n"); - } - (void)gnc_sql_set_table_version (be, SPLIT_TABLE, SPLIT_TABLE_VERSION); + (void)gnc_sql_set_table_version (be, m_table_name.c_str(), m_version); PINFO ("Splits table upgraded from version %d to version %d\n", version, - SPLIT_TABLE_VERSION); + m_version); } } /* ================================================================= */ @@ -581,8 +609,8 @@ delete_splits (GncSqlBackend* be, Transaction* pTx) * @param inst Split * @return TRUE if successful, FALSE if error */ -static gboolean -commit_split (GncSqlBackend* be, QofInstance* inst) +bool +GncSqlSplitBackend::commit (GncSqlBackend* be, QofInstance* inst) { E_DB_OPERATION op; gboolean is_infant; @@ -623,54 +651,19 @@ commit_split (GncSqlBackend* be, QofInstance* inst) return is_ok; } -static void -save_split_cb (gpointer data, gpointer user_data) + +bool +GncSqlTransBackend::commit (GncSqlBackend* be, QofInstance* inst) { - split_info_t* split_info = (split_info_t*)user_data; - Split* pSplit = GNC_SPLIT (data); - - g_return_if_fail (data != NULL); - g_return_if_fail (GNC_IS_SPLIT (data)); - g_return_if_fail (user_data != NULL); - - if (split_info->is_ok) - { - split_info->is_ok = commit_split (split_info->be, QOF_INSTANCE (pSplit)); - } -} - -static gboolean -save_splits (GncSqlBackend* be, const GncGUID* tx_guid, SplitList* pSplitList) -{ - split_info_t split_info; - - g_return_val_if_fail (be != NULL, FALSE); - g_return_val_if_fail (tx_guid != NULL, FALSE); - g_return_val_if_fail (pSplitList != NULL, FALSE); - - split_info.be = be; - split_info.guid = tx_guid; - split_info.is_ok = TRUE; - g_list_foreach (pSplitList, save_split_cb, &split_info); - - return split_info.is_ok; -} - -static gboolean -save_transaction (GncSqlBackend* be, Transaction* pTx, gboolean do_save_splits) -{ - const GncGUID* guid; E_DB_OPERATION op; - gboolean is_infant; - QofInstance* inst; gboolean is_ok = TRUE; const char* err = NULL; g_return_val_if_fail (be != NULL, FALSE); - g_return_val_if_fail (pTx != NULL, FALSE); + g_return_val_if_fail (inst != NULL, FALSE); - inst = QOF_INSTANCE (pTx); - is_infant = qof_instance_get_infant (inst); + auto pTx = GNC_TRANS(inst); + auto is_infant = qof_instance_get_infant (inst); if (qof_instance_get_destroying (inst)) { op = OP_DB_DELETE; @@ -708,8 +701,8 @@ save_transaction (GncSqlBackend* be, Transaction* pTx, gboolean do_save_splits) if (is_ok) { - // Commit slots and splits - guid = qof_instance_get_guid (inst); + // Commit slots + auto guid = qof_instance_get_guid (inst); if (!qof_instance_get_destroying (inst)) { is_ok = gnc_sql_slots_save (be, guid, is_infant, inst); @@ -717,14 +710,6 @@ save_transaction (GncSqlBackend* be, Transaction* pTx, gboolean do_save_splits) { err = "Slots save failed. Check trace log for SQL errors"; } - if (is_ok && do_save_splits) - { - is_ok = save_splits (be, guid, xaccTransGetSplitList (pTx)); - if (! is_ok) - { - err = "Split save failed. Check trace log for SQL errors"; - } - } } else { @@ -767,26 +752,6 @@ save_transaction (GncSqlBackend* be, Transaction* pTx, gboolean do_save_splits) return is_ok; } -gboolean -gnc_sql_save_transaction (GncSqlBackend* be, QofInstance* inst) -{ - g_return_val_if_fail (be != NULL, FALSE); - g_return_val_if_fail (inst != NULL, FALSE); - g_return_val_if_fail (GNC_IS_TRANS (inst), FALSE); - - return save_transaction (be, GNC_TRANS (inst), /* do_save_splits */TRUE); -} - -static gboolean -commit_transaction (GncSqlBackend* be, QofInstance* inst) -{ - g_return_val_if_fail (be != NULL, FALSE); - g_return_val_if_fail (inst != NULL, FALSE); - g_return_val_if_fail (GNC_IS_TRANS (inst), FALSE); - - return save_transaction (be, GNC_TRANS (inst), /* do_save_splits */FALSE); -} - /* ================================================================= */ /** * Loads all transactions for an account. @@ -825,7 +790,8 @@ void gnc_sql_transaction_load_tx_for_account (GncSqlBackend* be, * * @param be SQL backend */ -void gnc_sql_transaction_load_all_tx (GncSqlBackend* be) +void +GncSqlTransBackend::load_all (GncSqlBackend* be) { gchar* query_sql; GncSqlStatement* stmt; @@ -1471,41 +1437,8 @@ GncSqlColumnTableEntryImpl::add_to_query(const GncSqlBackend* be, void gnc_sql_init_transaction_handler (void) { - static GncSqlObjectBackend be_data_tx = - { - GNC_SQL_BACKEND_VERSION, - GNC_ID_TRANS, - commit_transaction, /* commit */ -#if LOAD_TRANSACTIONS_AS_NEEDED - NULL, /* initial load */ -#else - gnc_sql_transaction_load_all_tx, -#endif - create_transaction_tables, /* create tables */ - NULL, /* compile_query */ - NULL, /* run_query */ - NULL, /* free_query */ - NULL /* write */ - }; - static GncSqlObjectBackend be_data_split = - { - GNC_SQL_BACKEND_VERSION, - GNC_ID_SPLIT, - commit_split, /* commit */ - NULL, /* initial_load */ - NULL, /* create tables */ -#if LOAD_TRANSACTIONS_AS_NEEDED - compile_split_query, - run_split_query, - free_split_query, -#else - NULL, /* compile_query */ - NULL, /* run_query */ - NULL, /* free_query */ -#endif - NULL /* write */ - }; - + static GncSqlTransBackend be_data_tx { + GNC_SQL_BACKEND_VERSION, GNC_ID_TRANS, TRANSACTION_TABLE, tx_col_table}; gnc_sql_register_backend(&be_data_tx); gnc_sql_register_backend(&be_data_split); } diff --git a/src/backend/sql/gnc-transaction-sql.h b/src/backend/sql/gnc-transaction-sql.h index eae7e63dc7..9bec050faf 100644 --- a/src/backend/sql/gnc-transaction-sql.h +++ b/src/backend/sql/gnc-transaction-sql.h @@ -38,23 +38,6 @@ extern "C" } void gnc_sql_init_transaction_handler (void); -/** - * Commits all of the splits for a transaction. - * - * @param be SQL backend - * @param pTx Transaction - */ -void gnc_sql_transaction_commit_splits (GncSqlBackend* be, Transaction* pTx); - -/** - * Saves a transaction to the db. - * - * @param be SQL backend - * @param inst Transaction instance - * @return TRUE if successful, FALSE if unsuccessful - */ -gboolean gnc_sql_save_transaction (GncSqlBackend* be, QofInstance* inst); - /** * Loads all transactions which have splits for a specific account. * @@ -63,14 +46,6 @@ gboolean gnc_sql_save_transaction (GncSqlBackend* be, QofInstance* inst); */ void gnc_sql_transaction_load_tx_for_account (GncSqlBackend* be, Account* account); - -/** - * Loads all transactions. - * - * @param be SQL backend - */ -void gnc_sql_transaction_load_all_tx (GncSqlBackend* be); - typedef struct { Account* acct; diff --git a/src/backend/sql/gnc-vendor-sql.cpp b/src/backend/sql/gnc-vendor-sql.cpp index 0caf56a3c9..e2fe4252f1 100644 --- a/src/backend/sql/gnc-vendor-sql.cpp +++ b/src/backend/sql/gnc-vendor-sql.cpp @@ -79,6 +79,17 @@ static EntryVec col_table gnc_sql_make_table_entry("tax_table", 0, 0, "tax-table"), }); +class GncSqlVendorBackend : public GncSqlObjectBackend +{ +public: + GncSqlVendorBackend(int version, const std::string& type, + const std::string& table, const EntryVec& vec) : + GncSqlObjectBackend(version, type, table, vec) {} + void load_all(GncSqlBackend*) override; + bool commit(GncSqlBackend*, QofInstance*) override; + bool write(GncSqlBackend*) override; +}; + static GncVendor* load_single_vendor (GncSqlBackend* be, GncSqlRow& row) { @@ -99,8 +110,8 @@ load_single_vendor (GncSqlBackend* be, GncSqlRow& row) return pVendor; } -static void -load_all_vendors (GncSqlBackend* be) +void +GncSqlVendorBackend::load_all (GncSqlBackend* be) { GncSqlStatement* stmt; @@ -126,23 +137,8 @@ load_all_vendors (GncSqlBackend* be) } /* ================================================================= */ -static void -create_vendor_tables (GncSqlBackend* be) -{ - gint version; - - g_return_if_fail (be != NULL); - - version = gnc_sql_get_table_version (be, TABLE_NAME); - if (version == 0) - { - gnc_sql_create_table (be, TABLE_NAME, TABLE_VERSION, col_table); - } -} - -/* ================================================================= */ -static gboolean -save_vendor (GncSqlBackend* be, QofInstance* inst) +bool +GncSqlVendorBackend::commit (GncSqlBackend* be, QofInstance* inst) { GncVendor* v; const GncGUID* guid; @@ -218,27 +214,24 @@ vendor_should_be_saved (GncVendor* vendor) static void write_single_vendor (QofInstance* term_p, gpointer data_p) { - write_objects_t* s = (write_objects_t*)data_p; + auto s = reinterpret_cast(data_p); g_return_if_fail (term_p != NULL); g_return_if_fail (GNC_IS_VENDOR (term_p)); g_return_if_fail (data_p != NULL); - if (s->is_ok && vendor_should_be_saved (GNC_VENDOR (term_p))) + if (vendor_should_be_saved (GNC_VENDOR (term_p))) { - s->is_ok = save_vendor (s->be, term_p); + s->commit (term_p); } } -static gboolean -write_vendors (GncSqlBackend* be) +bool +GncSqlVendorBackend::write (GncSqlBackend* be) { - write_objects_t data; - g_return_val_if_fail (be != NULL, FALSE); + write_objects_t data{be, true, this}; - data.be = be; - data.is_ok = TRUE; qof_object_foreach (GNC_ID_VENDOR, be->book, write_single_vendor, &data); return data.is_ok; @@ -248,16 +241,8 @@ write_vendors (GncSqlBackend* be) void gnc_vendor_sql_initialize (void) { - static GncSqlObjectBackend be_data = - { - GNC_SQL_BACKEND_VERSION, - GNC_ID_VENDOR, - save_vendor, /* commit */ - load_all_vendors, /* initial_load */ - create_vendor_tables, /* create_tables */ - NULL, NULL, NULL, - write_vendors /* write */ - }; + static GncSqlVendorBackend be_data { + GNC_SQL_BACKEND_VERSION, GNC_ID_VENDOR, TABLE_NAME, col_table}; gnc_sql_register_backend(&be_data); }