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 ); } }
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); } } }
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 ); } } }
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 ); } }
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; }
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; } } } } }
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); } } }
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 ); } }
/** * 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 ); } }
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 ); } } }
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; } } } } }
/** * 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 } }
/*@ 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 }
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 (""); }