Skip to content

Commit

Permalink
Fix parent/child links for tax tables. If a tax table's parent table …
Browse files Browse the repository at this point in the history
…has not been loaded yet, remember the relationship, and after all tables have been loaded, fix up the rest of the parent/child links.

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@18856 57a11ea4-9604-0410-9ed3-97b8803252fd
  • Loading branch information
Phil Longstaff committed Mar 6, 2010
1 parent c4e929a commit 7744613
Showing 1 changed file with 105 additions and 12 deletions.
117 changes: 105 additions & 12 deletions src/business/business-core/sql/gnc-tax-table-sql.c
Expand Up @@ -57,7 +57,9 @@ typedef struct
static gpointer get_obj_guid( gpointer pObject, const QofParam* param );
static void set_obj_guid( gpointer pObject, gpointer pValue );
static gpointer get_child( gpointer pObject, const QofParam* param );
static gpointer get_parent( gpointer pObject );
static void set_parent( gpointer pObject, gpointer pValue );
static void set_parent_guid( gpointer pObject, gpointer pValue );

#define MAX_NAME_LEN 50

Expand All @@ -69,19 +71,23 @@ static GncSqlColumnTableEntry tt_col_table[] =
{ "guid", CT_GUID, 0, COL_NNUL | COL_PKEY, "guid" },
{ "name", CT_STRING, MAX_NAME_LEN, COL_NNUL, "name" },
{ "refcount", CT_INT64, 0, COL_NNUL, NULL, GNC_TT_REFCOUNT },
{
"invisible", CT_BOOLEAN, 0, COL_NNUL, NULL, NULL,
{ "invisible", CT_BOOLEAN, 0, COL_NNUL, NULL, NULL,
(QofAccessFunc)gncTaxTableGetInvisible, (QofSetterFunc)set_invisible
},
/* { "child", CT_TAXTABLEREF, 0, 0, NULL, NULL,
get_child, (QofSetterFunc)gncTaxTableSetChild }, */
{
"parent", CT_TAXTABLEREF, 0, 0, NULL, NULL,
(QofAccessFunc)gncTaxTableGetParent, set_parent
{ "parent", CT_GUID, 0, 0, NULL, NULL,
(QofAccessFunc)get_parent, set_parent
},
{ NULL }
};

static GncSqlColumnTableEntry tt_parent_col_table[] =
{
{ "parent", CT_GUID, 0, 0, NULL, NULL, NULL, set_parent_guid },
{ NULL }
};

#define TTENTRIES_TABLE_NAME "taxtable_entries"
#define TTENTRIES_TABLE_VERSION 3

Expand Down Expand Up @@ -115,6 +121,12 @@ static GncSqlColumnTableEntry guid_col_table[] =
{ NULL }
};

typedef struct {
/*@ dependent @*/ GncTaxTable* tt;
GUID guid;
gboolean have_guid;
} taxtable_parent_guid_struct;

static gpointer
get_obj_guid( gpointer pObject, const QofParam* param )
{
Expand Down Expand Up @@ -156,23 +168,63 @@ get_child( gpointer pObject, const QofParam* param )
return gncTaxTableGetChild( tt );
}

static /*@ null @*//*@ dependent @*/ gpointer
get_parent( gpointer pObject )
{
const GncTaxTable* tt;
const GncTaxTable* pParent;
const GUID* parent_guid;

g_return_val_if_fail( pObject != NULL, NULL );
g_return_val_if_fail( GNC_IS_TAXTABLE(pObject), NULL );

tt = GNC_TAXTABLE(pObject);
pParent = gncTaxTableGetParent( tt );
if( pParent == NULL ) {
parent_guid = NULL;
} else {
parent_guid = qof_instance_get_guid( QOF_INSTANCE(pParent) );
}

return (gpointer)parent_guid;
}

static void
set_parent( gpointer data, gpointer value )
{
GncTaxTable* tt = GNC_TAXTABLE(data);
GncTaxTable* tt;
GncTaxTable* parent;
QofBook* pBook;
GUID* guid = (GUID*)value;

g_return_if_fail( data != NULL );
g_return_if_fail( GNC_IS_TAXTABLE(data) );

if ( value != NULL )
tt = GNC_TAXTABLE(data);
pBook = qof_instance_get_book( QOF_INSTANCE(tt) );
if ( guid != NULL )
{
parent = GNC_TAXTABLE(value);
gncTaxTableSetParent( tt, parent );
gncTaxTableSetChild( parent, tt );
parent = gncTaxTableLookup( pBook, guid );
if( parent != NULL ) {
gncTaxTableSetParent( tt, parent );
gncTaxTableSetChild( parent, tt );
}
}
}

static void
set_parent_guid( gpointer pObject, /*@ null @*/ gpointer pValue )
{
taxtable_parent_guid_struct* s = (taxtable_parent_guid_struct*)pObject;
GUID* guid = (GUID*)pValue;

g_return_if_fail( pObject != NULL );
g_return_if_fail( pValue != NULL );

s->guid = *guid;
s->have_guid = TRUE;
}

static void
load_single_ttentry( GncSqlBackend* be, GncSqlRow* row, GncTaxTable* tt )
{
Expand Down Expand Up @@ -223,7 +275,8 @@ load_taxtable_entries( GncSqlBackend* be, GncTaxTable* tt )
}

static void
load_single_taxtable( GncSqlBackend* be, GncSqlRow* row )
load_single_taxtable( GncSqlBackend* be, GncSqlRow* row,
GList** l_tt_needing_parents )
{
const GUID* guid;
GncTaxTable* tt;
Expand All @@ -241,6 +294,23 @@ load_single_taxtable( GncSqlBackend* be, GncSqlRow* row )
gnc_sql_slots_load( be, QOF_INSTANCE(tt) );
load_taxtable_entries( be, tt );

/* If the tax table doesn't have a parent, it might be because it hasn't been loaded yet.
If so, add this tax table to the list of tax tables with no parent, along with the parent
GUID so that after they are all loaded, the parents can be fixed up. */
if( gncTaxTableGetParent( tt ) == NULL ) {
taxtable_parent_guid_struct* s = g_malloc( (gsize)sizeof(taxtable_parent_guid_struct) );
g_assert( s != NULL );

s->tt = tt;
s->have_guid = FALSE;
gnc_sql_load_object( be, row, GNC_ID_TAXTABLE, s, tt_parent_col_table );
if( s->have_guid ) {
*l_tt_needing_parents = g_list_prepend( *l_tt_needing_parents, s );
} else {
g_free( s );
}
}

qof_instance_mark_clean( QOF_INSTANCE(tt) );
}

Expand All @@ -259,14 +329,37 @@ load_all_taxtables( GncSqlBackend* be )
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 );
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;
set_parent( s->tt, &s->guid );
tt_needing_parents = g_list_delete_link( tt_needing_parents, elem );
progress_made = TRUE;
}
}
}
}
}

Expand Down

0 comments on commit 7744613

Please sign in to comment.