Example #1
0
/* ----------------------------------------------------------------- */
static void
load_tx_guid( const GncSqlBackend* be, GncSqlRow* row,
              /*@ null @*/ QofSetterFunc setter, gpointer pObject,
              const GncSqlColumnTableEntry* table_row )
{
    const GValue* val;
    GncGUID guid;
    Transaction* tx;
    const gchar* guid_str;

    g_return_if_fail( be != NULL );
    g_return_if_fail( row != NULL );
    g_return_if_fail( pObject != NULL );
    g_return_if_fail( table_row != NULL );

    val = gnc_sql_row_get_value_at_col_name( row, table_row->col_name );
    g_assert( val != NULL );
    guid_str = g_value_get_string(val);
    if ( guid_str != NULL )
    {
        (void)string_to_guid( guid_str, &guid );
        tx = xaccTransLookup( &guid, be->book );

        // If the transaction is not found, try loading it
        if ( tx == NULL )
        {
            gchar* buf;
            GncSqlStatement* stmt;

            buf = g_strdup_printf( "SELECT * FROM %s WHERE guid='%s'",
                                   TRANSACTION_TABLE, guid_str );
            stmt = gnc_sql_create_statement_from_sql( (GncSqlBackend*)be, buf );
            g_free( buf );
            query_transactions( (GncSqlBackend*)be, stmt );
            tx = xaccTransLookup( &guid, be->book );
        }

        if ( tx != NULL )
        {
            if ( table_row->gobj_param_name != NULL )
            {
		qof_instance_increase_editlevel (pObject);
                g_object_set( pObject, table_row->gobj_param_name, tx, NULL );
		qof_instance_decrease_editlevel (pObject);
            }
            else
            {
                g_return_if_fail( setter != NULL );
                (*setter)( pObject, (const gpointer)tx );
            }
        }
    }
}
Example #2
0
/* ================================================================= */
static void
load_account_guid (const GncSqlBackend* be, GncSqlRow* row,
                   QofSetterFunc setter, gpointer pObject,
                   const GncSqlColumnTableEntry* table_row)
{
    const GValue* val;
    GncGUID guid;
    Account* account = NULL;

    g_return_if_fail (be != NULL);
    g_return_if_fail (row != NULL);
    g_return_if_fail (pObject != NULL);
    g_return_if_fail (table_row != NULL);

    val = gnc_sql_row_get_value_at_col_name (row, table_row->col_name);
    if (val != NULL && G_VALUE_HOLDS_STRING (val) &&
        g_value_get_string (val) != NULL)
    {
        (void)string_to_guid (g_value_get_string (val), &guid);
        account = xaccAccountLookup (&guid, be->book);
        if (account != NULL)
        {
            if (table_row->gobj_param_name != NULL)
            {
                qof_instance_increase_editlevel (pObject);
                g_object_set (pObject, table_row->gobj_param_name, account, NULL);
                qof_instance_decrease_editlevel (pObject);
            }
            else
            {
                g_return_if_fail (setter != NULL);
                (*setter) (pObject, (const gpointer)account);
            }
        }
        else
        {
            PWARN ("Account ref '%s' not found", g_value_get_string (val));
        }
    }
}
Example #3
0
/* ================================================================= */
static void
load_billterm_guid (const GncSqlBackend* be, GncSqlRow* row,
                    QofSetterFunc setter, gpointer pObject,
                    const GncSqlColumnTableEntry* table_row)
{
    const GValue* val;
    GncGUID guid;
    GncBillTerm* term = NULL;

    g_return_if_fail (be != NULL);
    g_return_if_fail (row != NULL);
    g_return_if_fail (pObject != NULL);
    g_return_if_fail (table_row != NULL);

    val = gnc_sql_row_get_value_at_col_name (row, table_row->col_name);
    if (val != NULL && G_VALUE_HOLDS_STRING (val) &&
        g_value_get_string (val) != NULL)
    {
        string_to_guid (g_value_get_string (val), &guid);
        term = gncBillTermLookup (be->book, &guid);
        if (term != NULL)
        {
            if (table_row->gobj_param_name != NULL)
            {
                qof_instance_increase_editlevel (pObject);
                g_object_set (pObject, table_row->gobj_param_name, term, NULL);
                qof_instance_decrease_editlevel (pObject);
            }
            else
            {
                (*setter) (pObject, (const gpointer)term);
            }
        }
        else
        {
            PWARN ("Billterm ref '%s' not found", g_value_get_string (val));
        }
    }
}
Example #4
0
static void
load_commodity_guid( const GncSqlBackend* be, GncSqlRow* row,
                     /*@ null @*/ QofSetterFunc setter, gpointer pObject,
                     const GncSqlColumnTableEntry* table_row )
{
    const GValue* val;
    GncGUID guid;
    gnc_commodity* commodity = NULL;

    g_return_if_fail( be != NULL );
    g_return_if_fail( row != NULL );
    g_return_if_fail( pObject != NULL );
    g_return_if_fail( table_row != NULL );

    val = gnc_sql_row_get_value_at_col_name( row, table_row->col_name );
    if ( val != NULL && G_VALUE_HOLDS_STRING( val ) && g_value_get_string( val ) != NULL )
    {
        (void)string_to_guid( g_value_get_string( val ), &guid );
        commodity = gnc_commodity_find_commodity_by_guid( &guid, be->book );
        if ( commodity != NULL )
        {
            if ( table_row->gobj_param_name != NULL )
            {
		qof_instance_increase_editlevel (pObject);
                g_object_set( pObject, table_row->gobj_param_name, commodity, NULL );
		qof_instance_decrease_editlevel (pObject);
            }
            else if ( setter != NULL )
            {
                (*setter)( pObject, (const gpointer)commodity );
            }
        }
        else
        {
            PWARN( "Commodity ref '%s' not found", g_value_get_string( val ) );
        }
    }
}
Example #5
0
void
GncSqlAccountBackend::load_all (GncSqlBackend* sql_be)
{
    QofBook* pBook;
    ParentGuidVec l_accounts_needing_parents;
    g_return_if_fail (sql_be != NULL);

    ENTER ("");

    pBook = sql_be->book();

    std::stringstream sql;
    sql << "SELECT * FROM " << TABLE_NAME;
    auto stmt = sql_be->create_statement_from_sql(sql.str());
    auto result = sql_be->execute_select_statement(stmt);
    for (auto row : *result)
        load_single_account (sql_be, row, l_accounts_needing_parents);

    sql.str("");
    sql << "SELECT DISTINCT guid FROM " << TABLE_NAME;
    gnc_sql_slots_load_for_sql_subquery (sql_be, sql.str().c_str(),
                                         (BookLookupFn)xaccAccountLookup);

    /* While there are items on the list of accounts needing parents,
       try to see if the parent has now been loaded.  Theory says that if
       items are removed from the front and added to the back if the
       parent is still not available, then eventually, the list will
       shrink to size 0. */
    if (!l_accounts_needing_parents.empty())
    {
        auto progress_made = true;
        std::reverse(l_accounts_needing_parents.begin(),
                     l_accounts_needing_parents.end());
	auto end = l_accounts_needing_parents.end();
        while (progress_made)
        {
            progress_made = false;
            end = std::remove_if(l_accounts_needing_parents.begin(), end,
				 [&](ParentGuidPtr s)
				 {
				     auto pParent = xaccAccountLookup (&s->guid,
								       sql_be->book());
				     if (pParent != nullptr)
				     {
					 gnc_account_append_child (pParent,
								   s->pAccount);
					 progress_made = true;
					 delete s;
					 return true;
				     }
				     return false;
				 });
        }

        /* Any non-ROOT accounts left over must be parented by the root account */
        auto root = gnc_book_get_root_account (pBook);
        end = std::remove_if(l_accounts_needing_parents.begin(), end,
			     [&](ParentGuidPtr s)
			     {
				 if (xaccAccountGetType (s->pAccount) != ACCT_TYPE_ROOT)
				     gnc_account_append_child (root, s->pAccount);
				 delete s;
				 return true;
			     });
    }

#if LOAD_TRANSACTIONS_AS_NEEDED
    /* Load starting balances */
    auto bal_slist = gnc_sql_get_account_balances_slist (sql_be);
    for (auto bal = bal_slist; bal != NULL; bal = bal->next)
    {
        acct_balances_t* balances = (acct_balances_t*)bal->data;

        qof_instance_increase_editlevel (balances->acct);
        g_object_set (balances->acct,
                      "start-balance", &balances->balance,
                      "start-cleared-balance", &balances->cleared_balance,
                      "start-reconciled-balance", &balances->reconciled_balance,
                      NULL);

        qof_instance_decrease_editlevel (balances->acct);
    }
    if (bal_slist != NULL)
    {
        g_slist_free (bal_slist);
    }
#endif
    LEAVE ("");
}
Example #6
0
static void
load_all_accounts (GncSqlBackend* be)
{
    GncSqlStatement* stmt = NULL;
    GncSqlResult* result;
    QofBook* pBook;
    GList* l_accounts_needing_parents = NULL;
    GSList* bal_slist;
    GSList* bal;

    g_return_if_fail (be != NULL);

    ENTER ("");

    pBook = be->book;

    stmt = gnc_sql_create_select_statement (be, TABLE_NAME);
    if (stmt == NULL)
    {
        LEAVE ("stmt == NULL");
        return;
    }
    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);
        gchar* sql;

        while (row != NULL)
        {
            load_single_account (be, row, &l_accounts_needing_parents);
            row = gnc_sql_result_get_next_row (result);
        }
        gnc_sql_result_dispose (result);

        sql = g_strdup_printf ("SELECT DISTINCT guid FROM %s", TABLE_NAME);
        gnc_sql_slots_load_for_sql_subquery (be, sql, (BookLookupFn)xaccAccountLookup);
        g_free (sql);

        /* While there are items on the list of accounts needing parents,
           try to see if the parent has now been loaded.  Theory says that if
           items are removed from the front and added to the back if the
           parent is still not available, then eventually, the list will
           shrink to size 0. */
        if (l_accounts_needing_parents != NULL)
        {
            gboolean progress_made = TRUE;
            Account* root;
            Account* pParent;
            GList* elem;

            while (progress_made)
            {
                progress_made = FALSE;
                for (elem = l_accounts_needing_parents; elem != NULL;)
                {
                    account_parent_guid_struct* s = (account_parent_guid_struct*)elem->data;
                    pParent = xaccAccountLookup (&s->guid, be->book);
                    if (pParent != NULL)
                    {
                        GList* next_elem;

                        gnc_account_append_child (pParent, s->pAccount);
                        next_elem = g_list_next (elem);
                        l_accounts_needing_parents = g_list_delete_link (l_accounts_needing_parents,
                                                                         elem);
                        g_free (s);
                        elem = next_elem;
                        progress_made = TRUE;
                    }
                    else
                    {
                        /* Can't be up in the for loop because the 'then' clause reads inside a node freed
                           by g_list_delete_link(). */
                        elem = g_list_next (elem);
                    }
                }
            }

            /* Any non-ROOT accounts left over must be parented by the root account */
            root = gnc_book_get_root_account (pBook);
            while (l_accounts_needing_parents != NULL)
            {
                account_parent_guid_struct* s = (account_parent_guid_struct*)
                                                l_accounts_needing_parents->data;
                if (xaccAccountGetType (s->pAccount) != ACCT_TYPE_ROOT)
                {
                    gnc_account_append_child (root, s->pAccount);
                }
                g_free (s);
                l_accounts_needing_parents = g_list_delete_link (l_accounts_needing_parents,
                                                                 l_accounts_needing_parents);
            }
        }

        /* Load starting balances */
        bal_slist = gnc_sql_get_account_balances_slist (be);
        for (bal = bal_slist; bal != NULL; bal = bal->next)
        {
            acct_balances_t* balances = (acct_balances_t*)bal->data;

            qof_instance_increase_editlevel (balances->acct);
            g_object_set (balances->acct,
                          "start-balance", &balances->balance,
                          "start-cleared-balance", &balances->cleared_balance,
                          "start-reconciled-balance", &balances->reconciled_balance,
                          NULL);

            qof_instance_decrease_editlevel (balances->acct);
        }
        if (bal_slist != NULL)
        {
            g_slist_free (bal_slist);
        }
    }

    LEAVE ("");
}
Example #7
0
/**
 * Executes a transaction query statement and loads the transactions and all
 * of the splits.
 *
 * @param be SQL backend
 * @param stmt SQL statement
 */
static void
query_transactions( GncSqlBackend* be, GncSqlStatement* stmt )
{
    GncSqlResult* result;

    g_return_if_fail( be != NULL );
    g_return_if_fail( stmt != NULL );

    result = gnc_sql_execute_select_statement( be, stmt );
    if ( result != NULL )
    {
        GList* tx_list = NULL;
        GList* node;
        GncSqlRow* row;
        Transaction* tx;
#if LOAD_TRANSACTIONS_AS_NEEDED
        GSList* bal_list = NULL;
        GSList* nextbal;
        Account* root = gnc_book_get_root_account( be->book );

        qof_event_suspend();
        xaccAccountBeginEdit( root );

        // Save the start/ending balances (balance, cleared and reconciled) for
        // every account.
        gnc_account_foreach_descendant( gnc_book_get_root_account( be->primary_book ),
                                        save_account_balances,
                                        &bal_list );
#endif

        // Load the transactions
        row = gnc_sql_result_get_first_row( result );
        while ( row != NULL )
        {
            tx = load_single_tx( be, row );
            if ( tx != NULL )
            {
                tx_list = g_list_prepend( tx_list, tx );
            }
            row = gnc_sql_result_get_next_row( result );
        }
        gnc_sql_result_dispose( result );

        // Load all splits and slots for the transactions
        if ( tx_list != NULL )
        {
            gnc_sql_slots_load_for_list( be, tx_list );
            load_splits_for_tx_list( be, tx_list );
        }

        // Commit all of the transactions
        for ( node = tx_list; node != NULL; node = node->next )
        {
            Transaction* pTx = GNC_TRANSACTION(node->data);
            xaccTransCommitEdit( pTx );
        }
        g_list_free( tx_list );

#if LOAD_TRANSACTIONS_AS_NEEDED
        // Update the account balances based on the loaded splits.  If the end
        // balance has changed, update the start balance so that the end
        // balance is the same as it was before the splits were loaded.
        // Repeat for cleared and reconciled balances.
        for ( nextbal = bal_list; nextbal != NULL; nextbal = nextbal->next )
        {
            full_acct_balances_t* balns = (full_acct_balances_t*)nextbal->data;
            gnc_numeric* pnew_end_bal;
            gnc_numeric* pnew_end_c_bal;
            gnc_numeric* pnew_end_r_bal;
            gnc_numeric adj;

            g_object_get( balns->acc,
                          "end-balance", &pnew_end_bal,
                          "end-cleared-balance", &pnew_end_c_bal,
                          "end-reconciled-balance", &pnew_end_r_bal,
                          NULL );

	    qof_instance_increase_editlevel (balns-acc);
            if ( !gnc_numeric_eq( *pnew_end_bal, balns->end_bal ) )
            {
                adj = gnc_numeric_sub( balns->end_bal, *pnew_end_bal,
                                       GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD );
                balns->start_bal = gnc_numeric_add( balns->start_bal, adj,
                                                    GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD );
                g_object_set( balns->acc, "start-balance", &balns->start_bal, NULL );
		qof_instance_decrease_editlevel (balns-acc);
            }
            if ( !gnc_numeric_eq( *pnew_end_c_bal, balns->end_cleared_bal ) )
            {
                adj = gnc_numeric_sub( balns->end_cleared_bal, *pnew_end_c_bal,
                                       GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD );
                balns->start_cleared_bal = gnc_numeric_add( balns->start_cleared_bal, adj,
                                           GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD );
                g_object_set( balns->acc, "start-cleared-balance", &balns->start_cleared_bal, NULL );
            }
            if ( !gnc_numeric_eq( *pnew_end_r_bal, balns->end_reconciled_bal ) )
            {
                adj = gnc_numeric_sub( balns->end_reconciled_bal, *pnew_end_r_bal,
                                       GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD );
                balns->start_reconciled_bal = gnc_numeric_add( balns->start_reconciled_bal, adj,
                                              GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD );
                g_object_set( balns->acc, "start-reconciled-balance", &balns->start_reconciled_bal, NULL );
            }
	    qof_instance_decrease_editlevel (balns-acc);
            xaccAccountRecomputeBalance( balns->acc );
            g_free( pnew_end_bal );
            g_free( pnew_end_c_bal );
            g_free( pnew_end_r_bal );
            g_free( balns );
        }
        if ( bal_list != NULL )
        {
            g_slist_free( bal_list );
        }

        xaccAccountCommitEdit( root );
        qof_event_resume();
#endif
    }
}