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_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_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_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; } } } } }
/** * Loads all transactions. This might be used during a save-as operation to ensure that * all data is in memory and ready to be saved. * * @param be SQL backend */ void gnc_sql_transaction_load_all_tx( GncSqlBackend* be ) { gchar* query_sql; GncSqlStatement* stmt; g_return_if_fail( be != NULL ); query_sql = g_strdup_printf( "SELECT * FROM %s", TRANSACTION_TABLE ); stmt = gnc_sql_create_statement_from_sql( be, query_sql ); g_free( query_sql ); if ( stmt != NULL ) { query_transactions( be, stmt ); gnc_sql_statement_dispose( stmt ); } }
G_GNUC_UNUSED static void run_split_query( GncSqlBackend* be, gpointer pQuery ) { split_query_info_t* query_info = (split_query_info_t*)pQuery; g_return_if_fail( be != NULL ); g_return_if_fail( pQuery != NULL ); if ( !query_info->has_been_run ) { query_transactions( be, query_info->stmt ); query_info->has_been_run = TRUE; gnc_sql_statement_dispose( query_info->stmt ); query_info->stmt = NULL; } }
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 ); } }
/** * Loads all transactions for an account. * * @param be SQL backend * @param account Account */ void gnc_sql_transaction_load_tx_for_account( GncSqlBackend* be, Account* account ) { const GncGUID* guid; gchar guid_buf[GUID_ENCODING_LENGTH+1]; gchar* query_sql; GncSqlStatement* stmt; g_return_if_fail( be != NULL ); g_return_if_fail( account != NULL ); guid = qof_instance_get_guid( QOF_INSTANCE(account) ); (void)guid_to_string_buff( guid, guid_buf ); query_sql = g_strdup_printf( "SELECT DISTINCT t.* FROM %s AS t, %s AS s WHERE s.tx_guid=t.guid AND s.account_guid ='%s'", TRANSACTION_TABLE, SPLIT_TABLE, guid_buf ); stmt = gnc_sql_create_statement_from_sql( be, query_sql ); g_free( query_sql ); if ( stmt != NULL ) { query_transactions( be, stmt ); gnc_sql_statement_dispose( stmt ); } }
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_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 (""); }
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; } } } } }
/*@ 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 }