Simplify SQL when loading slots for all objects of a given type.

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@18134 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Phil Longstaff 2009-06-15 22:19:35 +00:00
parent 66f9127933
commit 22a45587a9
6 changed files with 121 additions and 45 deletions

View File

@ -189,7 +189,6 @@ load_all_accounts( GncSqlBackend* be )
QofBook* pBook;
gnc_commodity_table* pTable;
GList* l_accounts_needing_parents = NULL;
GList* list = NULL;
GSList* bal_slist;
GSList* bal;
@ -210,20 +209,17 @@ load_all_accounts( GncSqlBackend* be )
if( result != NULL ) {
GncSqlRow* row = gnc_sql_result_get_first_row( result );
Account* acc;
gchar* sql;
while( row != NULL ) {
acc = load_single_account( be, row, &l_accounts_needing_parents );
if( acc != NULL ) {
list = g_list_append( list, acc );
}
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 );
}
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

View File

@ -135,8 +135,8 @@ load_all_commodities( GncSqlBackend* be )
gnc_sql_statement_dispose( stmt );
if( result != NULL ) {
gnc_commodity* pCommodity;
GList* list = NULL;
GncSqlRow* row = gnc_sql_result_get_first_row( result );
gchar* sql;
while( row != NULL ) {
pCommodity = load_single_commodity( be, row );
@ -146,17 +146,16 @@ load_all_commodities( GncSqlBackend* be )
guid = *qof_instance_get_guid( QOF_INSTANCE(pCommodity) );
pCommodity = gnc_commodity_table_insert( pTable, pCommodity );
list = g_list_append( list, pCommodity );
qof_instance_set_guid( QOF_INSTANCE(pCommodity), &guid );
}
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 );
}
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 );
}
}
/* ================================================================= */

View File

@ -140,23 +140,19 @@ load_all_lots( GncSqlBackend* be )
result = gnc_sql_execute_select_statement( be, stmt );
gnc_sql_statement_dispose( stmt );
if( result != NULL ) {
GList* list = NULL;
GncSqlRow* row = gnc_sql_result_get_first_row( result );
GNCLot* lot;
gchar* sql;
while( row != NULL ) {
lot = load_single_lot( be, row );
if( lot != NULL ) {
list = g_list_append( list, lot );
}
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 );
}
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 );
}
}
}

View File

@ -102,15 +102,14 @@ load_all_prices( GncSqlBackend* be )
gnc_sql_statement_dispose( stmt );
if( result != NULL ) {
GNCPrice* pPrice;
GList* list = NULL;
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 ) {
list = g_list_append( list, pPrice );
(void)gnc_pricedb_add_price( pPriceDB, pPrice );
}
row = gnc_sql_result_get_next_row( result );
@ -118,10 +117,9 @@ load_all_prices( GncSqlBackend* be )
gnc_sql_result_dispose( result );
gnc_pricedb_set_bulk_update( pPriceDB, FALSE );
if( list != NULL ) {
gnc_sql_slots_load_for_list( be, list );
g_list_free( list );
}
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 );
}
}
}

View File

@ -557,6 +557,79 @@ gnc_sql_slots_load_for_list( GncSqlBackend* be, GList* list )
}
}
static void
load_slot_for_book_object( GncSqlBackend* be, GncSqlRow* row, BookLookupFn lookup_fn )
{
slot_info_t slot_info;
const GUID* guid;
QofInstance* inst;
g_return_if_fail( be != NULL );
g_return_if_fail( row != NULL );
g_return_if_fail( lookup_fn != NULL );
guid = load_obj_guid( be, row );
g_return_if_fail( guid != NULL );
inst = lookup_fn( guid, be->primary_book );
g_return_if_fail( inst != NULL );
slot_info.be = be;
slot_info.pKvpFrame = qof_instance_get_slots( inst );
slot_info.path = NULL;
gnc_sql_load_object( be, row, TABLE_NAME, &slot_info, col_table );
if( slot_info.path != NULL ) {
(void)g_string_free( slot_info.path, TRUE );
}
}
/**
* 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
create_slots_tables( GncSqlBackend* be )

View File

@ -45,32 +45,46 @@ gboolean gnc_sql_slots_save( GncSqlBackend* be, const GUID* guid,
gboolean is_infant, KvpFrame* pFrame );
/**
* gnc_sql_slots_delete - Deletes slots for an object from the db.
*
* @param be SQL backend
* @param guid Object guid
* gnc_sql_slots_delete - Deletes slots for an object from the db.
*
* @param be SQL backend
* @param guid Object guid
* @return TRUE if successful, FALSE if error
*/
*/
gboolean gnc_sql_slots_delete( GncSqlBackend* be, const GUID* guid );
/**
* gnc_sql_slots_load - Loads slots for an object from the db.
*
* @param be SQL backend
* @param guid Object guid
*/
* gnc_sql_slots_load - Loads slots for an object from the db.
*
* @param be SQL backend
* @param guid Object guid
*/
void gnc_sql_slots_load( GncSqlBackend* be, QofInstance* inst );
/**
* gnc_sql_slots_load_for_list - Loads slots for a list of objects from the db.
* Loading slots for a list of objects can be faster than loading for one object
* at a time because fewer SQL queries are used.
*
* @param be SQL backend
* @param list List of objects
*/
* gnc_sql_slots_load_for_list - Loads slots for a list of objects from the db.
* Loading slots for a list of objects can be faster than loading for one object
* at a time because fewer SQL queries are used.
*
* @param be SQL backend
* @param list List of objects
*/
void gnc_sql_slots_load_for_list( GncSqlBackend* be, GList* list );
/**
* 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 to get the right object from the book
*/
typedef QofInstance* (*BookLookupFn)( const GUID* guid, const QofBook* book );
void gnc_sql_slots_load_for_sql_subquery( GncSqlBackend* be, const gchar* subquery,
BookLookupFn lookup_fn );
void gnc_sql_init_slots_handler( void );
#endif /* GNC_SLOTS_SQL_H_ */