Beispiel #1
0
static void
load_taxtable_entries( GncSqlBackend* be, GncTaxTable* tt )
{
    GncSqlResult* result;
    gchar guid_buf[GUID_ENCODING_LENGTH+1];
    GValue value;
    gchar* buf;
    GncSqlStatement* stmt;
    GError* error = NULL;

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

    guid_to_string_buff( qof_instance_get_guid( QOF_INSTANCE(tt) ), guid_buf );
    memset( &value, 0, sizeof( GValue ) );
    g_value_init( &value, G_TYPE_STRING );
    g_value_set_string( &value, guid_buf );
    buf = g_strdup_printf( "SELECT * FROM %s WHERE taxtable='%s'", TTENTRIES_TABLE_NAME, guid_buf );
    stmt = gnc_sql_connection_create_statement_from_sql( be->conn, buf );
    g_free( buf );
    result = gnc_sql_execute_select_statement( be, stmt );
    gnc_sql_statement_dispose( stmt );
    if ( result != NULL )
    {
        GncSqlRow* row;

        row = gnc_sql_result_get_first_row( result );
        while ( row != NULL )
        {
            load_single_ttentry( be, row, tt );
            row = gnc_sql_result_get_next_row( result );
        }
        gnc_sql_result_dispose( result );
    }
}
Beispiel #2
0
static void
load_all_employees (GncSqlBackend* be)
{
    GncSqlStatement* stmt;
    GncSqlResult* result;

    g_return_if_fail (be != NULL);

    stmt = gnc_sql_create_select_statement (be, TABLE_NAME);
    result = gnc_sql_execute_select_statement (be, stmt);
    gnc_sql_statement_dispose (stmt);
    if (result != NULL)
    {
        GncSqlRow* row;
        GList* list = NULL;

        row = gnc_sql_result_get_first_row (result);
        while (row != NULL)
        {
            GncEmployee* pEmployee = load_single_employee (be, row);
            if (pEmployee != NULL)
            {
                list = g_list_append (list, pEmployee);
            }
            row = gnc_sql_result_get_next_row (result);
        }
        gnc_sql_result_dispose (result);

        if (list != NULL)
        {
            gnc_sql_slots_load_for_list (be, list);
            g_list_free (list);
        }
    }
}
Beispiel #3
0
static void
load_all_books( GncSqlBackend* be )
{
    GncSqlStatement* stmt;
    GncSqlResult* result;

    g_return_if_fail( be != NULL );

    stmt = gnc_sql_create_select_statement( be, BOOK_TABLE );
    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 );

            // If there are no rows, try committing the book
            if ( row == NULL )
            {
                (void)gnc_sql_save_book( be, QOF_INSTANCE(be->book) );
            }
            else
            {
                // Otherwise, load the 1st book.
                load_single_book( be, row );
            }

            gnc_sql_result_dispose( result );
        }
    }
}
static void
load_all_lots( GncSqlBackend* be )
{
    GncSqlStatement* stmt;
    GncSqlResult* result;

    g_return_if_fail( be != NULL );

    stmt = gnc_sql_create_select_statement( be, TABLE_NAME );
    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 );
            gchar* sql;

            while ( row != NULL )
            {
                load_single_lot( be, row );
                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)gnc_lot_lookup );
            g_free( sql );
        }
    }
}
Beispiel #5
0
void
gnc_sql_slots_load_for_list( GncSqlBackend* be, GList* list )
{
    QofCollection* coll;
    GncSqlStatement* stmt;
    GString* sql;
    GncSqlResult* result;
    gboolean single_item;

    g_return_if_fail( be != NULL );

    // Ignore empty list
    if ( list == NULL ) return;

    coll = qof_instance_get_collection( QOF_INSTANCE(list->data) );

    // Create the query for all slots for all items on the list
    sql = g_string_sized_new( 40 + (GUID_ENCODING_LENGTH + 3) * g_list_length( list ) );
    g_string_append_printf( sql, "SELECT * FROM %s WHERE %s ", TABLE_NAME, obj_guid_col_table[0].col_name );
    if ( g_list_length( list ) != 1 )
    {
        (void)g_string_append( sql, "IN (" );
        single_item = FALSE;
    }
    else
    {
        (void)g_string_append( sql, "= " );
        single_item = TRUE;
    }
    (void)gnc_sql_append_guid_list_to_sql( sql, list, G_MAXUINT );
    if ( !single_item )
    {
        (void)g_string_append( sql, ")" );
    }

    // Execute the query and load the slots
    stmt = gnc_sql_create_statement_from_sql( be, sql->str );
    if ( stmt == NULL )
    {
        PERR( "stmt == NULL, SQL = '%s'\n", sql->str );
        (void)g_string_free( sql, TRUE );
        return;
    }
    (void)g_string_free( sql, TRUE );
    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 )
        {
            load_slot_for_list_item( be, row, coll );
            row = gnc_sql_result_get_next_row( result );
        }
        gnc_sql_result_dispose( result );
    }
}
Beispiel #6
0
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;
}
Beispiel #7
0
static void
load_all_taxtables( GncSqlBackend* be )
{
    GncSqlStatement* stmt;
    GncSqlResult* result;

    g_return_if_fail( be != NULL );

    /* First time, create the query */
    stmt = gnc_sql_create_select_statement( be, TT_TABLE_NAME );
    result = gnc_sql_execute_select_statement( be, stmt );
    gnc_sql_statement_dispose( stmt );
    if ( result != NULL )
    {
        GncSqlRow* row;
        GList* tt_needing_parents = NULL;

        row = gnc_sql_result_get_first_row( result );
        while ( row != NULL )
        {
            load_single_taxtable( be, row, &tt_needing_parents );
            row = gnc_sql_result_get_next_row( result );
        }
        gnc_sql_result_dispose( result );

        /* While there are items on the list of taxtables 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 ( tt_needing_parents != NULL )
        {
            gboolean progress_made = TRUE;
            GncTaxTable* root;
            Account* pParent;
            GList* elem;

            while ( progress_made )
            {
                progress_made = FALSE;
                for ( elem = tt_needing_parents; elem != NULL; elem = g_list_next( elem ) )
                {
                    taxtable_parent_guid_struct* s = (taxtable_parent_guid_struct*)elem->data;
                    tt_set_parent( s->tt, &s->guid );
                    tt_needing_parents = g_list_delete_link( tt_needing_parents, elem );
                    progress_made = TRUE;
                }
            }
        }
    }
}
Beispiel #8
0
static void
load_all_prices (GncSqlBackend* be)
{
    GncSqlStatement* stmt;
    GncSqlResult* result;
    QofBook* pBook;
    GNCPriceDB* pPriceDB;

    g_return_if_fail (be != NULL);

    pBook = be->book;
    pPriceDB = gnc_pricedb_get_db (pBook);
    stmt = gnc_sql_create_select_statement (be, TABLE_NAME);
    if (stmt != NULL)
    {
        result = gnc_sql_execute_select_statement (be, stmt);
        gnc_sql_statement_dispose (stmt);
        if (result != NULL)
        {
            GNCPrice* pPrice;
            GncSqlRow* row = gnc_sql_result_get_first_row (result);
            gchar* sql;

            gnc_pricedb_set_bulk_update (pPriceDB, TRUE);
            while (row != NULL)
            {
                pPrice = load_single_price (be, row);

                if (pPrice != NULL)
                {
                    (void)gnc_pricedb_add_price (pPriceDB, pPrice);
                    gnc_price_unref (pPrice);
                }
                row = gnc_sql_result_get_next_row (result);
            }
            gnc_sql_result_dispose (result);
            gnc_pricedb_set_bulk_update (pPriceDB, FALSE);

            sql = g_strdup_printf ("SELECT DISTINCT guid FROM %s", TABLE_NAME);
            gnc_sql_slots_load_for_sql_subquery (be, sql, (BookLookupFn)gnc_price_lookup);
            g_free (sql);
        }
    }
}
Beispiel #9
0
static /*@ null @*/ GncSqlResult*
gnc_sql_set_recurrences_from_db( GncSqlBackend* be, const GncGUID* guid )
{
    gchar* buf;
    gchar guid_buf[GUID_ENCODING_LENGTH+1];
    GncSqlStatement* stmt;
    GncSqlResult* result;

    g_return_val_if_fail( be != NULL, NULL );
    g_return_val_if_fail( guid != NULL, NULL );

    (void)guid_to_string_buff( guid, guid_buf );
    buf = g_strdup_printf( "SELECT * FROM %s WHERE obj_guid='%s'", TABLE_NAME, guid_buf );
    stmt = gnc_sql_connection_create_statement_from_sql( be->conn, buf );
    g_free( buf );
    result = gnc_sql_execute_select_statement( be, stmt );
    gnc_sql_statement_dispose( stmt );
    return result;
}
static void
load_all_commodities( GncSqlBackend* be )
{
    GncSqlStatement* stmt;
    GncSqlResult* result;
    gnc_commodity_table* pTable;

    pTable = gnc_commodity_table_get_table( be->book );
    stmt = gnc_sql_create_select_statement( be, COMMODITIES_TABLE );
    if ( stmt == NULL ) return;
    result = gnc_sql_execute_select_statement( be, stmt );
    gnc_sql_statement_dispose( stmt );
    if ( result != NULL )
    {
        gnc_commodity* pCommodity;
        GncSqlRow* row = gnc_sql_result_get_first_row( result );
        gchar* sql;

        while ( row != NULL )
        {
            pCommodity = load_single_commodity( be, row );

            if ( pCommodity != NULL )
            {
                GncGUID guid;

                guid = *qof_instance_get_guid( QOF_INSTANCE(pCommodity) );
                pCommodity = gnc_commodity_table_insert( pTable, pCommodity );
                qof_instance_set_guid( QOF_INSTANCE(pCommodity), &guid );
            }
            row = gnc_sql_result_get_next_row( result );
        }
        gnc_sql_result_dispose( result );

        sql = g_strdup_printf( "SELECT DISTINCT guid FROM %s", COMMODITIES_TABLE );
        gnc_sql_slots_load_for_sql_subquery( be, sql,
                                             (BookLookupFn)gnc_commodity_find_commodity_by_guid );
        g_free( sql );
    }
}
Beispiel #11
0
/**
 * gnc_sql_slots_load_for_sql_subquery - Loads slots for all objects whose guid is
 * supplied by a subquery.  The subquery should be of the form "SELECT DISTINCT guid FROM ...".
 * This is faster than loading for one object at a time because fewer SQL queries * are used.
 *
 * @param be SQL backend
 * @param subquery Subquery SQL string
 * @param lookup_fn Lookup function
 */
void gnc_sql_slots_load_for_sql_subquery( GncSqlBackend* be, const gchar* subquery,
        BookLookupFn lookup_fn )
{
    gchar* sql;
    GncSqlStatement* stmt;
    GncSqlResult* result;

    g_return_if_fail( be != NULL );

    // Ignore empty subquery
    if ( subquery == NULL ) return;

    sql = g_strdup_printf( "SELECT * FROM %s WHERE %s IN (%s)",
                           TABLE_NAME, obj_guid_col_table[0].col_name,
                           subquery );

    // Execute the query and load the slots
    stmt = gnc_sql_create_statement_from_sql( be, sql );
    if ( stmt == NULL )
    {
        PERR( "stmt == NULL, SQL = '%s'\n", sql );
        g_free( sql );
        return;
    }
    g_free( sql );
    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 )
        {
            load_slot_for_book_object( be, row, lookup_fn );
            row = gnc_sql_result_get_next_row( result );
        }
        gnc_sql_result_dispose( result );
    }
}
Beispiel #12
0
static void
slots_load_info ( slot_info_t *pInfo )
{
    gchar* buf;
    GncSqlResult* result;
    gchar guid_buf[GUID_ENCODING_LENGTH + 1];
    GncSqlStatement* stmt;

    g_return_if_fail( pInfo != NULL );
    g_return_if_fail( pInfo->be != NULL );
    g_return_if_fail( pInfo->guid != NULL );
    g_return_if_fail( pInfo->pKvpFrame != NULL );

    (void)guid_to_string_buff( pInfo->guid, guid_buf );

    buf = g_strdup_printf( "SELECT * FROM %s WHERE obj_guid='%s'",
                           TABLE_NAME, guid_buf );
    stmt = gnc_sql_create_statement_from_sql( pInfo->be, buf );
    g_free( buf );
    if ( stmt != NULL )
    {
        result = gnc_sql_execute_select_statement( pInfo->be, stmt );
        gnc_sql_statement_dispose( stmt );
        if ( result != NULL )
        {
            GncSqlRow* row = gnc_sql_result_get_first_row( result );

            while ( row != NULL )
            {
                load_slot( pInfo, row );
                row = gnc_sql_result_get_next_row( result );
            }
            gnc_sql_result_dispose( result );
        }
    }
}
Beispiel #13
0
static void
load_all_billterms (GncSqlBackend* be)
{
    GncSqlStatement* stmt;
    GncSqlResult* result;

    g_return_if_fail (be != NULL);

    stmt = gnc_sql_create_select_statement (be, TABLE_NAME);
    result = gnc_sql_execute_select_statement (be, stmt);
    gnc_sql_statement_dispose (stmt);
    if (result != NULL)
    {
        GncSqlRow* row;
        GList* list = NULL;
        GList* l_billterms_needing_parents = NULL;

        row = gnc_sql_result_get_first_row (result);
        while (row != NULL)
        {
            GncBillTerm* pBillTerm = load_single_billterm (be, row,
                                                           &l_billterms_needing_parents);
            if (pBillTerm != NULL)
            {
                list = g_list_append (list, pBillTerm);
            }
            row = gnc_sql_result_get_next_row (result);
        }
        gnc_sql_result_dispose (result);

        if (list != NULL)
        {
            gnc_sql_slots_load_for_list (be, list);
            g_list_free (list);
        }

        /* While there are items on the list of billterms 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_billterms_needing_parents != NULL)
        {
            gboolean progress_made = TRUE;
            GList* elem;

            while (progress_made)
            {
                progress_made = FALSE;
                for (elem = l_billterms_needing_parents; elem != NULL;
                     elem = g_list_next (elem))
                {
                    billterm_parent_guid_struct* s = (billterm_parent_guid_struct*)elem->data;
                    bt_set_parent (s->billterm, &s->guid);
                    l_billterms_needing_parents = g_list_delete_link (l_billterms_needing_parents,
                                                                      elem);
                    progress_made = TRUE;
                }
            }
        }
    }
}
Beispiel #14
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 );

            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 );
            }
            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 );
            }
            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
    }
}
Beispiel #15
0
/*@ null @*/ GSList*
gnc_sql_get_account_balances_slist( GncSqlBackend* be )
{
#if LOAD_TRANSACTIONS_AS_NEEDED
    GncSqlResult* result;
    GncSqlStatement* stmt;
    gchar* buf;
    GSList* bal_slist = NULL;

    g_return_val_if_fail( be != NULL, NULL );

    buf = g_strdup_printf( "SELECT account_guid, reconcile_state, sum(quantity_num) as quantity_num, quantity_denom FROM %s GROUP BY account_guid, reconcile_state, quantity_denom ORDER BY account_guid, reconcile_state",
                           SPLIT_TABLE );
    stmt = gnc_sql_create_statement_from_sql( be, buf );
    g_assert( stmt != NULL );
    g_free( buf );
    result = gnc_sql_execute_select_statement( be, stmt );
    gnc_sql_statement_dispose( stmt );
    if ( result != NULL )
    {
        GncSqlRow* row;
        acct_balances_t* bal = NULL;

        row = gnc_sql_result_get_first_row( result );
        while ( row != NULL )
        {
            single_acct_balance_t* single_bal;

            // Get the next reconcile state balance and merge with other balances
            single_bal = load_single_acct_balances( be, row );
            if ( single_bal != NULL )
            {
                if ( bal != NULL && bal->acct != single_bal->acct )
                {
                    bal->cleared_balance = gnc_numeric_add( bal->cleared_balance, bal->reconciled_balance,
                                                            GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD );
                    bal->balance = gnc_numeric_add( bal->balance, bal->cleared_balance,
                                                    GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD );
                    bal_slist = g_slist_append( bal_slist, bal );
                    bal = NULL;
                }
                if ( bal == NULL )
                {
                    bal = g_malloc( (gsize)sizeof(acct_balances_t) );
                    g_assert( bal != NULL );

                    bal->acct = single_bal->acct;
                    bal->balance = gnc_numeric_zero();
                    bal->cleared_balance = gnc_numeric_zero();
                    bal->reconciled_balance = gnc_numeric_zero();
                }
                if ( single_bal->reconcile_state == 'n' )
                {
                    bal->balance = gnc_numeric_add( bal->balance, single_bal->balance,
                                                    GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD );
                }
                else if ( single_bal->reconcile_state == 'c' )
                {
                    bal->cleared_balance = gnc_numeric_add( bal->cleared_balance, single_bal->balance,
                                                            GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD );
                }
                else if ( single_bal->reconcile_state == 'y' )
                {
                    bal->reconciled_balance = gnc_numeric_add( bal->reconciled_balance, single_bal->balance,
                                              GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD );
                }
                g_free( single_bal );
            }
            row = gnc_sql_result_get_next_row( result );
        }

        // Add the final balance
        if ( bal != NULL )
        {
            bal->cleared_balance = gnc_numeric_add( bal->cleared_balance, bal->reconciled_balance,
                                                    GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD );
            bal->balance = gnc_numeric_add( bal->balance, bal->cleared_balance,
                                            GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD );
            bal_slist = g_slist_append( bal_slist, bal );
        }
        gnc_sql_result_dispose( result );
    }

    return bal_slist;
#else
    return NULL;
#endif
}
Beispiel #16
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 ("");
}