/* ================================================================= */ static gboolean save_employee (GncSqlBackend* be, QofInstance* inst) { GncEmployee* emp; const GncGUID* guid; E_DB_OPERATION op; gboolean is_infant; gboolean is_ok = TRUE; g_return_val_if_fail (inst != NULL, FALSE); g_return_val_if_fail (GNC_IS_EMPLOYEE (inst), FALSE); g_return_val_if_fail (be != NULL, FALSE); emp = GNC_EMPLOYEE (inst); is_infant = qof_instance_get_infant (inst); if (qof_instance_get_destroying (inst)) { op = OP_DB_DELETE; } else if (be->is_pristine_db || is_infant) { op = OP_DB_INSERT; } else { op = OP_DB_UPDATE; } if (op != OP_DB_DELETE) { // Ensure the commodity is in the db is_ok = gnc_sql_save_commodity (be, gncEmployeeGetCurrency (emp)); } if (is_ok) { is_ok = gnc_sql_do_db_operation (be, op, TABLE_NAME, GNC_ID_EMPLOYEE, emp, col_table); } if (is_ok) { // Now, commit or delete any slots guid = qof_instance_get_guid (inst); if (!qof_instance_get_destroying (inst)) { is_ok = gnc_sql_slots_save (be, guid, is_infant, inst); } else { is_ok = gnc_sql_slots_delete (be, guid); } } return is_ok; }
/* ================================================================= */ bool GncSqlInvoiceBackend::commit (GncSqlBackend* be, QofInstance* inst) { const GncGUID* guid; GncInvoice* invoice; E_DB_OPERATION op; gboolean is_infant; gboolean is_ok = TRUE; g_return_val_if_fail (inst != NULL, FALSE); g_return_val_if_fail (GNC_IS_INVOICE (inst), FALSE); g_return_val_if_fail (be != NULL, FALSE); invoice = GNC_INVOICE (inst); is_infant = qof_instance_get_infant (inst); if (qof_instance_get_destroying (inst)) { op = OP_DB_DELETE; } else if (be->pristine() || is_infant) { op = OP_DB_INSERT; } else { op = OP_DB_UPDATE; } if (op != OP_DB_DELETE) { // Ensure the commodity is in the db is_ok = gnc_sql_save_commodity (be, gncInvoiceGetCurrency (invoice)); } if (is_ok) { is_ok = gnc_sql_do_db_operation (be, op, TABLE_NAME, GNC_ID_INVOICE, inst, col_table); } if (is_ok) { // Now, commit or delete any slots guid = qof_instance_get_guid (inst); if (!qof_instance_get_destroying (inst)) { is_ok = gnc_sql_slots_save (be, guid, is_infant, inst); } else { is_ok = gnc_sql_slots_delete (be, guid); } } return is_ok; }
/* ================================================================= */ bool GncSqlSchedXactionBackend::commit (GncSqlBackend* sql_be, QofInstance* inst) { SchedXaction* pSx; const GncGUID* guid; E_DB_OPERATION op; gboolean is_infant; gboolean is_ok; g_return_val_if_fail (sql_be != NULL, FALSE); g_return_val_if_fail (inst != NULL, FALSE); g_return_val_if_fail (GNC_IS_SX (inst), FALSE); pSx = GNC_SX (inst); is_infant = qof_instance_get_infant (inst); if (qof_instance_get_destroying (inst)) { op = OP_DB_DELETE; } else if (sql_be->pristine() || is_infant) { op = OP_DB_INSERT; } else { op = OP_DB_UPDATE; } is_ok = sql_be->do_db_operation(op, SCHEDXACTION_TABLE, GNC_SX_ID, pSx, col_table); guid = qof_instance_get_guid (inst); if (op == OP_DB_INSERT || op == OP_DB_UPDATE) { gnc_sql_recurrence_save_list (sql_be, guid, gnc_sx_get_schedule (pSx)); } else { gnc_sql_recurrence_delete (sql_be, guid); } if (is_ok) { // Now, commit any slots if (op == OP_DB_INSERT || op == OP_DB_UPDATE) { is_ok = gnc_sql_slots_save (sql_be, guid, is_infant, inst); } else { is_ok = gnc_sql_slots_delete (sql_be, guid); } } return is_ok; }
/* ================================================================= */ bool GncSqlVendorBackend::commit (GncSqlBackend* sql_be, QofInstance* inst) { GncVendor* v; const GncGUID* guid; E_DB_OPERATION op; gboolean is_infant; gboolean is_ok = TRUE; g_return_val_if_fail (inst != NULL, FALSE); g_return_val_if_fail (GNC_IS_VENDOR (inst), FALSE); g_return_val_if_fail (sql_be != NULL, FALSE); v = GNC_VENDOR (inst); is_infant = qof_instance_get_infant (inst); if (qof_instance_get_destroying (inst)) { op = OP_DB_DELETE; } else if (sql_be->pristine() || is_infant) { op = OP_DB_INSERT; } else { op = OP_DB_UPDATE; } if (op != OP_DB_DELETE) { // Ensure the commodity is in the db is_ok = sql_be->save_commodity (gncVendorGetCurrency(v)); } if (is_ok) { is_ok = sql_be->do_db_operation(op, TABLE_NAME, GNC_ID_VENDOR, v, col_table); } if (is_ok) { // Now, commit or delete any slots guid = qof_instance_get_guid (inst); if (!qof_instance_get_destroying (inst)) { is_ok = gnc_sql_slots_save (sql_be, guid, is_infant, inst); } else { is_ok = gnc_sql_slots_delete (sql_be, guid); } } return is_ok; }
bool GncSqlTaxTableBackend::commit (GncSqlBackend* sql_be, QofInstance* inst) { GncTaxTable* tt; const GncGUID* guid; E_DB_OPERATION op; gboolean is_infant; gboolean is_ok; g_return_val_if_fail (inst != NULL, FALSE); g_return_val_if_fail (GNC_IS_TAXTABLE (inst), FALSE); g_return_val_if_fail (sql_be != NULL, FALSE); tt = GNC_TAXTABLE (inst); is_infant = qof_instance_get_infant (inst); if (qof_instance_get_destroying (inst)) { op = OP_DB_DELETE; } else if (sql_be->pristine() || is_infant) { op = OP_DB_INSERT; } else { op = OP_DB_UPDATE; } is_ok = sql_be->do_db_operation(op, TT_TABLE_NAME, GNC_ID_TAXTABLE, tt, tt_col_table); if (is_ok) { // Now, commit or delete any slots and tax table entries guid = qof_instance_get_guid (inst); if (!qof_instance_get_destroying (inst)) { is_ok = gnc_sql_slots_save (sql_be, guid, is_infant, inst); if (is_ok) { is_ok = save_tt_entries (sql_be, guid, gncTaxTableGetEntries (tt)); } } else { is_ok = gnc_sql_slots_delete (sql_be, guid); if (is_ok) { is_ok = delete_all_tt_entries (sql_be, guid); } } } return is_ok; }
/** * Commits a split to the database * * @param be SQL backend * @param inst Split * @return TRUE if successful, FALSE if error */ static gboolean commit_split( GncSqlBackend* be, QofInstance* inst ) { gint op; gboolean is_infant; gboolean is_ok; GncGUID *guid = (GncGUID*)qof_instance_get_guid(inst); g_return_val_if_fail( inst != NULL, FALSE ); g_return_val_if_fail( be != NULL, FALSE ); is_infant = qof_instance_get_infant( inst ); if ( qof_instance_get_destroying( inst ) ) { op = OP_DB_DELETE; } else if ( be->is_pristine_db || is_infant ) { op = OP_DB_INSERT; } else { op = OP_DB_UPDATE; } if (guid_equal (guid, guid_null ())) { *guid = guid_new_return (); qof_instance_set_guid (inst, guid); } is_ok = gnc_sql_do_db_operation( be, op, SPLIT_TABLE, GNC_ID_SPLIT, inst, split_col_table ); if ( is_ok && !qof_instance_get_destroying (inst)) { is_ok = gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) ); } return is_ok; }
static gboolean save_price (GncSqlBackend* be, QofInstance* inst) { GNCPrice* pPrice = GNC_PRICE (inst); E_DB_OPERATION op; gboolean is_infant; gboolean is_ok = TRUE; g_return_val_if_fail (be != NULL, FALSE); g_return_val_if_fail (inst != NULL, FALSE); g_return_val_if_fail (GNC_IS_PRICE (inst), FALSE); is_infant = qof_instance_get_infant (inst); if (qof_instance_get_destroying (inst)) { op = OP_DB_DELETE; } else if (be->is_pristine_db || is_infant) { op = OP_DB_INSERT; } else { op = OP_DB_UPDATE; } if (op != OP_DB_DELETE) { /* Ensure commodity and currency are in the db */ (void)gnc_sql_save_commodity (be, gnc_price_get_commodity (pPrice)); is_ok = gnc_sql_save_commodity (be, gnc_price_get_currency (pPrice)); } if (is_ok) { is_ok = gnc_sql_do_db_operation (be, op, TABLE_NAME, GNC_ID_PRICE, pPrice, col_table); } return is_ok; }
/* ================================================================= */ static gboolean do_commit_commodity( GncSqlBackend* be, QofInstance* inst, gboolean force_insert ) { const GncGUID* guid; gboolean is_infant; gint op; gboolean is_ok; is_infant = qof_instance_get_infant( inst ); if ( qof_instance_get_destroying( inst ) ) { op = OP_DB_DELETE; } else if ( be->is_pristine_db || is_infant || force_insert ) { op = OP_DB_INSERT; } else { op = OP_DB_UPDATE; } is_ok = gnc_sql_do_db_operation( be, op, COMMODITIES_TABLE, GNC_ID_COMMODITY, inst, col_table ); if ( is_ok ) { // Now, commit any slots guid = qof_instance_get_guid( inst ); if ( !qof_instance_get_destroying(inst) ) { is_ok = gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) ); } else { is_ok = gnc_sql_slots_delete( be, guid ); } } return is_ok; }
static gboolean save_transaction( GncSqlBackend* be, Transaction* pTx, gboolean do_save_splits ) { const GncGUID* guid; gint op; gboolean is_infant; QofInstance* inst; gboolean is_ok = TRUE; gchar* err = NULL; g_return_val_if_fail( be != NULL, FALSE ); g_return_val_if_fail( pTx != NULL, FALSE ); inst = QOF_INSTANCE(pTx); is_infant = qof_instance_get_infant( inst ); if ( qof_instance_get_destroying( inst ) ) { op = OP_DB_DELETE; } else if ( be->is_pristine_db || is_infant ) { op = OP_DB_INSERT; } else { op = OP_DB_UPDATE; } if ( op != OP_DB_DELETE ) { gnc_commodity *commodity = xaccTransGetCurrency( pTx ); // Ensure the commodity is in the db is_ok = gnc_sql_save_commodity( be, commodity ); if ( ! is_ok ) { err = "Commodity save failed: Probably an invalid or missing currency"; qof_backend_set_error( &be->be, ERR_BACKEND_DATA_CORRUPT); } } if ( is_ok ) { is_ok = gnc_sql_do_db_operation( be, op, TRANSACTION_TABLE, GNC_ID_TRANS, pTx, tx_col_table ); if ( ! is_ok ) { err = "Transaction header save failed. Check trace log for SQL errors"; } } if ( is_ok ) { // Commit slots and splits guid = qof_instance_get_guid( inst ); if ( !qof_instance_get_destroying(inst) ) { is_ok = gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) ); if ( ! is_ok ) { 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 { is_ok = gnc_sql_slots_delete( be, guid ); if ( ! is_ok ) { err = "Slots delete failed. Check trace log for SQL errors"; } if ( is_ok ) { is_ok = delete_splits( be, pTx ); if ( ! is_ok ) { err = "Split delete failed. Check trace log for SQL errors"; } } } } if (! is_ok ) { G_GNUC_UNUSED gchar *message1 = "Transaction %s dated %s in account %s not saved due to %s.%s"; G_GNUC_UNUSED gchar *message2 = "\nDatabase may be corrupted, check your data carefully."; Split* split = xaccTransGetSplit( pTx, 0); Account *acc = xaccSplitGetAccount( split ); /* FIXME: This needs to be implemented qof_error_format_secondary_text( GTK_MESSAGE_DIALOG( msg ), message1, xaccTransGetDescription( pTx ), qof_print_date( xaccTransGetDate( pTx ) ), xaccAccountGetName( acc ), err, message2 ); */ PERR( "Transaction %s dated %s in account %s not saved due to %s.\n", xaccTransGetDescription( pTx ), qof_print_date( xaccTransGetDate( pTx ) ), xaccAccountGetName( acc ), err ); } return is_ok; }
/* ================================================================= */ bool GncSqlAccountBackend::commit (GncSqlBackend* sql_be, QofInstance* inst) { Account* pAcc = GNC_ACCOUNT (inst); const GncGUID* guid; gboolean is_infant; gboolean is_ok = FALSE; gnc_commodity* commodity; E_DB_OPERATION op; g_return_val_if_fail (sql_be != NULL, FALSE); g_return_val_if_fail (inst != NULL, FALSE); g_return_val_if_fail (GNC_IS_ACCOUNT (inst), FALSE); ENTER ("inst=%p", inst); is_infant = qof_instance_get_infant (inst); // If there is no commodity yet, this might be because a new account name // has been entered directly into the register and an account window will // be opened. The account info is not complete yet, but the name has been // set, triggering this commit commodity = xaccAccountGetCommodity (pAcc); is_ok = TRUE; if (qof_instance_get_destroying (inst)) { op = OP_DB_DELETE; } else if (sql_be->pristine() || is_infant) { op = OP_DB_INSERT; } else { op = OP_DB_UPDATE; } // If not deleting the account, ensure the commodity is in the db if (op != OP_DB_DELETE && commodity != NULL) { is_ok = sql_be->save_commodity(commodity); } if (is_ok) { is_ok = sql_be->do_db_operation (op, TABLE_NAME, GNC_ID_ACCOUNT, pAcc, col_table); } if (is_ok) { // Now, commit or delete any slots guid = qof_instance_get_guid (inst); if (!qof_instance_get_destroying (inst)) { is_ok = gnc_sql_slots_save (sql_be, guid, is_infant, inst); } else { is_ok = gnc_sql_slots_delete (sql_be, guid); } } LEAVE ("is_ok=%d", is_ok); return is_ok; }
/* Commit_edit handler - find the correct backend handler for this object * type and call its commit handler */ void GncSqlBackend::commit_edit (QofInstance* inst) { sql_backend be_data; gboolean is_dirty; gboolean is_destroying; gboolean is_infant; g_return_if_fail (inst != NULL); if (qof_book_is_readonly(m_book)) { qof_backend_set_error (&qof_be, ERR_BACKEND_READONLY); (void)m_conn->rollback_transaction (); return; } /* During initial load where objects are being created, don't commit anything, but do mark the object as clean. */ if (m_loading) { qof_instance_mark_clean (inst); return; } // The engine has a PriceDB object but it isn't in the database if (strcmp (inst->e_type, "PriceDB") == 0) { qof_instance_mark_clean (inst); qof_book_mark_session_saved (m_book); return; } ENTER (" "); is_dirty = qof_instance_get_dirty_flag (inst); is_destroying = qof_instance_get_destroying (inst); is_infant = qof_instance_get_infant (inst); DEBUG ("%s dirty = %d, do_free = %d, infant = %d\n", (inst->e_type ? inst->e_type : "(null)"), is_dirty, is_destroying, is_infant); if (!is_dirty && !is_destroying) { LEAVE ("!dirty OR !destroying"); return; } if (!m_conn->begin_transaction ()) { PERR ("begin_transaction failed\n"); LEAVE ("Rolled back - database transaction begin error"); return; } bool is_ok = true; auto obe = m_backend_registry.get_object_backend(std::string{inst->e_type}); if (obe != nullptr) is_ok = obe->commit(this, inst); else { PERR ("Unknown object type '%s'\n", inst->e_type); (void)m_conn->rollback_transaction (); // Don't let unknown items still mark the book as being dirty qof_book_mark_session_saved(m_book); qof_instance_mark_clean (inst); LEAVE ("Rolled back - unknown object type"); return; } if (!is_ok) { // Error - roll it back (void)m_conn->rollback_transaction(); // This *should* leave things marked dirty LEAVE ("Rolled back - database error"); return; } (void)m_conn->commit_transaction (); qof_book_mark_session_saved(m_book); qof_instance_mark_clean (inst); LEAVE (""); }
/* ================================================================= */ bool GncSqlBudgetBackend::commit (GncSqlBackend* sql_be, QofInstance* inst) { GncBudget* pBudget = GNC_BUDGET (inst); const GncGUID* guid; E_DB_OPERATION op; gboolean is_infant; gboolean is_ok; g_return_val_if_fail (sql_be != NULL, FALSE); g_return_val_if_fail (inst != NULL, FALSE); g_return_val_if_fail (GNC_IS_BUDGET (inst), FALSE); is_infant = qof_instance_get_infant (inst); if (qof_instance_get_destroying (inst)) { op = OP_DB_DELETE; } else if (sql_be->pristine() || is_infant) { op = OP_DB_INSERT; } else { op = OP_DB_UPDATE; } is_ok = sql_be->do_db_operation(op, BUDGET_TABLE, GNC_ID_BUDGET, pBudget, col_table); // Now, commit any slots and recurrence if (is_ok) { guid = qof_instance_get_guid (inst); if (!qof_instance_get_destroying (inst)) { is_ok = save_budget_amounts (sql_be, pBudget); if (is_ok) { is_ok = gnc_sql_recurrence_save (sql_be, guid, gnc_budget_get_recurrence (pBudget)); } if (is_ok) { is_ok = gnc_sql_slots_save (sql_be, guid, is_infant, inst); } } else { is_ok = delete_budget_amounts (sql_be, pBudget); if (is_ok) { is_ok = gnc_sql_recurrence_delete (sql_be, guid); } if (is_ok) { (void)gnc_sql_slots_delete (sql_be, guid); } } } return is_ok; }