/* ================================================================= */ 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; }
gboolean gnc_sql_slots_delete( GncSqlBackend* be, const GncGUID* guid ) { gchar* buf; GncSqlResult* result; gchar guid_buf[GUID_ENCODING_LENGTH + 1]; GncSqlStatement* stmt; slot_info_t slot_info = { NULL, NULL, TRUE, NULL, 0, NULL, FRAME, NULL, g_string_new('\0') }; g_return_val_if_fail( be != NULL, FALSE ); g_return_val_if_fail( guid != NULL, FALSE ); (void)guid_to_string_buff( guid, guid_buf ); buf = g_strdup_printf( "SELECT * FROM %s WHERE obj_guid='%s' and slot_type in ('%d', '%d') and not guid_val is null", TABLE_NAME, guid_buf, KVP_TYPE_FRAME, KVP_TYPE_GLIST ); stmt = gnc_sql_create_statement_from_sql( be, buf ); g_free( buf ); if ( stmt != NULL ) { result = gnc_sql_execute_select_statement( be, stmt ); gnc_sql_statement_dispose( stmt ); if ( result != NULL ) { GncSqlRow* row = gnc_sql_result_get_first_row( result ); while ( row != NULL ) { GncSqlColumnTableEntry table_row = col_table[guid_val_col]; GncGUID child_guid; const GValue* val = gnc_sql_row_get_value_at_col_name( row, table_row.col_name); if ( val == NULL ) continue; (void)string_to_guid( g_value_get_string( val ), &child_guid ); gnc_sql_slots_delete( be, &child_guid ); row = gnc_sql_result_get_next_row( result ); } gnc_sql_result_dispose( result ); } } slot_info.be = be; slot_info.guid = guid; slot_info.is_ok = TRUE; slot_info.is_ok = gnc_sql_do_db_operation( be, OP_DB_DELETE, TABLE_NAME, TABLE_NAME, &slot_info, obj_guid_col_table ); return slot_info.is_ok; }
/** * Callback function to delete slots for a split * * @param data Split * @param user_data split_info_t structure contain operation info */ static void delete_split_slots_cb( gpointer data, gpointer user_data ) { 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 = gnc_sql_slots_delete( split_info->be, qof_instance_get_guid( QOF_INSTANCE(pSplit) ) ); } }
gboolean gnc_sql_slots_delete (GncSqlBackend* sql_be, const GncGUID* guid) { gchar* buf; gchar guid_buf[GUID_ENCODING_LENGTH + 1]; slot_info_t slot_info = { NULL, NULL, TRUE, NULL, KvpValue::Type::INVALID, NULL, FRAME, NULL, "" }; g_return_val_if_fail (sql_be != NULL, FALSE); g_return_val_if_fail (guid != NULL, FALSE); (void)guid_to_string_buff (guid, guid_buf); buf = g_strdup_printf ("SELECT * FROM %s WHERE obj_guid='%s' and slot_type in ('%d', '%d') and not guid_val is null", TABLE_NAME, guid_buf, KvpValue::Type::FRAME, KvpValue::Type::GLIST); auto stmt = sql_be->create_statement_from_sql(buf); g_free (buf); if (stmt != nullptr) { auto result = sql_be->execute_select_statement(stmt); for (auto row : *result) { try { const GncSqlColumnTableEntryPtr table_row = col_table[guid_val_col]; GncGUID child_guid; auto val = row.get_string_at_col (table_row->name()); (void)string_to_guid (val.c_str(), &child_guid); gnc_sql_slots_delete (sql_be, &child_guid); } catch (std::invalid_argument) { continue; } } } slot_info.be = sql_be; slot_info.guid = guid; slot_info.is_ok = TRUE; slot_info.is_ok = sql_be->do_db_operation(OP_DB_DELETE, TABLE_NAME, TABLE_NAME, &slot_info, obj_guid_col_table); return slot_info.is_ok; }
gboolean gnc_sql_slots_save( GncSqlBackend* be, const GncGUID* guid, gboolean is_infant, KvpFrame* pFrame ) { slot_info_t slot_info = { NULL, NULL, TRUE, NULL, 0, NULL, FRAME, NULL, g_string_new('\0') }; g_return_val_if_fail( be != NULL, FALSE ); g_return_val_if_fail( guid != NULL, FALSE ); g_return_val_if_fail( pFrame != NULL, FALSE ); // If this is not saving into a new db, clear out the old saved slots first if ( !be->is_pristine_db && !is_infant ) { (void)gnc_sql_slots_delete( be, guid ); } slot_info.be = be; slot_info.guid = guid; kvp_frame_for_each_slot( pFrame, save_slot, &slot_info ); (void)g_string_free( slot_info.path, TRUE ); return slot_info.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; }
gboolean gnc_sql_slots_save( GncSqlBackend* be, const GncGUID* guid, gboolean is_infant, QofInstance *inst) { slot_info_t slot_info = { NULL, NULL, TRUE, NULL, KvpValue::Type::INVALID, NULL, FRAME, NULL, g_string_new(NULL) }; KvpFrame *pFrame = qof_instance_get_slots (inst); g_return_val_if_fail( be != NULL, FALSE ); g_return_val_if_fail( guid != NULL, FALSE ); g_return_val_if_fail( pFrame != NULL, FALSE ); // If this is not saving into a new db, clear out the old saved slots first if ( !be->is_pristine_db && !is_infant ) { (void)gnc_sql_slots_delete( be, guid ); } slot_info.be = be; slot_info.guid = guid; pFrame->for_each_slot(save_slot, &slot_info); (void)g_string_free( slot_info.path, TRUE ); return slot_info.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; }
/* ================================================================= */ 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; }