Improve error handling. If an SQL command fails, set the qof backend error

code.  Unfortunately, at this time, the front end seems to ignore the error
(other than logging it).



git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@17606 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Phil Longstaff
2008-09-27 17:31:23 +00:00
parent 810bb601a6
commit d1198d026f
30 changed files with 792 additions and 451 deletions

View File

@@ -859,7 +859,7 @@ conn_execute_nonselect_statement( GncSqlConnection* conn, GncSqlStatement* stmt
result = dbi_conn_query( dbi_conn->conn, dbi_stmt->sql->str ); result = dbi_conn_query( dbi_conn->conn, dbi_stmt->sql->str );
if( result == NULL ) { if( result == NULL ) {
PERR( "Error executing SQL %s\n", dbi_stmt->sql->str ); PERR( "Error executing SQL %s\n", dbi_stmt->sql->str );
return 0; return -1;
} }
DEBUG( "SQL: %s\n", dbi_stmt->sql->str ); DEBUG( "SQL: %s\n", dbi_stmt->sql->str );
num_rows = dbi_result_get_numrows_affected( result ); num_rows = dbi_result_get_numrows_affected( result );
@@ -910,22 +910,28 @@ conn_does_table_exist( GncSqlConnection* conn, const gchar* table_name )
} }
} }
static void static gboolean
conn_begin_transaction( GncSqlConnection* conn ) conn_begin_transaction( GncSqlConnection* conn )
{ {
GncDbiSqlConnection* dbi_conn = (GncDbiSqlConnection*)conn; GncDbiSqlConnection* dbi_conn = (GncDbiSqlConnection*)conn;
return TRUE;
} }
static void static gboolean
conn_rollback_transaction( GncSqlConnection* conn ) conn_rollback_transaction( GncSqlConnection* conn )
{ {
GncDbiSqlConnection* dbi_conn = (GncDbiSqlConnection*)conn; GncDbiSqlConnection* dbi_conn = (GncDbiSqlConnection*)conn;
return TRUE;
} }
static void static gboolean
conn_commit_transaction( GncSqlConnection* conn ) conn_commit_transaction( GncSqlConnection* conn )
{ {
GncDbiSqlConnection* dbi_conn = (GncDbiSqlConnection*)conn; GncDbiSqlConnection* dbi_conn = (GncDbiSqlConnection*)conn;
return TRUE;
} }
static const gchar* static const gchar*
@@ -1009,7 +1015,7 @@ add_table_column( GString* ddl, const GncSqlColumnInfo* info )
} }
} }
static void static gboolean
conn_create_table( GncSqlConnection* conn, const gchar* table_name, conn_create_table( GncSqlConnection* conn, const gchar* table_name,
const GList* col_info_list ) const GList* col_info_list )
{ {
@@ -1019,9 +1025,9 @@ conn_create_table( GncSqlConnection* conn, const gchar* table_name,
guint col_num; guint col_num;
dbi_result result; dbi_result result;
g_return_if_fail( conn != NULL ); g_return_val_if_fail( conn != NULL, FALSE );
g_return_if_fail( table_name != NULL ); g_return_val_if_fail( table_name != NULL, FALSE );
g_return_if_fail( col_info_list != NULL ); g_return_val_if_fail( col_info_list != NULL, FALSE );
ddl = g_string_new( "" ); ddl = g_string_new( "" );
g_string_printf( ddl, "CREATE TABLE %s (", table_name ); g_string_printf( ddl, "CREATE TABLE %s (", table_name );
@@ -1040,9 +1046,11 @@ conn_create_table( GncSqlConnection* conn, const gchar* table_name,
result = dbi_conn_query( dbi_conn->conn, ddl->str ); result = dbi_conn_query( dbi_conn->conn, ddl->str );
dbi_result_free( result ); dbi_result_free( result );
g_string_free( ddl, TRUE ); g_string_free( ddl, TRUE );
return TRUE;
} }
static void static gboolean
conn_create_index( GncSqlConnection* conn, const gchar* index_name, conn_create_index( GncSqlConnection* conn, const gchar* index_name,
const gchar* table_name, const GncSqlColumnTableEntry* col_table ) const gchar* table_name, const GncSqlColumnTableEntry* col_table )
{ {
@@ -1053,10 +1061,10 @@ conn_create_index( GncSqlConnection* conn, const gchar* index_name,
GncDbiSqlConnection* dbi_conn = (GncDbiSqlConnection*)conn; GncDbiSqlConnection* dbi_conn = (GncDbiSqlConnection*)conn;
GError* error = NULL; GError* error = NULL;
g_return_if_fail( conn != NULL ); g_return_val_if_fail( conn != NULL, FALSE );
g_return_if_fail( index_name != NULL ); g_return_val_if_fail( index_name != NULL, FALSE );
g_return_if_fail( table_name != NULL ); g_return_val_if_fail( table_name != NULL, FALSE );
g_return_if_fail( col_table != NULL ); g_return_val_if_fail( col_table != NULL, FALSE );
cnn = gda_conn->conn; cnn = gda_conn->conn;
g_return_if_fail( cnn != NULL ); g_return_if_fail( cnn != NULL );
@@ -1123,6 +1131,8 @@ conn_create_index( GncSqlConnection* conn, const gchar* index_name,
g_object_unref( op ); g_object_unref( op );
} }
#endif #endif
return TRUE;
} }
static gchar* static gchar*

View File

@@ -263,16 +263,17 @@ create_account_tables( GncSqlBackend* be )
} }
/* ================================================================= */ /* ================================================================= */
void gboolean
gnc_sql_save_account( GncSqlBackend* be, QofInstance* inst ) gnc_sql_save_account( GncSqlBackend* be, QofInstance* inst )
{ {
Account* pAcc = GNC_ACCOUNT(inst); Account* pAcc = GNC_ACCOUNT(inst);
const GUID* guid; const GUID* guid;
gboolean is_infant; gboolean is_infant;
gboolean is_ok = FALSE;
g_return_if_fail( be != NULL ); g_return_val_if_fail( be != NULL, FALSE );
g_return_if_fail( inst != NULL ); g_return_val_if_fail( inst != NULL, FALSE );
g_return_if_fail( GNC_IS_ACCOUNT(inst) ); g_return_val_if_fail( GNC_IS_ACCOUNT(inst), FALSE );
is_infant = qof_instance_get_infant( inst ); is_infant = qof_instance_get_infant( inst );
@@ -293,19 +294,25 @@ gnc_sql_save_account( GncSqlBackend* be, QofInstance* inst )
// If not deleting the account, ensure the commodity is in the db // If not deleting the account, ensure the commodity is in the db
if( op != OP_DB_DELETE ) { if( op != OP_DB_DELETE ) {
gnc_sql_save_commodity( be, xaccAccountGetCommodity( pAcc ) ); is_ok = gnc_sql_save_commodity( be, xaccAccountGetCommodity( pAcc ) );
} }
(void)gnc_sql_do_db_operation( be, op, TABLE_NAME, GNC_ID_ACCOUNT, pAcc, col_table ); if( is_ok ) {
is_ok = gnc_sql_do_db_operation( be, op, TABLE_NAME, GNC_ID_ACCOUNT, pAcc, col_table );
}
// Now, commit or delete any slots if( is_ok ) {
guid = qof_instance_get_guid( inst ); // Now, commit or delete any slots
if( !qof_instance_get_destroying(inst) ) { guid = qof_instance_get_guid( inst );
gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) ); if( !qof_instance_get_destroying(inst) ) {
} else { is_ok = gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
gnc_sql_slots_delete( be, guid ); } else {
} is_ok = gnc_sql_slots_delete( be, guid );
}
}
} }
return is_ok;
} }
/* ================================================================= */ /* ================================================================= */
@@ -354,8 +361,8 @@ gnc_sql_init_account_handler( void )
{ {
GNC_SQL_BACKEND_VERSION, GNC_SQL_BACKEND_VERSION,
GNC_ID_ACCOUNT, GNC_ID_ACCOUNT,
gnc_sql_save_account, /* commit */ gnc_sql_save_account, /* commit */
load_all_accounts, /* initial_load */ load_all_accounts, /* initial_load */
create_account_tables /* create_tables */ create_account_tables /* create_tables */
}; };

View File

@@ -33,6 +33,6 @@
#include <gmodule.h> #include <gmodule.h>
void gnc_sql_init_account_handler( void ); void gnc_sql_init_account_handler( void );
void gnc_sql_save_account( GncSqlBackend* be, QofInstance* inst ); gboolean gnc_sql_save_account( GncSqlBackend* be, QofInstance* inst );
#endif /* GNC_ACCOUNT_SQL_H_ */ #endif /* GNC_ACCOUNT_SQL_H_ */

View File

@@ -63,7 +63,7 @@ static const gchar* convert_search_obj( QofIdType objType );
static void gnc_sql_init_object_handlers( void ); static void gnc_sql_init_object_handlers( void );
static void update_save_progress( GncSqlBackend* be ); static void update_save_progress( GncSqlBackend* be );
static void register_standard_col_type_handlers( void ); static void register_standard_col_type_handlers( void );
static void reset_version_info( GncSqlBackend* be ); static gboolean reset_version_info( GncSqlBackend* be );
static GncSqlStatement* build_insert_statement( GncSqlBackend* be, static GncSqlStatement* build_insert_statement( GncSqlBackend* be,
const gchar* table_name, const gchar* table_name,
QofIdTypeConst obj_name, gpointer pObject, QofIdTypeConst obj_name, gpointer pObject,
@@ -86,7 +86,8 @@ typedef struct {
/* callback structure */ /* callback structure */
typedef struct { typedef struct {
gboolean ok; gboolean is_known;
gboolean is_ok;
GncSqlBackend* be; GncSqlBackend* be;
QofInstance* inst; QofInstance* inst;
QofQuery* pQuery; QofQuery* pQuery;
@@ -240,83 +241,110 @@ write_commodities( GncSqlBackend* be, QofBook* book )
} }
} }
static void static gboolean
write_account_tree( GncSqlBackend* be, Account* root ) write_account_tree( GncSqlBackend* be, Account* root )
{ {
GList* descendants; GList* descendants;
GList* node; GList* node;
gboolean is_ok = TRUE;
g_return_if_fail( be != NULL ); g_return_val_if_fail( be != NULL, FALSE );
g_return_if_fail( root != NULL ); g_return_val_if_fail( root != NULL, FALSE );
descendants = gnc_account_get_descendants( root ); descendants = gnc_account_get_descendants( root );
for( node = descendants; node != NULL; node = g_list_next(node) ) { for( node = descendants; node != NULL && is_ok; node = g_list_next(node) ) {
gnc_sql_save_account( be, QOF_INSTANCE(GNC_ACCOUNT(node->data)) ); is_ok = gnc_sql_save_account( be, QOF_INSTANCE(GNC_ACCOUNT(node->data)) );
update_save_progress( be ); update_save_progress( be );
} }
g_list_free( descendants ); g_list_free( descendants );
return is_ok;
} }
static void static gboolean
write_accounts( GncSqlBackend* be ) write_accounts( GncSqlBackend* be )
{ {
g_return_if_fail( be != NULL ); g_return_val_if_fail( be != NULL, FALSE );
write_account_tree( be, gnc_book_get_root_account( be->primary_book ) ); return write_account_tree( be, gnc_book_get_root_account( be->primary_book ) );
} }
typedef struct {
GncSqlBackend* be;
gboolean is_ok;
} write_objects_t;
static int static int
write_tx( Transaction* tx, gpointer data ) write_tx( Transaction* tx, gpointer data )
{ {
GncSqlBackend* be = (GncSqlBackend*)data; write_objects_t* s = (write_objects_t*)data;
g_return_val_if_fail( tx != NULL, 0 ); g_return_val_if_fail( tx != NULL, 0 );
g_return_val_if_fail( data != NULL, 0 ); g_return_val_if_fail( data != NULL, 0 );
gnc_sql_save_transaction( be, QOF_INSTANCE(tx) ); s->is_ok = gnc_sql_save_transaction( s->be, QOF_INSTANCE(tx) );
update_save_progress( be ); update_save_progress( s->be );
return 0; if( s->is_ok ) {
return 0;
} else {
return 1;
}
} }
static void static gboolean
write_transactions( GncSqlBackend* be ) write_transactions( GncSqlBackend* be )
{ {
g_return_if_fail( be != NULL ); write_objects_t data;
g_return_val_if_fail( be != NULL, FALSE );
data.be = be;
data.is_ok = TRUE;
xaccAccountTreeForEachTransaction( gnc_book_get_root_account( be->primary_book ), xaccAccountTreeForEachTransaction( gnc_book_get_root_account( be->primary_book ),
write_tx, write_tx,
(gpointer)be ); &data );
return data.is_ok;
} }
static void static gboolean
write_template_transactions( GncSqlBackend* be ) write_template_transactions( GncSqlBackend* be )
{ {
Account* ra; Account* ra;
write_objects_t data;
g_return_if_fail( be != NULL ); g_return_val_if_fail( be != NULL, FALSE );
data.is_ok = TRUE;
ra = gnc_book_get_template_root( be->primary_book ); ra = gnc_book_get_template_root( be->primary_book );
if( gnc_account_n_descendants( ra ) > 0 ) { if( gnc_account_n_descendants( ra ) > 0 ) {
write_account_tree( be, ra ); data.is_ok = write_account_tree( be, ra );
xaccAccountTreeForEachTransaction( ra, write_tx, (gpointer)be ); if( data.is_ok ) {
data.be = be;
xaccAccountTreeForEachTransaction( ra, write_tx, &data );
}
} }
return data.is_ok;
} }
static void static gboolean
write_schedXactions( GncSqlBackend* be ) write_schedXactions( GncSqlBackend* be )
{ {
GList* schedXactions; GList* schedXactions;
SchedXaction* tmpSX; SchedXaction* tmpSX;
gboolean is_ok = TRUE;
g_return_if_fail( be != NULL ); g_return_val_if_fail( be != NULL, FALSE );
schedXactions = gnc_book_get_schedxactions( be->primary_book )->sx_list; schedXactions = gnc_book_get_schedxactions( be->primary_book )->sx_list;
for( ; schedXactions != NULL; schedXactions = schedXactions->next ) { for( ; schedXactions != NULL && is_ok; schedXactions = schedXactions->next ) {
tmpSX = schedXactions->data; tmpSX = schedXactions->data;
gnc_sql_save_schedxaction( be, QOF_INSTANCE( tmpSX ) ); is_ok = gnc_sql_save_schedxaction( be, QOF_INSTANCE( tmpSX ) );
} }
return is_ok;
} }
static void static void
@@ -354,7 +382,7 @@ gnc_sql_sync_all( GncSqlBackend* be, QofBook *book )
GError* error = NULL; GError* error = NULL;
gint row; gint row;
gint numTables; gint numTables;
gboolean status; gboolean is_ok;
g_return_if_fail( be != NULL ); g_return_if_fail( be != NULL );
g_return_if_fail( book != NULL ); g_return_if_fail( book != NULL );
@@ -379,12 +407,22 @@ gnc_sql_sync_all( GncSqlBackend* be, QofBook *book )
// FIXME: should write the set of commodities that are used // FIXME: should write the set of commodities that are used
//write_commodities( be, book ); //write_commodities( be, book );
gnc_sql_save_book( be, QOF_INSTANCE(book) ); is_ok = gnc_sql_save_book( be, QOF_INSTANCE(book) );
write_accounts( be ); if( is_ok ) {
write_transactions( be ); is_ok = write_accounts( be );
write_template_transactions( be ); }
write_schedXactions( be ); if( is_ok ) {
qof_object_foreach_backend( GNC_SQL_BACKEND, write_cb, be ); is_ok = write_transactions( be );
}
if( is_ok ) {
is_ok = write_template_transactions( be );
}
if( is_ok ) {
is_ok = write_schedXactions( be );
}
if( is_ok ) {
qof_object_foreach_backend( GNC_SQL_BACKEND, write_cb, be );
}
gnc_sql_connection_commit_transaction( be->conn ); gnc_sql_connection_commit_transaction( be->conn );
be->is_pristine_db = FALSE; be->is_pristine_db = FALSE;
@@ -423,11 +461,11 @@ commit_cb( const gchar* type, gpointer data_p, gpointer be_data_p )
/* If this has already been handled, or is not the correct handler, return */ /* If this has already been handled, or is not the correct handler, return */
if( strcmp( pData->type_name, be_data->inst->e_type ) != 0 ) return; if( strcmp( pData->type_name, be_data->inst->e_type ) != 0 ) return;
if( be_data->ok ) return; if( be_data->is_known ) return;
if( pData->commit != NULL ) { if( pData->commit != NULL ) {
(pData->commit)( be_data->be, be_data->inst ); be_data->is_ok = (pData->commit)( be_data->be, be_data->inst );
be_data->ok = TRUE; be_data->is_known = TRUE;
} }
} }
@@ -439,7 +477,6 @@ gnc_sql_commit_edit( GncSqlBackend *be, QofInstance *inst )
{ {
sql_backend be_data; sql_backend be_data;
GError* error; GError* error;
gboolean status;
gboolean is_dirty; gboolean is_dirty;
gboolean is_destroying; gboolean is_destroying;
gboolean is_infant; gboolean is_infant;
@@ -479,21 +516,30 @@ gnc_sql_commit_edit( GncSqlBackend *be, QofInstance *inst )
error = NULL; error = NULL;
gnc_sql_connection_begin_transaction( be->conn ); gnc_sql_connection_begin_transaction( be->conn );
be_data.ok = FALSE; be_data.is_known = FALSE;
be_data.be = be; be_data.be = be;
be_data.inst = inst; be_data.inst = inst;
qof_object_foreach_backend( GNC_SQL_BACKEND, commit_cb, &be_data ); qof_object_foreach_backend( GNC_SQL_BACKEND, commit_cb, &be_data );
if( !be_data.ok ) { if( !be_data.is_known ) {
PERR( "gnc_sql_commit_edit(): Unknown object type '%s'\n", inst->e_type ); PERR( "gnc_sql_commit_edit(): Unknown object type '%s'\n", inst->e_type );
gnc_sql_connection_rollback_transaction( be->conn ); gnc_sql_connection_rollback_transaction( be->conn );
// Don't let unknown items still mark the book as being dirty // Don't let unknown items still mark the book as being dirty
qof_instance_mark_clean(inst); qof_instance_mark_clean(inst);
qof_book_mark_saved( be->primary_book ); qof_book_mark_saved( be->primary_book );
LEAVE( "Rolled back" ); LEAVE( "Rolled back - unknown object type" );
return; return;
} }
if( !be_data.is_ok ) {
// Error - roll it back
gnc_sql_connection_rollback_transaction( be->conn );
// This *should* leave things marked dirty
LEAVE( "Rolled back - database error" );
return;
}
gnc_sql_connection_commit_transaction( be->conn ); gnc_sql_connection_commit_transaction( be->conn );
qof_instance_mark_clean(inst); qof_instance_mark_clean(inst);
@@ -613,13 +659,13 @@ compile_query_cb( const gchar* type, gpointer data_p, gpointer be_data_p )
// Is this the right item? // Is this the right item?
if( strcmp( type, be_data->pQueryInfo->searchObj ) != 0 ) return; if( strcmp( type, be_data->pQueryInfo->searchObj ) != 0 ) return;
if( be_data->ok ) return; if( be_data->is_ok ) return;
if( pData->compile_query != NULL ) { if( pData->compile_query != NULL ) {
be_data->pQueryInfo->pCompiledQuery = (pData->compile_query)( be_data->pQueryInfo->pCompiledQuery = (pData->compile_query)(
be_data->be, be_data->be,
be_data->pQuery ); be_data->pQuery );
be_data->ok = TRUE; be_data->is_ok = TRUE;
} }
} }
@@ -643,14 +689,14 @@ gnc_sql_compile_query( QofBackend* pBEnd, QofQuery* pQuery )
pQueryInfo = g_malloc( sizeof( gnc_sql_query_info ) ); pQueryInfo = g_malloc( sizeof( gnc_sql_query_info ) );
// Try various objects first // Try various objects first
be_data.ok = FALSE; be_data.is_ok = FALSE;
be_data.be = be; be_data.be = be;
be_data.pQuery = pQuery; be_data.pQuery = pQuery;
pQueryInfo->searchObj = searchObj; pQueryInfo->searchObj = searchObj;
be_data.pQueryInfo = pQueryInfo; be_data.pQueryInfo = pQueryInfo;
qof_object_foreach_backend( GNC_SQL_BACKEND, compile_query_cb, &be_data ); qof_object_foreach_backend( GNC_SQL_BACKEND, compile_query_cb, &be_data );
if( be_data.ok ) { if( be_data.is_ok ) {
LEAVE( "" ); LEAVE( "" );
return be_data.pQueryInfo; return be_data.pQueryInfo;
} }
@@ -697,12 +743,12 @@ free_query_cb( const gchar* type, gpointer data_p, gpointer be_data_p )
g_return_if_fail( type != NULL && pData != NULL && be_data != NULL ); g_return_if_fail( type != NULL && pData != NULL && be_data != NULL );
g_return_if_fail( pData->version == GNC_SQL_BACKEND_VERSION ); g_return_if_fail( pData->version == GNC_SQL_BACKEND_VERSION );
if( be_data->ok ) return; if( be_data->is_ok ) return;
if( strcmp( type, be_data->pQueryInfo->searchObj ) != 0 ) return; if( strcmp( type, be_data->pQueryInfo->searchObj ) != 0 ) return;
if( pData->free_query != NULL ) { if( pData->free_query != NULL ) {
(pData->free_query)( be_data->be, be_data->pCompiledQuery ); (pData->free_query)( be_data->be, be_data->pCompiledQuery );
be_data->ok = TRUE; be_data->is_ok = TRUE;
} }
} }
@@ -719,13 +765,13 @@ gnc_sql_free_query( QofBackend* pBEnd, gpointer pQuery )
ENTER( " " ); ENTER( " " );
// Try various objects first // Try various objects first
be_data.ok = FALSE; be_data.is_ok = FALSE;
be_data.be = be; be_data.be = be;
be_data.pCompiledQuery = pQuery; be_data.pCompiledQuery = pQuery;
be_data.pQueryInfo = pQueryInfo; be_data.pQueryInfo = pQueryInfo;
qof_object_foreach_backend( GNC_SQL_BACKEND, free_query_cb, &be_data ); qof_object_foreach_backend( GNC_SQL_BACKEND, free_query_cb, &be_data );
if( be_data.ok ) { if( be_data.is_ok ) {
LEAVE( "" ); LEAVE( "" );
return; return;
} }
@@ -745,14 +791,14 @@ run_query_cb( const gchar* type, gpointer data_p, gpointer be_data_p )
g_return_if_fail( type != NULL && pData != NULL && be_data != NULL ); g_return_if_fail( type != NULL && pData != NULL && be_data != NULL );
g_return_if_fail( pData->version == GNC_SQL_BACKEND_VERSION ); g_return_if_fail( pData->version == GNC_SQL_BACKEND_VERSION );
if( be_data->ok ) return; if( be_data->is_ok ) return;
// Is this the right item? // Is this the right item?
if( strcmp( type, be_data->pQueryInfo->searchObj ) != 0 ) return; if( strcmp( type, be_data->pQueryInfo->searchObj ) != 0 ) return;
if( pData->run_query != NULL ) { if( pData->run_query != NULL ) {
(pData->run_query)( be_data->be, be_data->pCompiledQuery ); (pData->run_query)( be_data->be, be_data->pCompiledQuery );
be_data->ok = TRUE; be_data->is_ok = TRUE;
} }
} }
@@ -775,7 +821,7 @@ gnc_sql_run_query( QofBackend* pBEnd, gpointer pQuery )
qof_event_suspend(); qof_event_suspend();
// Try various objects first // Try various objects first
be_data.ok = FALSE; be_data.is_ok = FALSE;
be_data.be = be; be_data.be = be;
be_data.pCompiledQuery = pQueryInfo->pCompiledQuery; be_data.pCompiledQuery = pQueryInfo->pCompiledQuery;
be_data.pQueryInfo = pQueryInfo; be_data.pQueryInfo = pQueryInfo;
@@ -784,7 +830,7 @@ gnc_sql_run_query( QofBackend* pBEnd, gpointer pQuery )
be->loading = FALSE; be->loading = FALSE;
be->in_query = FALSE; be->in_query = FALSE;
qof_event_resume(); qof_event_resume();
// if( be_data.ok ) { // if( be_data.is_ok ) {
// LEAVE( "" ); // LEAVE( "" );
// return; // return;
// } // }
@@ -1883,7 +1929,7 @@ gnc_sql_load_object( const GncSqlBackend* be, GncSqlRow* row,
/* ================================================================= */ /* ================================================================= */
GncSqlStatement* GncSqlStatement*
gnc_sql_create_select_statement( const GncSqlBackend* be, const gchar* table_name ) gnc_sql_create_select_statement( GncSqlBackend* be, const gchar* table_name )
{ {
gchar* sql; gchar* sql;
@@ -1895,7 +1941,7 @@ gnc_sql_create_select_statement( const GncSqlBackend* be, const gchar* table_nam
} }
static GncSqlStatement* static GncSqlStatement*
create_single_col_select_statement( const GncSqlBackend* be, create_single_col_select_statement( GncSqlBackend* be,
const gchar* table_name, const gchar* table_name,
const GncSqlColumnTableEntry* table_row ) const GncSqlColumnTableEntry* table_row )
{ {
@@ -1914,15 +1960,14 @@ create_single_col_select_statement( const GncSqlBackend* be,
GncSqlResult* GncSqlResult*
gnc_sql_execute_select_statement( GncSqlBackend* be, GncSqlStatement* stmt ) gnc_sql_execute_select_statement( GncSqlBackend* be, GncSqlStatement* stmt )
{ {
GError* error = NULL;
GncSqlResult* result; GncSqlResult* result;
g_return_val_if_fail( be != NULL, NULL ); g_return_val_if_fail( be != NULL, NULL );
g_return_val_if_fail( stmt != NULL, NULL ); g_return_val_if_fail( stmt != NULL, NULL );
result = gnc_sql_connection_execute_select_statement( be->conn, stmt ); result = gnc_sql_connection_execute_select_statement( be->conn, stmt );
if( error != NULL ) { if( result == NULL ) {
PERR( "SQL error: %s\n%s\n", gnc_sql_statement_to_sql( stmt ), error->message ); PERR( "SQL error: %s\n", gnc_sql_statement_to_sql( stmt ) );
qof_backend_set_error( &be->be, ERR_BACKEND_SERVER_ERR ); qof_backend_set_error( &be->be, ERR_BACKEND_SERVER_ERR );
} }
@@ -1930,9 +1975,8 @@ gnc_sql_execute_select_statement( GncSqlBackend* be, GncSqlStatement* stmt )
} }
GncSqlStatement* GncSqlStatement*
gnc_sql_create_statement_from_sql( const GncSqlBackend* be, gchar* sql ) gnc_sql_create_statement_from_sql( GncSqlBackend* be, gchar* sql )
{ {
GError* error = NULL;
GncSqlStatement* stmt; GncSqlStatement* stmt;
g_return_val_if_fail( be != NULL, NULL ); g_return_val_if_fail( be != NULL, NULL );
@@ -1940,17 +1984,17 @@ gnc_sql_create_statement_from_sql( const GncSqlBackend* be, gchar* sql )
stmt = gnc_sql_connection_create_statement_from_sql( be->conn, sql ); stmt = gnc_sql_connection_create_statement_from_sql( be->conn, sql );
if( stmt == NULL ) { if( stmt == NULL ) {
PERR( "SQL error: %s\n%s\n", sql, error->message ); PERR( "SQL error: %s\n", sql );
qof_backend_set_error( &be->be, ERR_BACKEND_SERVER_ERR );
} }
return stmt; return stmt;
} }
GncSqlResult* GncSqlResult*
gnc_sql_execute_select_sql( const GncSqlBackend* be, gchar* sql ) gnc_sql_execute_select_sql( GncSqlBackend* be, gchar* sql )
{ {
GncSqlStatement* stmt; GncSqlStatement* stmt;
GError* error = NULL;
GncSqlResult* result = NULL; GncSqlResult* result = NULL;
g_return_val_if_fail( be != NULL, NULL ); g_return_val_if_fail( be != NULL, NULL );
@@ -1961,15 +2005,16 @@ gnc_sql_execute_select_sql( const GncSqlBackend* be, gchar* sql )
return NULL; return NULL;
} }
result = gnc_sql_connection_execute_select_statement( be->conn, stmt ); result = gnc_sql_connection_execute_select_statement( be->conn, stmt );
if( error != NULL ) { if( result == NULL ) {
PERR( "SQL error: %s\n%s\n", sql, error->message ); PERR( "SQL error: %s\n", sql );
qof_backend_set_error( &be->be, ERR_BACKEND_SERVER_ERR );
} }
return result; return result;
} }
gint gint
gnc_sql_execute_nonselect_sql( const GncSqlBackend* be, gchar* sql ) gnc_sql_execute_nonselect_sql( GncSqlBackend* be, gchar* sql )
{ {
GncSqlStatement* stmt; GncSqlStatement* stmt;
gint result; gint result;
@@ -1979,7 +2024,7 @@ gnc_sql_execute_nonselect_sql( const GncSqlBackend* be, gchar* sql )
stmt = gnc_sql_create_statement_from_sql( be, sql ); stmt = gnc_sql_create_statement_from_sql( be, sql );
if( stmt == NULL ) { if( stmt == NULL ) {
return 0; return -1;
} }
result = gnc_sql_connection_execute_nonselect_statement( be->conn, stmt ); result = gnc_sql_connection_execute_nonselect_statement( be->conn, stmt );
gnc_sql_statement_dispose( stmt ); gnc_sql_statement_dispose( stmt );
@@ -2073,6 +2118,7 @@ gnc_sql_do_db_operation( GncSqlBackend* be,
const GncSqlColumnTableEntry* table ) const GncSqlColumnTableEntry* table )
{ {
GncSqlStatement* stmt; GncSqlStatement* stmt;
gboolean ok = FALSE;
g_return_val_if_fail( be != NULL, FALSE ); g_return_val_if_fail( be != NULL, FALSE );
g_return_val_if_fail( table_name != NULL, FALSE ); g_return_val_if_fail( table_name != NULL, FALSE );
@@ -2090,13 +2136,19 @@ gnc_sql_do_db_operation( GncSqlBackend* be,
g_assert( FALSE ); g_assert( FALSE );
} }
if( stmt != NULL ) { if( stmt != NULL ) {
gnc_sql_connection_execute_nonselect_statement( be->conn, stmt ); gint result;
gnc_sql_statement_dispose( stmt );
return TRUE; result = gnc_sql_connection_execute_nonselect_statement( be->conn, stmt );
} else { if( result == -1 ) {
return FALSE; PERR( "SQL error: %s\n", gnc_sql_statement_to_sql( stmt ) );
qof_backend_set_error( &be->be, ERR_BACKEND_SERVER_ERR );
} else {
ok = TRUE;
}
gnc_sql_statement_dispose( stmt );
} }
return ok;
} }
static GSList* static GSList*
@@ -2302,13 +2354,14 @@ build_delete_statement( GncSqlBackend* be,
} }
/* ================================================================= */ /* ================================================================= */
void gboolean
gnc_sql_commit_standard_item( GncSqlBackend* be, QofInstance* inst, const gchar* tableName, gnc_sql_commit_standard_item( GncSqlBackend* be, QofInstance* inst, const gchar* tableName,
QofIdTypeConst obj_name, const GncSqlColumnTableEntry* col_table ) QofIdTypeConst obj_name, const GncSqlColumnTableEntry* col_table )
{ {
const GUID* guid; const GUID* guid;
gboolean is_infant; gboolean is_infant;
gint op; gint op;
gboolean is_ok;
is_infant = qof_instance_get_infant( inst ); is_infant = qof_instance_get_infant( inst );
if( qof_instance_get_destroying( inst ) ) { if( qof_instance_get_destroying( inst ) ) {
@@ -2318,24 +2371,29 @@ gnc_sql_commit_standard_item( GncSqlBackend* be, QofInstance* inst, const gchar*
} else { } else {
op = OP_DB_UPDATE; op = OP_DB_UPDATE;
} }
(void)gnc_sql_do_db_operation( be, op, tableName, obj_name, inst, col_table ); is_ok = gnc_sql_do_db_operation( be, op, tableName, obj_name, inst, col_table );
// Now, commit any slots if( is_ok ) {
guid = qof_instance_get_guid( inst ); // Now, commit any slots
if( !qof_instance_get_destroying(inst) ) { guid = qof_instance_get_guid( inst );
gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) ); if( !qof_instance_get_destroying(inst) ) {
} else { is_ok = gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
gnc_sql_slots_delete( be, guid ); } else {
} is_ok = gnc_sql_slots_delete( be, guid );
}
}
return is_ok;
} }
/* ================================================================= */ /* ================================================================= */
static gboolean static gboolean
create_table( const GncSqlBackend* be, const gchar* table_name, do_create_table( const GncSqlBackend* be, const gchar* table_name,
const GncSqlColumnTableEntry* col_table ) const GncSqlColumnTableEntry* col_table )
{ {
GList* col_info_list = NULL; GList* col_info_list = NULL;
gboolean ok = FALSE;
g_return_val_if_fail( be != NULL, FALSE ); g_return_val_if_fail( be != NULL, FALSE );
g_return_val_if_fail( table_name != NULL, FALSE ); g_return_val_if_fail( table_name != NULL, FALSE );
@@ -2347,19 +2405,19 @@ create_table( const GncSqlBackend* be, const gchar* table_name,
pHandler = get_handler( col_table ); pHandler = get_handler( col_table );
pHandler->add_col_info_to_list_fn( be, col_table, &col_info_list ); pHandler->add_col_info_to_list_fn( be, col_table, &col_info_list );
} }
gnc_sql_connection_create_table( be->conn, table_name, col_info_list ); ok = gnc_sql_connection_create_table( be->conn, table_name, col_info_list );
return TRUE; return ok;
} }
gboolean gboolean
gnc_sql_create_table( const GncSqlBackend* be, const gchar* table_name, gnc_sql_create_table( GncSqlBackend* be, const gchar* table_name,
gint table_version, const GncSqlColumnTableEntry* col_table ) gint table_version, const GncSqlColumnTableEntry* col_table )
{ {
gboolean ok; gboolean ok;
ok = create_table( be, table_name, col_table ); ok = do_create_table( be, table_name, col_table );
if( ok ) { if( ok ) {
(void)gnc_sql_set_table_version( be, table_name, table_version ); ok = gnc_sql_set_table_version( be, table_name, table_version );
} }
return ok; return ok;
} }
@@ -2368,21 +2426,24 @@ gboolean
gnc_sql_create_temp_table( const GncSqlBackend* be, const gchar* table_name, gnc_sql_create_temp_table( const GncSqlBackend* be, const gchar* table_name,
const GncSqlColumnTableEntry* col_table ) const GncSqlColumnTableEntry* col_table )
{ {
return create_table( be, table_name, col_table ); return do_create_table( be, table_name, col_table );
} }
void gboolean
gnc_sql_create_index( const GncSqlBackend* be, const gchar* index_name, gnc_sql_create_index( const GncSqlBackend* be, const gchar* index_name,
const gchar* table_name, const gchar* table_name,
const GncSqlColumnTableEntry* col_table ) const GncSqlColumnTableEntry* col_table )
{ {
g_return_if_fail( be != NULL ); gboolean ok;
g_return_if_fail( index_name != NULL );
g_return_if_fail( table_name != NULL ); g_return_val_if_fail( be != NULL, FALSE );
g_return_if_fail( col_table != NULL ); g_return_val_if_fail( index_name != NULL, FALSE );
g_return_val_if_fail( table_name != NULL, FALSE );
g_return_val_if_fail( col_table != NULL, FALSE );
gnc_sql_connection_create_index( be->conn, index_name, table_name, ok = gnc_sql_connection_create_index( be->conn, index_name, table_name,
col_table ); col_table );
return ok;
} }
gint gint
@@ -2454,7 +2515,7 @@ gnc_sql_init_version_info( GncSqlBackend* be )
} else { } else {
gboolean ok; gboolean ok;
ok = create_table( be, VERSION_TABLE_NAME, version_table ); ok = do_create_table( be, VERSION_TABLE_NAME, version_table );
} }
} }
@@ -2463,20 +2524,23 @@ gnc_sql_init_version_info( GncSqlBackend* be )
* It also recreates the version table in the db. * It also recreates the version table in the db.
* *
* @param be Backend struct * @param be Backend struct
* @return TRUE if successful, FALSE if error
*/ */
static void static gboolean
reset_version_info( GncSqlBackend* be ) reset_version_info( GncSqlBackend* be )
{ {
gboolean ok; gboolean ok;
g_return_if_fail( be != NULL ); g_return_val_if_fail( be != NULL, FALSE );
ok = create_table( be, VERSION_TABLE_NAME, version_table ); ok = do_create_table( be, VERSION_TABLE_NAME, version_table );
if( be->versions == NULL ) { if( be->versions == NULL ) {
be->versions = g_hash_table_new_full( g_str_hash, g_str_equal, g_free, NULL ); be->versions = g_hash_table_new_full( g_str_hash, g_str_equal, g_free, NULL );
} else { } else {
g_hash_table_remove_all( be->versions ); g_hash_table_remove_all( be->versions );
} }
return ok;
} }
/** /**
@@ -2502,10 +2566,11 @@ gnc_sql_finalize_version_info( GncSqlBackend* be )
* @return TRUE if successful, FALSE if unsuccessful * @return TRUE if successful, FALSE if unsuccessful
*/ */
gboolean gboolean
gnc_sql_set_table_version( const GncSqlBackend* be, const gchar* table_name, gint version ) gnc_sql_set_table_version( GncSqlBackend* be, const gchar* table_name, gint version )
{ {
gchar* sql; gchar* sql;
gint cur_version; gint cur_version;
gint status;
g_return_val_if_fail( be != NULL, FALSE ); g_return_val_if_fail( be != NULL, FALSE );
g_return_val_if_fail( table_name != NULL, FALSE ); g_return_val_if_fail( table_name != NULL, FALSE );
@@ -2521,7 +2586,11 @@ gnc_sql_set_table_version( const GncSqlBackend* be, const gchar* table_name, gin
VERSION_COL_NAME, version, VERSION_COL_NAME, version,
TABLE_COL_NAME, table_name ); TABLE_COL_NAME, table_name );
} }
(void)gnc_sql_execute_nonselect_sql( be, sql ); status = gnc_sql_execute_nonselect_sql( be, sql );
if( status == -1 ) {
PERR( "SQL error: %s\n", sql );
qof_backend_set_error( &be->be, ERR_BACKEND_SERVER_ERR );
}
} }
g_hash_table_insert( be->versions, g_strdup( table_name ), GINT_TO_POINTER(version) ); g_hash_table_insert( be->versions, g_strdup( table_name ), GINT_TO_POINTER(version) );

View File

@@ -159,16 +159,16 @@ struct GncSqlStatement
struct GncSqlConnection struct GncSqlConnection
{ {
void (*dispose)( GncSqlConnection* ); void (*dispose)( GncSqlConnection* );
GncSqlResult* (*executeSelectStatement)( GncSqlConnection*, GncSqlStatement* ); GncSqlResult* (*executeSelectStatement)( GncSqlConnection*, GncSqlStatement* ); /**< Returns NULL if error */
gint (*executeNonSelectStatement)( GncSqlConnection*, GncSqlStatement* ); gint (*executeNonSelectStatement)( GncSqlConnection*, GncSqlStatement* ); /**< Returns -1 if error */
GncSqlStatement* (*createStatementFromSql)( GncSqlConnection*, gchar* ); GncSqlStatement* (*createStatementFromSql)( GncSqlConnection*, gchar* );
gboolean (*doesTableExist)( GncSqlConnection*, const gchar* ); gboolean (*doesTableExist)( GncSqlConnection*, const gchar* );
void (*beginTransaction)( GncSqlConnection* ); gboolean (*beginTransaction)( GncSqlConnection* ); /**< Returns TRUE if successful, FALSE if error */
void (*rollbackTransaction)( GncSqlConnection* ); gboolean (*rollbackTransaction)( GncSqlConnection* ); /**< Returns TRUE if successful, FALSE if error */
void (*commitTransaction)( GncSqlConnection* ); gboolean (*commitTransaction)( GncSqlConnection* ); /**< Returns TRUE if successful, FALSE if error */
const gchar* (*getColumnTypeName)( GncSqlConnection*, GType, gint size ); const gchar* (*getColumnTypeName)( GncSqlConnection*, GType, gint size );
void (*createTable)( GncSqlConnection*, const gchar*, const GList* ); gboolean (*createTable)( GncSqlConnection*, const gchar*, const GList* ); /**< Returns TRUE if successful, FALSE if error */
void (*createIndex)( GncSqlConnection*, const gchar*, const gchar*, const GncSqlColumnTableEntry* ); gboolean (*createIndex)( GncSqlConnection*, const gchar*, const gchar*, const GncSqlColumnTableEntry* ); /**< Returns TRUE if successful, FALSE if error */
gchar* (*quoteString)( const GncSqlConnection*, gchar* ); gchar* (*quoteString)( const GncSqlConnection*, gchar* );
}; };
#define gnc_sql_connection_dispose(CONN) (CONN)->dispose(CONN) #define gnc_sql_connection_dispose(CONN) (CONN)->dispose(CONN)
@@ -251,8 +251,10 @@ typedef struct
{ {
int version; /**< Backend version number */ int version; /**< Backend version number */
const gchar * type_name; /**< Engine object type name */ const gchar * type_name; /**< Engine object type name */
/** Commit an instance of this object to the database */ /** Commit an instance of this object to the database
void (*commit)( GncSqlBackend* be, QofInstance* inst ); * @return TRUE if successful, FALSE if error
*/
gboolean (*commit)( GncSqlBackend* be, QofInstance* inst );
/** Load all objects of this type from the database */ /** Load all objects of this type from the database */
void (*initial_load)( GncSqlBackend* be ); void (*initial_load)( GncSqlBackend* be );
/** Create database tables for this object */ /** Create database tables for this object */
@@ -263,8 +265,10 @@ typedef struct
void (*run_query)( GncSqlBackend* be, gpointer pQuery ); void (*run_query)( GncSqlBackend* be, gpointer pQuery );
/** Free a query on these objects */ /** Free a query on these objects */
void (*free_query)( GncSqlBackend* be, gpointer pQuery ); void (*free_query)( GncSqlBackend* be, gpointer pQuery );
/** Write all objects of this type to the database */ /** Write all objects of this type to the database
void (*write)( GncSqlBackend* be ); * @return TRUE if successful, FALSE if error
*/
gboolean (*write)( GncSqlBackend* be );
} GncSqlObjectBackend; } GncSqlObjectBackend;
#define GNC_SQL_BACKEND "gnc:sql:1" #define GNC_SQL_BACKEND "gnc:sql:1"
#define GNC_SQL_BACKEND_VERSION 1 #define GNC_SQL_BACKEND_VERSION 1
@@ -417,31 +421,35 @@ gboolean gnc_sql_do_db_operation( GncSqlBackend* be,
const GncSqlColumnTableEntry* table ); const GncSqlColumnTableEntry* table );
/** /**
* Execute an SQL SELECT statement. * Executes an SQL SELECT statement and returns the result rows. If an error
* occurs, an entry is added to the log, an error status is returned to qof and
* NULL is returned.
* *
* @param be SQL backend struct * @param be SQL backend struct
* @param statement Statement * @param statement Statement
* @return Results * @return Results, or NULL if an error has occured
*/ */
GncSqlResult* gnc_sql_execute_select_statement( GncSqlBackend* be, GncSqlStatement* statement ); GncSqlResult* gnc_sql_execute_select_statement( GncSqlBackend* be, GncSqlStatement* statement );
/** /**
* Executes an SQL SELECT statement from an SQL char string. * Executes an SQL SELECT statement from an SQL char string and returns the
* result rows. If an error occurs, an entry is added to the log, an error
* status is returned to qof and NULL is returned.
* *
* @param be SQL backend struct * @param be SQL backend struct
* @param sql SQL SELECT string * @param sql SQL SELECT string
* @return Results * @return Results, or NULL if an error has occured
*/ */
GncSqlResult* gnc_sql_execute_select_sql( const GncSqlBackend* be, gchar* sql ); GncSqlResult* gnc_sql_execute_select_sql( GncSqlBackend* be, gchar* sql );
/** /**
* Executes an SQL non-SELECT statement from an SQL char string. * Executes an SQL non-SELECT statement from an SQL char string.
* *
* @param be SQL backend struct * @param be SQL backend struct
* @param sql SQL non-SELECT string * @param sql SQL non-SELECT string
* @returns Number of rows affected * @returns Number of rows affected, or -1 if an error has occured
*/ */
gint gnc_sql_execute_nonselect_sql( const GncSqlBackend* be, gchar* sql ); gint gnc_sql_execute_nonselect_sql( GncSqlBackend* be, gchar* sql );
/** /**
* Creates a statement from an SQL char string. * Creates a statement from an SQL char string.
@@ -450,7 +458,7 @@ gint gnc_sql_execute_nonselect_sql( const GncSqlBackend* be, gchar* sql );
* @param sql SQL char string * @param sql SQL char string
* @return Statement * @return Statement
*/ */
GncSqlStatement* gnc_sql_create_statement_from_sql( const GncSqlBackend* be, gchar* sql ); GncSqlStatement* gnc_sql_create_statement_from_sql( GncSqlBackend* be, gchar* sql );
/** /**
* Loads a Gnucash object from the database. * Loads a Gnucash object from the database.
@@ -497,7 +505,7 @@ gint gnc_sql_get_table_version( const GncSqlBackend* be, const gchar* table_name
* @param table_version Table version * @param table_version Table version
* @return TRUE if successful, FALSE if unsuccessful * @return TRUE if successful, FALSE if unsuccessful
*/ */
gboolean gnc_sql_set_table_version( const GncSqlBackend* be, gboolean gnc_sql_set_table_version( GncSqlBackend* be,
const gchar* table_name, const gchar* table_name,
gint table_version ); gint table_version );
@@ -510,7 +518,7 @@ gboolean gnc_sql_set_table_version( const GncSqlBackend* be,
* @param col_table DB table description * @param col_table DB table description
* @return TRUE if successful, FALSE if unsuccessful * @return TRUE if successful, FALSE if unsuccessful
*/ */
gboolean gnc_sql_create_table( const GncSqlBackend* be, gboolean gnc_sql_create_table( GncSqlBackend* be,
const gchar* table_name, const gchar* table_name,
gint table_version, gint table_version,
const GncSqlColumnTableEntry* col_table ); const GncSqlColumnTableEntry* col_table );
@@ -535,8 +543,9 @@ gboolean gnc_sql_create_temp_table( const GncSqlBackend* be,
* @param index_name Index name * @param index_name Index name
* @param table_name Table name * @param table_name Table name
* @param col_table Columns that the index should index * @param col_table Columns that the index should index
* @return TRUE if successful, FALSE if unsuccessful
*/ */
void gnc_sql_create_index( const GncSqlBackend* be, const gchar* index_name, gboolean gnc_sql_create_index( const GncSqlBackend* be, const gchar* index_name,
const gchar* table_name, const GncSqlColumnTableEntry* col_table ); const gchar* table_name, const GncSqlColumnTableEntry* col_table );
/** /**
@@ -566,7 +575,7 @@ const GUID* gnc_sql_load_tx_guid( const GncSqlBackend* be, GncSqlRow* row );
* @param table_name Table name * @param table_name Table name
* @return Statement * @return Statement
*/ */
GncSqlStatement* gnc_sql_create_select_statement( const GncSqlBackend* be, GncSqlStatement* gnc_sql_create_select_statement( GncSqlBackend* be,
const gchar* table_name ); const gchar* table_name );
/** /**
@@ -656,8 +665,9 @@ void gnc_sql_finalize_version_info( GncSqlBackend* be );
* @param tableName SQL table name * @param tableName SQL table name
* @param obj_name QOF object type name * @param obj_name QOF object type name
* @param col_table Column table * @param col_table Column table
* @return TRUE if successful, FALSE if not
*/ */
void gnc_sql_commit_standard_item( GncSqlBackend* be, QofInstance* inst, const gchar* tableName, gboolean gnc_sql_commit_standard_item( GncSqlBackend* be, QofInstance* inst, const gchar* tableName,
QofIdTypeConst obj_name, const GncSqlColumnTableEntry* col_table ); QofIdTypeConst obj_name, const GncSqlColumnTableEntry* col_table );
void _retrieve_guid_( gpointer pObject, gpointer pValue ); void _retrieve_guid_( gpointer pObject, gpointer pValue );

View File

@@ -190,18 +190,18 @@ create_book_tables( GncSqlBackend* be )
} }
/* ================================================================= */ /* ================================================================= */
void gboolean
gnc_sql_save_book( GncSqlBackend* be, QofInstance* inst) gnc_sql_save_book( GncSqlBackend* be, QofInstance* inst)
{ {
const GUID* guid; const GUID* guid;
gint op; gint op;
gboolean is_infant; gboolean is_infant;
g_return_if_fail( be != NULL ); g_return_val_if_fail( be != NULL, FALSE );
g_return_if_fail( inst != NULL ); g_return_val_if_fail( inst != NULL, FALSE );
g_return_if_fail( QOF_IS_BOOK(inst) ); g_return_val_if_fail( QOF_IS_BOOK(inst), FALSE );
gnc_sql_commit_standard_item( be, inst, BOOK_TABLE, GNC_ID_BOOK, col_table ); return gnc_sql_commit_standard_item( be, inst, BOOK_TABLE, GNC_ID_BOOK, col_table );
} }
/* ================================================================= */ /* ================================================================= */

View File

@@ -33,6 +33,6 @@
#include <gmodule.h> #include <gmodule.h>
void gnc_sql_init_book_handler( void ); void gnc_sql_init_book_handler( void );
void gnc_sql_save_book( GncSqlBackend* be, QofInstance* inst ); gboolean gnc_sql_save_book( GncSqlBackend* be, QofInstance* inst );
#endif /* GNC_BOOK_SQL_H_ */ #endif /* GNC_BOOK_SQL_H_ */

View File

@@ -135,17 +135,18 @@ create_budget_tables( GncSqlBackend* be )
} }
/* ================================================================= */ /* ================================================================= */
static void static gboolean
save_budget( GncSqlBackend* be, QofInstance* inst ) save_budget( GncSqlBackend* be, QofInstance* inst )
{ {
GncBudget* pBudget = GNC_BUDGET(inst); GncBudget* pBudget = GNC_BUDGET(inst);
const GUID* guid; const GUID* guid;
gint op; gint op;
gboolean is_infant; gboolean is_infant;
gboolean is_ok;
g_return_if_fail( be != NULL ); g_return_val_if_fail( be != NULL, FALSE );
g_return_if_fail( inst != NULL ); g_return_val_if_fail( inst != NULL, FALSE );
g_return_if_fail( GNC_IS_BUDGET(inst) ); g_return_val_if_fail( GNC_IS_BUDGET(inst), FALSE );
is_infant = qof_instance_get_infant( inst ); is_infant = qof_instance_get_infant( inst );
if( qof_instance_get_destroying( inst ) ) { if( qof_instance_get_destroying( inst ) ) {
@@ -155,32 +156,55 @@ save_budget( GncSqlBackend* be, QofInstance* inst )
} else { } else {
op = OP_DB_UPDATE; op = OP_DB_UPDATE;
} }
(void)gnc_sql_do_db_operation( be, op, BUDGET_TABLE, GNC_ID_BUDGET, pBudget, col_table ); is_ok = gnc_sql_do_db_operation( be, op, BUDGET_TABLE, GNC_ID_BUDGET, pBudget, col_table );
// Now, commit any slots and recurrence // Now, commit any slots and recurrence
guid = qof_instance_get_guid( inst ); if( is_ok ) {
if( !qof_instance_get_destroying(inst) ) { guid = qof_instance_get_guid( inst );
gnc_sql_recurrence_save( be, guid, gnc_budget_get_recurrence( pBudget ) ); if( !qof_instance_get_destroying(inst) ) {
gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) ); is_ok = gnc_sql_recurrence_save( be, guid, gnc_budget_get_recurrence( pBudget ) );
} else { if( is_ok ) {
gnc_sql_recurrence_delete( be, guid ); is_ok = gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
gnc_sql_slots_delete( be, guid ); }
} } else {
is_ok = gnc_sql_recurrence_delete( be, guid );
if( is_ok ) {
gnc_sql_slots_delete( be, guid );
}
}
}
return is_ok;
} }
typedef struct {
GncSqlBackend* be;
gboolean is_ok;
} write_objects_t;
static void static void
do_save_budget( QofInstance* inst, gpointer data ) do_save_budget( QofInstance* inst, gpointer data )
{ {
save_budget( (GncSqlBackend*)data, inst ); write_objects_t* s = (write_objects_t*)data;
if( s->is_ok ) {
s->is_ok = save_budget( s->be, inst );
}
} }
static void static gboolean
write_budgets( GncSqlBackend* be ) write_budgets( GncSqlBackend* be )
{ {
g_return_if_fail( be != NULL ); write_objects_t data;
g_return_val_if_fail( be != NULL, FALSE );
data.be = be;
data.is_ok = TRUE;
qof_collection_foreach( qof_book_get_collection( be->primary_book, GNC_ID_BUDGET ), qof_collection_foreach( qof_book_get_collection( be->primary_book, GNC_ID_BUDGET ),
(QofInstanceForeachCB)do_save_budget, be ); (QofInstanceForeachCB)do_save_budget, &data );
return data.is_ok;
} }
/* ================================================================= */ /* ================================================================= */

View File

@@ -169,16 +169,16 @@ create_commodities_tables( GncSqlBackend* be )
} }
/* ================================================================= */ /* ================================================================= */
static void static gboolean
commit_commodity( GncSqlBackend* be, QofInstance* inst ) commit_commodity( GncSqlBackend* be, QofInstance* inst )
{ {
const GUID* guid; const GUID* guid;
g_return_if_fail( be != NULL ); g_return_val_if_fail( be != NULL, FALSE );
g_return_if_fail( inst != NULL ); g_return_val_if_fail( inst != NULL, FALSE );
g_return_if_fail( GNC_IS_COMMODITY(inst) ); g_return_val_if_fail( GNC_IS_COMMODITY(inst), FALSE );
gnc_sql_commit_standard_item( be, inst, COMMODITIES_TABLE, GNC_ID_COMMODITY, col_table ); return gnc_sql_commit_standard_item( be, inst, COMMODITIES_TABLE, GNC_ID_COMMODITY, col_table );
} }
static gboolean static gboolean
@@ -191,15 +191,19 @@ is_commodity_in_db( GncSqlBackend* be, gnc_commodity* pCommodity )
pCommodity, col_table ); pCommodity, col_table );
} }
void gboolean
gnc_sql_save_commodity( GncSqlBackend* be, gnc_commodity* pCommodity ) gnc_sql_save_commodity( GncSqlBackend* be, gnc_commodity* pCommodity )
{ {
g_return_if_fail( be != NULL ); gboolean is_ok = TRUE;
g_return_if_fail( pCommodity != NULL );
g_return_val_if_fail( be != NULL, FALSE );
g_return_val_if_fail( pCommodity != NULL, FALSE );
if( !is_commodity_in_db( be, pCommodity ) ) { if( !is_commodity_in_db( be, pCommodity ) ) {
commit_commodity( be, QOF_INSTANCE(pCommodity) ); is_ok = commit_commodity( be, QOF_INSTANCE(pCommodity) );
} }
return is_ok;
} }
/* ----------------------------------------------------------------- */ /* ----------------------------------------------------------------- */

View File

@@ -33,6 +33,6 @@
#include <gmodule.h> #include <gmodule.h>
void gnc_sql_init_commodity_handler( void ); void gnc_sql_init_commodity_handler( void );
void gnc_sql_save_commodity( GncSqlBackend* be, gnc_commodity* pCommodity ); gboolean gnc_sql_save_commodity( GncSqlBackend* be, gnc_commodity* pCommodity );
#endif /* GNC_COMMODITY_SQL_H_ */ #endif /* GNC_COMMODITY_SQL_H_ */

View File

@@ -187,29 +187,43 @@ create_lots_tables( GncSqlBackend* be )
/* ================================================================= */ /* ================================================================= */
static void static gboolean
commit_lot( GncSqlBackend* be, QofInstance* inst ) commit_lot( GncSqlBackend* be, QofInstance* inst )
{ {
g_return_if_fail( be != NULL ); g_return_val_if_fail( be != NULL, FALSE );
g_return_if_fail( inst != NULL ); g_return_val_if_fail( inst != NULL, FALSE );
g_return_if_fail( GNC_IS_LOT(inst) ); g_return_val_if_fail( GNC_IS_LOT(inst), FALSE );
gnc_sql_commit_standard_item( be, inst, TABLE_NAME, GNC_ID_LOT, col_table ); return gnc_sql_commit_standard_item( be, inst, TABLE_NAME, GNC_ID_LOT, col_table );
} }
typedef struct {
GncSqlBackend* be;
gboolean is_ok;
} write_objects_t;
static void static void
do_save_lot( QofInstance* inst, gpointer data ) do_save_lot( QofInstance* inst, gpointer data )
{ {
commit_lot( (GncSqlBackend*)data, inst ); write_objects_t* s = (write_objects_t*)data;
if( s->is_ok ) {
s->is_ok = commit_lot( s->be, inst );
}
} }
static void static gboolean
write_lots( GncSqlBackend* be ) write_lots( GncSqlBackend* be )
{ {
g_return_if_fail( be != NULL ); write_objects_t data;
g_return_val_if_fail( be != NULL, FALSE );
data.be = be;
data.is_ok = TRUE;
qof_collection_foreach( qof_book_get_collection( be->primary_book, GNC_ID_LOT ), qof_collection_foreach( qof_book_get_collection( be->primary_book, GNC_ID_LOT ),
(QofInstanceForeachCB)do_save_lot, be ); (QofInstanceForeachCB)do_save_lot, &data );
return data.is_ok;
} }
/* ================================================================= */ /* ================================================================= */

View File

@@ -132,16 +132,17 @@ create_prices_tables( GncSqlBackend* be )
/* ================================================================= */ /* ================================================================= */
static void static gboolean
save_price( GncSqlBackend* be, QofInstance* inst ) save_price( GncSqlBackend* be, QofInstance* inst )
{ {
GNCPrice* pPrice = GNC_PRICE(inst); GNCPrice* pPrice = GNC_PRICE(inst);
gint op; gint op;
gboolean is_infant; gboolean is_infant;
gboolean is_ok;
g_return_if_fail( be != NULL ); g_return_val_if_fail( be != NULL, FALSE );
g_return_if_fail( inst != NULL ); g_return_val_if_fail( inst != NULL, FALSE );
g_return_if_fail( GNC_IS_PRICE(inst) ); g_return_val_if_fail( GNC_IS_PRICE(inst), FALSE );
is_infant = qof_instance_get_infant( inst ); is_infant = qof_instance_get_infant( inst );
if( qof_instance_get_destroying( inst ) ) { if( qof_instance_get_destroying( inst ) ) {
@@ -155,35 +156,49 @@ save_price( GncSqlBackend* be, QofInstance* inst )
if( op != OP_DB_DELETE ) { if( op != OP_DB_DELETE ) {
/* Ensure commodity and currency are in the db */ /* Ensure commodity and currency are in the db */
gnc_sql_save_commodity( be, gnc_price_get_commodity( pPrice ) ); gnc_sql_save_commodity( be, gnc_price_get_commodity( pPrice ) );
gnc_sql_save_commodity( be, gnc_price_get_currency( pPrice ) ); is_ok = gnc_sql_save_commodity( be, gnc_price_get_currency( pPrice ) );
} }
(void)gnc_sql_do_db_operation( be, op, TABLE_NAME, GNC_ID_PRICE, pPrice, col_table ); if( is_ok ) {
is_ok = gnc_sql_do_db_operation( be, op, TABLE_NAME, GNC_ID_PRICE, pPrice, col_table );
}
return is_ok;
} }
typedef struct {
GncSqlBackend* be;
gboolean is_ok;
} write_objects_t;
static gboolean static gboolean
write_price( GNCPrice* p, gpointer data ) write_price( GNCPrice* p, gpointer data )
{ {
GncSqlBackend* be = (GncSqlBackend*)data; write_objects_t* s = (write_objects_t*)data;
g_return_val_if_fail( p != NULL, FALSE ); g_return_val_if_fail( p != NULL, FALSE );
g_return_val_if_fail( data != NULL, FALSE ); g_return_val_if_fail( data != NULL, FALSE );
save_price( be, QOF_INSTANCE(p) ); if( s->is_ok ) {
s->is_ok = save_price( s->be, QOF_INSTANCE(p) );
}
return TRUE; return s->is_ok;
} }
static void static gboolean
write_prices( GncSqlBackend* be ) write_prices( GncSqlBackend* be )
{ {
GNCPriceDB* priceDB; GNCPriceDB* priceDB;
write_objects_t data;
g_return_if_fail( be != NULL ); g_return_val_if_fail( be != NULL, FALSE );
priceDB = gnc_book_get_pricedb( be->primary_book ); priceDB = gnc_book_get_pricedb( be->primary_book );
gnc_pricedb_foreach_price( priceDB, write_price, be, TRUE ); data.be = be;
data.is_ok = TRUE;
return gnc_pricedb_foreach_price( priceDB, write_price, &data, TRUE );
} }
/* ================================================================= */ /* ================================================================= */

View File

@@ -173,21 +173,21 @@ set_recurrence_period_start( gpointer pObject, gpointer pValue )
/* ================================================================= */ /* ================================================================= */
void gboolean
gnc_sql_recurrence_save( GncSqlBackend* be, const GUID* guid, const Recurrence* r ) gnc_sql_recurrence_save( GncSqlBackend* be, const GUID* guid, const Recurrence* r )
{ {
recurrence_info_t recurrence_info; recurrence_info_t recurrence_info;
g_return_if_fail( be != NULL ); g_return_val_if_fail( be != NULL, FALSE );
g_return_if_fail( guid != NULL ); g_return_val_if_fail( guid != NULL, FALSE );
g_return_if_fail( r != NULL ); g_return_val_if_fail( r != NULL, FALSE );
gnc_sql_recurrence_delete( be, guid ); gnc_sql_recurrence_delete( be, guid );
recurrence_info.be = be; recurrence_info.be = be;
recurrence_info.guid = guid; recurrence_info.guid = guid;
recurrence_info.pRecurrence = (Recurrence*)r; recurrence_info.pRecurrence = (Recurrence*)r;
(void)gnc_sql_do_db_operation( be, OP_DB_INSERT, TABLE_NAME, return gnc_sql_do_db_operation( be, OP_DB_INSERT, TABLE_NAME,
TABLE_NAME, &recurrence_info, col_table ); TABLE_NAME, &recurrence_info, col_table );
} }
@@ -211,17 +211,17 @@ gnc_sql_recurrence_save_list( GncSqlBackend* be, const GUID* guid, GList* schedu
} }
} }
void gboolean
gnc_sql_recurrence_delete( GncSqlBackend* be, const GUID* guid ) gnc_sql_recurrence_delete( GncSqlBackend* be, const GUID* guid )
{ {
recurrence_info_t recurrence_info; recurrence_info_t recurrence_info;
g_return_if_fail( be != NULL ); g_return_val_if_fail( be != NULL, FALSE );
g_return_if_fail( guid != NULL ); g_return_val_if_fail( guid != NULL, FALSE );
recurrence_info.be = be; recurrence_info.be = be;
recurrence_info.guid = guid; recurrence_info.guid = guid;
(void)gnc_sql_do_db_operation( be, OP_DB_DELETE, TABLE_NAME, return gnc_sql_do_db_operation( be, OP_DB_DELETE, TABLE_NAME,
TABLE_NAME, &recurrence_info, guid_col_table ); TABLE_NAME, &recurrence_info, guid_col_table );
} }

View File

@@ -32,9 +32,9 @@
#include "qof.h" #include "qof.h"
#include <gmodule.h> #include <gmodule.h>
void gnc_sql_recurrence_save( GncSqlBackend* be, const GUID* guid, const Recurrence* pRecurrence ); gboolean gnc_sql_recurrence_save( GncSqlBackend* be, const GUID* guid, const Recurrence* pRecurrence );
void gnc_sql_recurrence_save_list( GncSqlBackend* be, const GUID* guid, GList* schedule ); void gnc_sql_recurrence_save_list( GncSqlBackend* be, const GUID* guid, GList* schedule );
void gnc_sql_recurrence_delete( GncSqlBackend* be, const GUID* guid ); gboolean gnc_sql_recurrence_delete( GncSqlBackend* be, const GUID* guid );
void gnc_sql_recurrence_load( GncSqlBackend* be, const GUID* guid, Recurrence* pRecurrence ); void gnc_sql_recurrence_load( GncSqlBackend* be, const GUID* guid, Recurrence* pRecurrence );
void gnc_sql_recurrence_load_list( GncSqlBackend* be, const GUID* guid, GList** pSchedule ); void gnc_sql_recurrence_load_list( GncSqlBackend* be, const GUID* guid, GList** pSchedule );

View File

@@ -260,17 +260,18 @@ create_sx_tables( GncSqlBackend* be )
} }
/* ================================================================= */ /* ================================================================= */
void gboolean
gnc_sql_save_schedxaction( GncSqlBackend* be, QofInstance* inst ) gnc_sql_save_schedxaction( GncSqlBackend* be, QofInstance* inst )
{ {
SchedXaction* pSx; SchedXaction* pSx;
const GUID* guid; const GUID* guid;
gint op; gint op;
gboolean is_infant; gboolean is_infant;
gboolean is_ok;
g_return_if_fail( be != NULL ); g_return_val_if_fail( be != NULL, FALSE );
g_return_if_fail( inst != NULL ); g_return_val_if_fail( inst != NULL, FALSE );
g_return_if_fail( GNC_IS_SX(inst) ); g_return_val_if_fail( GNC_IS_SX(inst), FALSE );
pSx = GNC_SX(inst); pSx = GNC_SX(inst);
@@ -282,16 +283,20 @@ gnc_sql_save_schedxaction( GncSqlBackend* be, QofInstance* inst )
} else { } else {
op = OP_DB_UPDATE; op = OP_DB_UPDATE;
} }
(void)gnc_sql_do_db_operation( be, op, SCHEDXACTION_TABLE, GNC_SX_ID, pSx, col_table ); is_ok = gnc_sql_do_db_operation( be, op, SCHEDXACTION_TABLE, GNC_SX_ID, pSx, col_table );
guid = qof_instance_get_guid( inst ); guid = qof_instance_get_guid( inst );
gnc_sql_recurrence_save_list( be, guid, gnc_sx_get_schedule( pSx ) ); gnc_sql_recurrence_save_list( be, guid, gnc_sx_get_schedule( pSx ) );
// Now, commit any slots if( is_ok ) {
if( !qof_instance_get_destroying(inst) ) { // Now, commit any slots
gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) ); if( !qof_instance_get_destroying(inst) ) {
} else { is_ok = gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
gnc_sql_slots_delete( be, guid ); } else {
} is_ok = gnc_sql_slots_delete( be, guid );
}
}
return is_ok;
} }
/* ================================================================= */ /* ================================================================= */

View File

@@ -33,6 +33,6 @@
#include <gmodule.h> #include <gmodule.h>
void gnc_sql_init_schedxaction_handler( void ); void gnc_sql_init_schedxaction_handler( void );
void gnc_sql_save_schedxaction( GncSqlBackend* be, QofInstance* inst ); gboolean gnc_sql_save_schedxaction( GncSqlBackend* be, QofInstance* inst );
#endif /* GNC_SCHEDXACTION_SQL_H_ */ #endif /* GNC_SCHEDXACTION_SQL_H_ */

View File

@@ -45,6 +45,7 @@ static QofLogModule log_module = G_LOG_DOMAIN;
typedef struct { typedef struct {
GncSqlBackend* be; GncSqlBackend* be;
const GUID* guid; const GUID* guid;
gboolean is_ok;
KvpFrame* pKvpFrame; KvpFrame* pKvpFrame;
KvpValueType value_type; KvpValueType value_type;
KvpValue* pKvpValue; KvpValue* pKvpValue;
@@ -324,11 +325,17 @@ save_slot( const gchar* key, KvpValue* value, gpointer data )
{ {
slot_info_t* pSlot_info = (slot_info_t*)data; slot_info_t* pSlot_info = (slot_info_t*)data;
gint curlen; gint curlen;
gboolean is_ok = FALSE;
g_return_if_fail( key != NULL ); g_return_if_fail( key != NULL );
g_return_if_fail( value != NULL ); g_return_if_fail( value != NULL );
g_return_if_fail( data != NULL ); g_return_if_fail( data != NULL );
// Ignore if we've already run into a failure
if( !pSlot_info->is_ok ) {
return;
}
curlen = pSlot_info->path->len; curlen = pSlot_info->path->len;
pSlot_info->pKvpValue = value; pSlot_info->pKvpValue = value;
if( curlen != 0 ) { if( curlen != 0 ) {
@@ -340,21 +347,23 @@ save_slot( const gchar* key, KvpValue* value, gpointer data )
KvpFrame* pKvpFrame = kvp_value_get_frame( value ); KvpFrame* pKvpFrame = kvp_value_get_frame( value );
kvp_frame_for_each_slot( pKvpFrame, save_slot, pSlot_info ); kvp_frame_for_each_slot( pKvpFrame, save_slot, pSlot_info );
} else { } else {
(void)gnc_sql_do_db_operation( pSlot_info->be, OP_DB_INSERT, TABLE_NAME, pSlot_info->is_ok = gnc_sql_do_db_operation( pSlot_info->be,
TABLE_NAME, pSlot_info, col_table ); OP_DB_INSERT, TABLE_NAME,
TABLE_NAME, pSlot_info,
col_table );
} }
g_string_truncate( pSlot_info->path, curlen ); g_string_truncate( pSlot_info->path, curlen );
} }
void gboolean
gnc_sql_slots_save( GncSqlBackend* be, const GUID* guid, gboolean is_infant, KvpFrame* pFrame ) gnc_sql_slots_save( GncSqlBackend* be, const GUID* guid, gboolean is_infant, KvpFrame* pFrame )
{ {
slot_info_t slot_info; slot_info_t slot_info;
g_return_if_fail( be != NULL ); g_return_val_if_fail( be != NULL, FALSE );
g_return_if_fail( guid != NULL ); g_return_val_if_fail( guid != NULL, FALSE );
g_return_if_fail( pFrame != NULL ); g_return_val_if_fail( pFrame != NULL, FALSE );
// If this is not saving into a new db, clear out the old saved slots first // If this is not saving into a new db, clear out the old saved slots first
if( !be->is_pristine_db && !is_infant ) { if( !be->is_pristine_db && !is_infant ) {
@@ -364,22 +373,28 @@ gnc_sql_slots_save( GncSqlBackend* be, const GUID* guid, gboolean is_infant, Kvp
slot_info.be = be; slot_info.be = be;
slot_info.guid = guid; slot_info.guid = guid;
slot_info.path = g_string_new( "" ); slot_info.path = g_string_new( "" );
slot_info.is_ok = TRUE;
kvp_frame_for_each_slot( pFrame, save_slot, &slot_info ); kvp_frame_for_each_slot( pFrame, save_slot, &slot_info );
g_string_free( slot_info.path, TRUE ); g_string_free( slot_info.path, TRUE );
return slot_info.is_ok;
} }
void gboolean
gnc_sql_slots_delete( GncSqlBackend* be, const GUID* guid ) gnc_sql_slots_delete( GncSqlBackend* be, const GUID* guid )
{ {
slot_info_t slot_info; slot_info_t slot_info;
g_return_if_fail( be != NULL ); g_return_val_if_fail( be != NULL, FALSE );
g_return_if_fail( guid != NULL ); g_return_val_if_fail( guid != NULL, FALSE );
slot_info.be = be; slot_info.be = be;
slot_info.guid = guid; slot_info.guid = guid;
(void)gnc_sql_do_db_operation( be, OP_DB_DELETE, TABLE_NAME, 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 ); TABLE_NAME, &slot_info, obj_guid_col_table );
return slot_info.is_ok;
} }
static void static void

View File

@@ -33,14 +33,15 @@
#include <gmodule.h> #include <gmodule.h>
/** /**
* gnc_sql_slots_save - Saves slots for an object to the db. * gnc_sql_slots_save - Saves slots for an object to the db.
* *
* @param be SQL backend * @param be SQL backend
* @param guid Object guid * @param guid Object guid
* @param is_infant Is this an infant object? * @param is_infant Is this an infant object?
* @param pFrame Top-level KVP frame * @param pFrame Top-level KVP frame
*/ * @return TRUE if successful, FALSE if error
void gnc_sql_slots_save( GncSqlBackend* be, const GUID* guid, */
gboolean gnc_sql_slots_save( GncSqlBackend* be, const GUID* guid,
gboolean is_infant, KvpFrame* pFrame ); gboolean is_infant, KvpFrame* pFrame );
/** /**
@@ -48,8 +49,9 @@ void gnc_sql_slots_save( GncSqlBackend* be, const GUID* guid,
* *
* @param be SQL backend * @param be SQL backend
* @param guid Object guid * @param guid Object guid
* @return TRUE if successful, FALSE if error
*/ */
void gnc_sql_slots_delete( GncSqlBackend* be, const GUID* guid ); gboolean gnc_sql_slots_delete( GncSqlBackend* be, const GUID* guid );
/** /**
* gnc_sql_slots_load - Loads slots for an object from the db. * gnc_sql_slots_load - Loads slots for an object from the db.

View File

@@ -57,6 +57,7 @@ static QofLogModule log_module = G_LOG_DOMAIN;
typedef struct { typedef struct {
GncSqlBackend* be; GncSqlBackend* be;
const GUID* guid; const GUID* guid;
gboolean is_ok;
} split_info_t; } split_info_t;
#define TX_MAX_NUM_LEN 2048 #define TX_MAX_NUM_LEN 2048
@@ -439,33 +440,41 @@ delete_split_slots_cb( gpointer data, gpointer user_data )
g_return_if_fail( GNC_IS_SPLIT(data) ); g_return_if_fail( GNC_IS_SPLIT(data) );
g_return_if_fail( user_data != NULL ); g_return_if_fail( user_data != NULL );
gnc_sql_slots_delete( split_info->be, if( split_info->is_ok ) {
qof_instance_get_guid( QOF_INSTANCE(pSplit) ) ); split_info->is_ok = gnc_sql_slots_delete( split_info->be,
qof_instance_get_guid( QOF_INSTANCE(pSplit) ) );
}
} }
static void static gboolean
delete_splits( GncSqlBackend* be, Transaction* pTx ) delete_splits( GncSqlBackend* be, Transaction* pTx )
{ {
split_info_t split_info; split_info_t split_info;
g_return_if_fail( be != NULL ); g_return_val_if_fail( be != NULL, FALSE );
g_return_if_fail( pTx != NULL ); g_return_val_if_fail( pTx != NULL, FALSE );
(void)gnc_sql_do_db_operation( be, OP_DB_DELETE, SPLIT_TABLE, if( !gnc_sql_do_db_operation( be, OP_DB_DELETE, SPLIT_TABLE,
SPLIT_TABLE, pTx, guid_col_table ); SPLIT_TABLE, pTx, guid_col_table ) ) {
return FALSE;
}
split_info.be = be; split_info.be = be;
split_info.is_ok = TRUE;
g_list_foreach( xaccTransGetSplitList( pTx ), delete_split_slots_cb, &split_info ); g_list_foreach( xaccTransGetSplitList( pTx ), delete_split_slots_cb, &split_info );
return split_info.is_ok;
} }
static void static gboolean
commit_split( GncSqlBackend* be, QofInstance* inst ) commit_split( GncSqlBackend* be, QofInstance* inst )
{ {
gint op; gint op;
gboolean is_infant; gboolean is_infant;
gboolean is_ok;
g_return_if_fail( inst != NULL ); g_return_val_if_fail( inst != NULL, FALSE );
g_return_if_fail( be != NULL ); g_return_val_if_fail( be != NULL, FALSE );
is_infant = qof_instance_get_infant( inst ); is_infant = qof_instance_get_infant( inst );
if( qof_instance_get_destroying( inst ) ) { if( qof_instance_get_destroying( inst ) ) {
@@ -475,11 +484,15 @@ commit_split( GncSqlBackend* be, QofInstance* inst )
} else { } else {
op = OP_DB_UPDATE; op = OP_DB_UPDATE;
} }
(void)gnc_sql_do_db_operation( be, op, SPLIT_TABLE, GNC_ID_SPLIT, inst, split_col_table ); is_ok = gnc_sql_do_db_operation( be, op, SPLIT_TABLE, GNC_ID_SPLIT, inst, split_col_table );
gnc_sql_slots_save( be, if( is_ok ) {
is_ok = gnc_sql_slots_save( be,
qof_instance_get_guid( inst ), qof_instance_get_guid( inst ),
is_infant, is_infant,
qof_instance_get_slots( inst ) ); qof_instance_get_slots( inst ) );
}
return is_ok;
} }
static void static void
@@ -492,33 +505,39 @@ save_split_cb( gpointer data, gpointer user_data )
g_return_if_fail( GNC_IS_SPLIT(data) ); g_return_if_fail( GNC_IS_SPLIT(data) );
g_return_if_fail( user_data != NULL ); g_return_if_fail( user_data != NULL );
commit_split( split_info->be, QOF_INSTANCE(pSplit) ); if( split_info->is_ok ) {
split_info->is_ok = commit_split( split_info->be, QOF_INSTANCE(pSplit) );
}
} }
static void static gboolean
save_splits( GncSqlBackend* be, const GUID* tx_guid, SplitList* pSplitList ) save_splits( GncSqlBackend* be, const GUID* tx_guid, SplitList* pSplitList )
{ {
split_info_t split_info; split_info_t split_info;
g_return_if_fail( be != NULL ); g_return_val_if_fail( be != NULL, FALSE );
g_return_if_fail( tx_guid != NULL ); g_return_val_if_fail( tx_guid != NULL, FALSE );
g_return_if_fail( pSplitList != NULL ); g_return_val_if_fail( pSplitList != NULL, FALSE );
split_info.be = be; split_info.be = be;
split_info.guid = tx_guid; split_info.guid = tx_guid;
split_info.is_ok = TRUE;
g_list_foreach( pSplitList, save_split_cb, &split_info ); g_list_foreach( pSplitList, save_split_cb, &split_info );
return split_info.is_ok;
} }
static void static gboolean
save_transaction( GncSqlBackend* be, Transaction* pTx, gboolean do_save_splits ) save_transaction( GncSqlBackend* be, Transaction* pTx, gboolean do_save_splits )
{ {
const GUID* guid; const GUID* guid;
gint op; gint op;
gboolean is_infant; gboolean is_infant;
QofInstance* inst; QofInstance* inst;
gboolean is_ok = TRUE;
g_return_if_fail( be != NULL ); g_return_val_if_fail( be != NULL, FALSE );
g_return_if_fail( pTx != NULL ); g_return_val_if_fail( pTx != NULL, FALSE );
inst = QOF_INSTANCE(pTx); inst = QOF_INSTANCE(pTx);
is_infant = qof_instance_get_infant( inst ); is_infant = qof_instance_get_infant( inst );
@@ -532,42 +551,50 @@ save_transaction( GncSqlBackend* be, Transaction* pTx, gboolean do_save_splits )
if( op != OP_DB_DELETE ) { if( op != OP_DB_DELETE ) {
// Ensure the commodity is in the db // Ensure the commodity is in the db
gnc_sql_save_commodity( be, xaccTransGetCurrency( pTx ) ); is_ok = gnc_sql_save_commodity( be, xaccTransGetCurrency( pTx ) );
} }
(void)gnc_sql_do_db_operation( be, op, TRANSACTION_TABLE, GNC_ID_TRANS, pTx, tx_col_table ); if( is_ok ) {
is_ok = gnc_sql_do_db_operation( be, op, TRANSACTION_TABLE, GNC_ID_TRANS, pTx, tx_col_table );
}
// Commit slots and splits if( is_ok ) {
guid = qof_instance_get_guid( inst ); // Commit slots and splits
if( !qof_instance_get_destroying(inst) ) { guid = qof_instance_get_guid( inst );
gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) ); if( !qof_instance_get_destroying(inst) ) {
if( do_save_splits ) { is_ok = gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
save_splits( be, guid, xaccTransGetSplitList( pTx ) ); if( is_ok && do_save_splits ) {
} is_ok = save_splits( be, guid, xaccTransGetSplitList( pTx ) );
} else { }
gnc_sql_slots_delete( be, guid ); } else {
delete_splits( be, pTx ); is_ok = gnc_sql_slots_delete( be, guid );
} if( is_ok ) {
is_ok = delete_splits( be, pTx );
}
}
}
return is_ok;
} }
void gboolean
gnc_sql_save_transaction( GncSqlBackend* be, QofInstance* inst ) gnc_sql_save_transaction( GncSqlBackend* be, QofInstance* inst )
{ {
g_return_if_fail( be != NULL ); g_return_val_if_fail( be != NULL, FALSE );
g_return_if_fail( inst != NULL ); g_return_val_if_fail( inst != NULL, FALSE );
g_return_if_fail( GNC_IS_TRANS(inst) ); g_return_val_if_fail( GNC_IS_TRANS(inst), FALSE );
save_transaction( be, GNC_TRANS(inst), TRUE ); return save_transaction( be, GNC_TRANS(inst), TRUE );
} }
static void static gboolean
commit_transaction( GncSqlBackend* be, QofInstance* inst ) commit_transaction( GncSqlBackend* be, QofInstance* inst )
{ {
g_return_if_fail( be != NULL ); g_return_val_if_fail( be != NULL, FALSE );
g_return_if_fail( inst != NULL ); g_return_val_if_fail( inst != NULL, FALSE );
g_return_if_fail( GNC_IS_TRANS(inst) ); g_return_val_if_fail( GNC_IS_TRANS(inst), FALSE );
save_transaction( be, GNC_TRANS(inst), FALSE ); return save_transaction( be, GNC_TRANS(inst), FALSE );
} }
/* ================================================================= */ /* ================================================================= */

View File

@@ -34,7 +34,7 @@
void gnc_sql_init_transaction_handler( void ); void gnc_sql_init_transaction_handler( void );
void gnc_sql_transaction_commit_splits( GncSqlBackend* be, Transaction* pTx ); void gnc_sql_transaction_commit_splits( GncSqlBackend* be, Transaction* pTx );
void gnc_sql_save_transaction( GncSqlBackend* be, QofInstance* inst ); gboolean gnc_sql_save_transaction( GncSqlBackend* be, QofInstance* inst );
void gnc_sql_get_account_balances( GncSqlBackend* be, Account* pAccount, void gnc_sql_get_account_balances( GncSqlBackend* be, Account* pAccount,
gnc_numeric* start_balance, gnc_numeric* start_balance,
gnc_numeric* cleared_balance, gnc_numeric* cleared_balance,

View File

@@ -143,18 +143,32 @@ load_all_billterms( GncSqlBackend* be )
} }
/* ================================================================= */ /* ================================================================= */
typedef struct {
GncSqlBackend* be;
gboolean is_ok;
} write_billterms_t;
static void static void
do_save_billterm( QofInstance* inst, gpointer p2 ) do_save_billterm( QofInstance* inst, gpointer p2 )
{ {
gnc_sql_save_billterm( (GncSqlBackend*)p2, inst ); write_billterms_t* data = (write_billterms_t*)p2;
if( data->is_ok ) {
data->is_ok = gnc_sql_save_billterm( data->be, inst );
}
} }
static void static gboolean
write_billterms( GncSqlBackend* be ) write_billterms( GncSqlBackend* be )
{ {
g_return_if_fail( be != NULL ); write_billterms_t data;
qof_object_foreach( GNC_ID_BILLTERM, be->primary_book, do_save_billterm, (gpointer)be ); g_return_val_if_fail( be != NULL, FALSE );
data.be = be;
data.is_ok = TRUE;
qof_object_foreach( GNC_ID_BILLTERM, be->primary_book, do_save_billterm, &data );
return data.is_ok;
} }
/* ================================================================= */ /* ================================================================= */
@@ -172,14 +186,14 @@ create_billterm_tables( GncSqlBackend* be )
} }
/* ================================================================= */ /* ================================================================= */
void gboolean
gnc_sql_save_billterm( GncSqlBackend* be, QofInstance* inst ) gnc_sql_save_billterm( GncSqlBackend* be, QofInstance* inst )
{ {
g_return_if_fail( inst != NULL ); g_return_val_if_fail( inst != NULL, FALSE );
g_return_if_fail( GNC_IS_BILLTERM(inst) ); g_return_val_if_fail( GNC_IS_BILLTERM(inst), FALSE );
g_return_if_fail( be != NULL ); g_return_val_if_fail( be != NULL, FALSE );
gnc_sql_commit_standard_item( be, inst, TABLE_NAME, GNC_ID_BILLTERM, col_table ); return gnc_sql_commit_standard_item( be, inst, TABLE_NAME, GNC_ID_BILLTERM, col_table );
} }
/* ================================================================= */ /* ================================================================= */

View File

@@ -35,6 +35,6 @@
#define CT_BILLTERMREF "billterm" #define CT_BILLTERMREF "billterm"
void gnc_billterm_sql_initialize( void ); void gnc_billterm_sql_initialize( void );
void gnc_sql_save_billterm( GncSqlBackend* be, QofInstance* inst ); gboolean gnc_sql_save_billterm( GncSqlBackend* be, QofInstance* inst );
#endif /* GNC_BILLTERM_SQL_H */ #endif /* GNC_BILLTERM_SQL_H */

View File

@@ -147,17 +147,22 @@ create_customer_tables( GncSqlBackend* be )
} }
/* ================================================================= */ /* ================================================================= */
static void static gboolean
save_customer( GncSqlBackend* be, QofInstance* inst ) save_customer( GncSqlBackend* be, QofInstance* inst )
{ {
g_return_if_fail( inst != NULL ); g_return_val_if_fail( inst != NULL, FALSE );
g_return_if_fail( GNC_CUSTOMER(inst) ); g_return_val_if_fail( GNC_CUSTOMER(inst), FALSE );
g_return_if_fail( be != NULL ); g_return_val_if_fail( be != NULL, FALSE );
gnc_sql_commit_standard_item( be, inst, TABLE_NAME, GNC_ID_CUSTOMER, col_table ); return gnc_sql_commit_standard_item( be, inst, TABLE_NAME, GNC_ID_CUSTOMER, col_table );
} }
/* ================================================================= */ /* ================================================================= */
typedef struct {
GncSqlBackend* be;
gboolean is_ok;
} write_customers_t;
static gboolean static gboolean
customer_should_be_saved( GncCustomer *customer ) customer_should_be_saved( GncCustomer *customer )
{ {
@@ -175,25 +180,30 @@ customer_should_be_saved( GncCustomer *customer )
} }
static void static void
write_single_customer( QofInstance *term_p, gpointer be_p ) write_single_customer( QofInstance *term_p, gpointer data_p )
{ {
GncSqlBackend* be = (GncSqlBackend*)be_p; write_customers_t* data = (write_customers_t*)data_p;
g_return_if_fail( term_p != NULL ); g_return_if_fail( term_p != NULL );
g_return_if_fail( GNC_IS_CUSTOMER(term_p) ); g_return_if_fail( GNC_IS_CUSTOMER(term_p) );
g_return_if_fail( be_p != NULL ); g_return_if_fail( data_p != NULL );
if( customer_should_be_saved( GNC_CUSTOMER(term_p) ) ) { if( customer_should_be_saved( GNC_CUSTOMER(term_p) ) && data->is_ok ) {
save_customer( be, term_p ); data->is_ok = save_customer( data->be, term_p );
} }
} }
static void static gboolean
write_customers( GncSqlBackend* be ) write_customers( GncSqlBackend* be )
{ {
g_return_if_fail( be != NULL ); write_customers_t data;
qof_object_foreach( GNC_ID_CUSTOMER, be->primary_book, write_single_customer, (gpointer)be ); g_return_val_if_fail( be != NULL, FALSE );
data.be = be;
data.is_ok = TRUE;
qof_object_foreach( GNC_ID_CUSTOMER, be->primary_book, write_single_customer, (gpointer)&data );
return data.is_ok;
} }
/* ================================================================= */ /* ================================================================= */

View File

@@ -144,17 +144,18 @@ create_employee_tables( GncSqlBackend* be )
} }
/* ================================================================= */ /* ================================================================= */
static void static gboolean
save_employee( GncSqlBackend* be, QofInstance* inst ) save_employee( GncSqlBackend* be, QofInstance* inst )
{ {
GncEmployee* emp; GncEmployee* emp;
const GUID* guid; const GUID* guid;
gint op; gint op;
gboolean is_infant; gboolean is_infant;
gboolean is_ok = TRUE;
g_return_if_fail( inst != NULL ); g_return_val_if_fail( inst != NULL, FALSE );
g_return_if_fail( GNC_IS_EMPLOYEE(inst) ); g_return_val_if_fail( GNC_IS_EMPLOYEE(inst), FALSE );
g_return_if_fail( be != NULL ); g_return_val_if_fail( be != NULL, FALSE );
emp = GNC_EMPLOYEE(inst); emp = GNC_EMPLOYEE(inst);
@@ -168,18 +169,24 @@ save_employee( GncSqlBackend* be, QofInstance* inst )
} }
if( op != OP_DB_DELETE ) { if( op != OP_DB_DELETE ) {
// Ensure the commodity is in the db // Ensure the commodity is in the db
gnc_sql_save_commodity( be, gncEmployeeGetCurrency( emp ) ); is_ok = gnc_sql_save_commodity( be, gncEmployeeGetCurrency( emp ) );
} }
(void)gnc_sql_do_db_operation( be, op, TABLE_NAME, GNC_ID_EMPLOYEE, emp, col_table ); if( is_ok ) {
is_ok = gnc_sql_do_db_operation( be, op, TABLE_NAME, GNC_ID_EMPLOYEE, emp, col_table );
}
// Now, commit or delete any slots if( is_ok ) {
guid = qof_instance_get_guid( inst ); // Now, commit or delete any slots
if( !qof_instance_get_destroying(inst) ) { guid = qof_instance_get_guid( inst );
gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) ); if( !qof_instance_get_destroying(inst) ) {
} else { is_ok = gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
gnc_sql_slots_delete( be, guid ); } else {
} is_ok = gnc_sql_slots_delete( be, guid );
}
}
return is_ok;
} }
/* ================================================================= */ /* ================================================================= */
@@ -198,26 +205,38 @@ employee_should_be_saved( GncEmployee *employee )
return TRUE; return TRUE;
} }
typedef struct {
GncSqlBackend* be;
gboolean is_ok;
} write_objects_t;
static void static void
write_single_employee( QofInstance *term_p, gpointer be_p ) write_single_employee( QofInstance *term_p, gpointer data_p )
{ {
GncSqlBackend* be = (GncSqlBackend*)be_p; write_objects_t* s = (write_objects_t*)data_p;
g_return_if_fail( term_p != NULL ); g_return_if_fail( term_p != NULL );
g_return_if_fail( GNC_IS_EMPLOYEE(term_p) ); g_return_if_fail( GNC_IS_EMPLOYEE(term_p) );
g_return_if_fail( be_p != NULL ); g_return_if_fail( data_p != NULL );
if( employee_should_be_saved( GNC_EMPLOYEE(term_p) ) ) { if( s->is_ok && employee_should_be_saved( GNC_EMPLOYEE(term_p) ) ) {
save_employee( be, term_p ); s->is_ok = save_employee( s->be, term_p );
} }
} }
static void static gboolean
write_employees( GncSqlBackend* be ) write_employees( GncSqlBackend* be )
{ {
g_return_if_fail( be != NULL ); write_objects_t data;
qof_object_foreach( GNC_ID_EMPLOYEE, be->primary_book, write_single_employee, (gpointer)be ); g_return_val_if_fail( be != NULL, FALSE );
data.be = be;
data.is_ok = TRUE;
qof_object_foreach( GNC_ID_EMPLOYEE, be->primary_book, write_single_employee, &data );
return data.is_ok;
} }
/* ================================================================= */ /* ================================================================= */

View File

@@ -167,40 +167,51 @@ create_entry_tables( GncSqlBackend* be )
} }
/* ================================================================= */ /* ================================================================= */
static void static gboolean
save_entry( GncSqlBackend* be, QofInstance* inst ) save_entry( GncSqlBackend* be, QofInstance* inst )
{ {
g_return_if_fail( inst != NULL ); g_return_val_if_fail( inst != NULL, FALSE );
g_return_if_fail( GNC_IS_ENTRY(inst) ); g_return_val_if_fail( GNC_IS_ENTRY(inst), FALSE );
g_return_if_fail( be != NULL ); g_return_val_if_fail( be != NULL, FALSE );
gnc_sql_commit_standard_item( be, inst, TABLE_NAME, GNC_ID_ENTRY, col_table ); return gnc_sql_commit_standard_item( be, inst, TABLE_NAME, GNC_ID_ENTRY, col_table );
} }
/* ================================================================= */ /* ================================================================= */
typedef struct {
GncSqlBackend* be;
gboolean is_ok;
} write_objects_t;
static void static void
write_single_entry( QofInstance *term_p, gpointer be_p ) write_single_entry( QofInstance *term_p, gpointer data_p )
{ {
GncSqlBackend* be = (GncSqlBackend*)be_p; write_objects_t* s = (write_objects_t*)data_p;
GncEntry* entry = GNC_ENTRY(term_p); GncEntry* entry = GNC_ENTRY(term_p);
g_return_if_fail( term_p != NULL ); g_return_if_fail( term_p != NULL );
g_return_if_fail( GNC_IS_ENTRY(term_p) ); g_return_if_fail( GNC_IS_ENTRY(term_p) );
g_return_if_fail( be_p != NULL ); g_return_if_fail( data_p != NULL );
/* Only save if attached */ /* Only save if attached */
if( gncEntryGetOrder( entry ) != NULL || gncEntryGetInvoice( entry ) != NULL || if( s->is_ok && (gncEntryGetOrder( entry ) != NULL || gncEntryGetInvoice( entry ) != NULL ||
gncEntryGetBill( entry ) != NULL ) { gncEntryGetBill( entry ) != NULL) ) {
save_entry( be, term_p ); s->is_ok = save_entry( s->be, term_p );
} }
} }
static void static gboolean
write_entries( GncSqlBackend* be ) write_entries( GncSqlBackend* be )
{ {
g_return_if_fail( be != NULL ); write_objects_t data;
qof_object_foreach( GNC_ID_ENTRY, be->primary_book, write_single_entry, (gpointer)be ); g_return_val_if_fail( be != NULL, FALSE );
data.be = be;
data.is_ok = TRUE;
qof_object_foreach( GNC_ID_ENTRY, be->primary_book, write_single_entry, &data );
return data.is_ok;
} }
/* ================================================================= */ /* ================================================================= */

View File

@@ -151,17 +151,18 @@ create_invoice_tables( GncSqlBackend* be )
} }
/* ================================================================= */ /* ================================================================= */
static void static gboolean
save_invoice( GncSqlBackend* be, QofInstance* inst ) save_invoice( GncSqlBackend* be, QofInstance* inst )
{ {
const GUID* guid; const GUID* guid;
GncInvoice* invoice; GncInvoice* invoice;
gint op; gint op;
gboolean is_infant; gboolean is_infant;
gboolean is_ok = TRUE;
g_return_if_fail( inst != NULL ); g_return_val_if_fail( inst != NULL, FALSE );
g_return_if_fail( GNC_IS_INVOICE(inst) ); g_return_val_if_fail( GNC_IS_INVOICE(inst), FALSE );
g_return_if_fail( be != NULL ); g_return_val_if_fail( be != NULL, FALSE );
invoice = GNC_INVOICE(inst); invoice = GNC_INVOICE(inst);
@@ -175,18 +176,24 @@ save_invoice( GncSqlBackend* be, QofInstance* inst )
} }
if( op != OP_DB_DELETE ) { if( op != OP_DB_DELETE ) {
// Ensure the commodity is in the db // Ensure the commodity is in the db
gnc_sql_save_commodity( be, gncInvoiceGetCurrency( invoice ) ); is_ok = gnc_sql_save_commodity( be, gncInvoiceGetCurrency( invoice ) );
} }
(void)gnc_sql_do_db_operation( be, op, TABLE_NAME, GNC_ID_INVOICE, inst, col_table ); if( is_ok ) {
is_ok = gnc_sql_do_db_operation( be, op, TABLE_NAME, GNC_ID_INVOICE, inst, col_table );
}
// Now, commit or delete any slots if( is_ok ) {
guid = qof_instance_get_guid( inst ); // Now, commit or delete any slots
if( !qof_instance_get_destroying(inst) ) { guid = qof_instance_get_guid( inst );
gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) ); if( !qof_instance_get_destroying(inst) ) {
} else { is_ok = gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
gnc_sql_slots_delete( be, guid ); } else {
} is_ok = gnc_sql_slots_delete( be, guid );
}
}
return is_ok;
} }
/* ================================================================= */ /* ================================================================= */
@@ -206,26 +213,37 @@ invoice_should_be_saved( GncInvoice *invoice )
return TRUE; return TRUE;
} }
typedef struct {
GncSqlBackend* be;
gboolean is_ok;
} write_objects_t;
static void static void
write_single_invoice( QofInstance *term_p, gpointer be_p ) write_single_invoice( QofInstance *term_p, gpointer data_p )
{ {
GncSqlBackend* be = (GncSqlBackend*)be_p; write_objects_t* s = (write_objects_t*)data_p;
g_return_if_fail( term_p != NULL ); g_return_if_fail( term_p != NULL );
g_return_if_fail( GNC_IS_INVOICE(term_p) ); g_return_if_fail( GNC_IS_INVOICE(term_p) );
g_return_if_fail( be_p != NULL ); g_return_if_fail( data_p != NULL );
if( invoice_should_be_saved( GNC_INVOICE(term_p) ) ) { if( s->is_ok && invoice_should_be_saved( GNC_INVOICE(term_p) ) ) {
save_invoice( be, term_p ); s->is_ok = save_invoice( s->be, term_p );
} }
} }
static void static gboolean
write_invoices( GncSqlBackend* be ) write_invoices( GncSqlBackend* be )
{ {
g_return_if_fail( be != NULL ); write_objects_t data;
qof_object_foreach( GNC_ID_INVOICE, be->primary_book, write_single_invoice, (gpointer)be ); g_return_val_if_fail( be != NULL, FALSE );
data.be = be;
data.is_ok = TRUE;
qof_object_foreach( GNC_ID_INVOICE, be->primary_book, write_single_invoice, &data );
return data.is_ok;
} }
/* ================================================================= */ /* ================================================================= */

View File

@@ -134,14 +134,14 @@ create_job_tables( GncSqlBackend* be )
} }
/* ================================================================= */ /* ================================================================= */
static void static gboolean
save_job( GncSqlBackend* be, QofInstance* inst ) save_job( GncSqlBackend* be, QofInstance* inst )
{ {
g_return_if_fail( inst != NULL ); g_return_val_if_fail( inst != NULL, FALSE );
g_return_if_fail( GNC_IS_JOB(inst) ); g_return_val_if_fail( GNC_IS_JOB(inst), FALSE );
g_return_if_fail( be != NULL ); g_return_val_if_fail( be != NULL, FALSE );
gnc_sql_commit_standard_item( be, inst, TABLE_NAME, GNC_ID_JOB, col_table ); return gnc_sql_commit_standard_item( be, inst, TABLE_NAME, GNC_ID_JOB, col_table );
} }
/* ================================================================= */ /* ================================================================= */
@@ -161,26 +161,37 @@ job_should_be_saved( GncJob *job )
return TRUE; return TRUE;
} }
typedef struct {
GncSqlBackend* be;
gboolean is_ok;
} write_objects_t;
static void static void
write_single_job( QofInstance *term_p, gpointer be_p ) write_single_job( QofInstance *term_p, gpointer data_p )
{ {
GncSqlBackend* be = (GncSqlBackend*)be_p; write_objects_t* s = (write_objects_t*)data_p;
g_return_if_fail( term_p != NULL ); g_return_if_fail( term_p != NULL );
g_return_if_fail( GNC_IS_JOB(term_p) ); g_return_if_fail( GNC_IS_JOB(term_p) );
g_return_if_fail( be_p != NULL ); g_return_if_fail( data_p != NULL );
if( job_should_be_saved( GNC_JOB(term_p) ) ) { if( s->is_ok && job_should_be_saved( GNC_JOB(term_p) ) ) {
save_job( be, term_p ); s->is_ok = save_job( s->be, term_p );
} }
} }
static void static gboolean
write_jobs( GncSqlBackend* be ) write_jobs( GncSqlBackend* be )
{ {
g_return_if_fail( be != NULL ); write_objects_t data;
qof_object_foreach( GNC_ID_JOB, be->primary_book, write_single_job, (gpointer)be ); g_return_val_if_fail( be != NULL, FALSE );
data.be = be;
data.is_ok = TRUE;
qof_object_foreach( GNC_ID_JOB, be->primary_book, write_single_job, &data );
return data.is_ok;
} }
/* ================================================================= */ /* ================================================================= */

View File

@@ -135,14 +135,14 @@ create_order_tables( GncSqlBackend* be )
} }
/* ================================================================= */ /* ================================================================= */
static void static gboolean
save_order( GncSqlBackend* be, QofInstance* inst ) save_order( GncSqlBackend* be, QofInstance* inst )
{ {
g_return_if_fail( inst != NULL ); g_return_val_if_fail( inst != NULL, FALSE );
g_return_if_fail( GNC_IS_ORDER(inst) ); g_return_val_if_fail( GNC_IS_ORDER(inst), FALSE );
g_return_if_fail( be != NULL ); g_return_val_if_fail( be != NULL, FALSE );
gnc_sql_commit_standard_item( be, inst, TABLE_NAME, GNC_ID_ORDER, col_table ); return gnc_sql_commit_standard_item( be, inst, TABLE_NAME, GNC_ID_ORDER, col_table );
} }
/* ================================================================= */ /* ================================================================= */
@@ -162,26 +162,37 @@ order_should_be_saved( GncOrder *order )
return TRUE; return TRUE;
} }
typedef struct {
GncSqlBackend* be;
gboolean is_ok;
} write_objects_t;
static void static void
write_single_order( QofInstance *term_p, gpointer be_p ) write_single_order( QofInstance *term_p, gpointer data_p )
{ {
GncSqlBackend* be = (GncSqlBackend*)be_p; write_objects_t* s = (write_objects_t*)data_p;
g_return_if_fail( term_p != NULL ); g_return_if_fail( term_p != NULL );
g_return_if_fail( GNC_IS_ORDER(term_p) ); g_return_if_fail( GNC_IS_ORDER(term_p) );
g_return_if_fail( be_p != NULL ); g_return_if_fail( data_p != NULL );
if( order_should_be_saved( GNC_ORDER(term_p) ) ) { if( s->is_ok && order_should_be_saved( GNC_ORDER(term_p) ) ) {
save_order( be, term_p ); s->is_ok = save_order( s->be, term_p );
} }
} }
static void static gboolean
write_orders( GncSqlBackend* be ) write_orders( GncSqlBackend* be )
{ {
g_return_if_fail( be != NULL ); write_objects_t data;
qof_object_foreach( GNC_ID_ORDER, be->primary_book, write_single_order, (gpointer)be ); g_return_val_if_fail( be != NULL, FALSE );
data.be = be;
data.is_ok = TRUE;
qof_object_foreach( GNC_ID_ORDER, be->primary_book, write_single_order, &data );
return data.is_ok;
} }
/* ================================================================= */ /* ================================================================= */

View File

@@ -268,52 +268,56 @@ create_taxtable_tables( GncSqlBackend* be )
} }
/* ================================================================= */ /* ================================================================= */
static void static gboolean
delete_all_tt_entries( GncSqlBackend* be, const GUID* guid ) delete_all_tt_entries( GncSqlBackend* be, const GUID* guid )
{ {
guid_info_t guid_info; guid_info_t guid_info;
g_return_if_fail( be != NULL ); g_return_val_if_fail( be != NULL, FALSE );
g_return_if_fail( guid != NULL ); g_return_val_if_fail( guid != NULL, FALSE );
guid_info.be = be; guid_info.be = be;
guid_info.guid = guid; guid_info.guid = guid;
(void)gnc_sql_do_db_operation( be, OP_DB_DELETE, TTENTRIES_TABLE_NAME, return gnc_sql_do_db_operation( be, OP_DB_DELETE, TTENTRIES_TABLE_NAME,
TTENTRIES_TABLE_NAME, &guid_info, guid_col_table ); TTENTRIES_TABLE_NAME, &guid_info, guid_col_table );
} }
static void static gboolean
save_tt_entries( GncSqlBackend* be, const GUID* guid, GList* entries ) save_tt_entries( GncSqlBackend* be, const GUID* guid, GList* entries )
{ {
GList* entry; GList* entry;
gboolean is_ok;
g_return_if_fail( be != NULL ); g_return_val_if_fail( be != NULL, FALSE );
g_return_if_fail( guid != NULL ); g_return_val_if_fail( guid != NULL, FALSE );
/* First, delete the old entries for this object */ /* First, delete the old entries for this object */
delete_all_tt_entries( be, guid ); is_ok = delete_all_tt_entries( be, guid );
for( entry = entries; entry != NULL; entry = entry->next ) { for( entry = entries; entry != NULL && is_ok; entry = entry->next ) {
GncTaxTableEntry* e = (GncTaxTableEntry*)entry->data; GncTaxTableEntry* e = (GncTaxTableEntry*)entry->data;
(void)gnc_sql_do_db_operation( be, is_ok = gnc_sql_do_db_operation( be,
OP_DB_INSERT, OP_DB_INSERT,
TTENTRIES_TABLE_NAME, TTENTRIES_TABLE_NAME,
GNC_ID_TAXTABLE, e, GNC_ID_TAXTABLE, e,
ttentries_col_table ); ttentries_col_table );
} }
return is_ok;
} }
static void static gboolean
save_taxtable( GncSqlBackend* be, QofInstance* inst ) save_taxtable( GncSqlBackend* be, QofInstance* inst )
{ {
GncTaxTable* tt; GncTaxTable* tt;
const GUID* guid; const GUID* guid;
gint op; gint op;
gboolean is_infant; gboolean is_infant;
gboolean is_ok;
g_return_if_fail( inst != NULL ); g_return_val_if_fail( inst != NULL, FALSE );
g_return_if_fail( GNC_IS_TAXTABLE(inst) ); g_return_val_if_fail( GNC_IS_TAXTABLE(inst), FALSE );
g_return_if_fail( be != NULL ); g_return_val_if_fail( be != NULL, FALSE );
tt = GNC_TAXTABLE(inst); tt = GNC_TAXTABLE(inst);
@@ -325,32 +329,55 @@ save_taxtable( GncSqlBackend* be, QofInstance* inst )
} else { } else {
op = OP_DB_UPDATE; op = OP_DB_UPDATE;
} }
(void)gnc_sql_do_db_operation( be, op, TT_TABLE_NAME, GNC_ID_TAXTABLE, tt, tt_col_table ); is_ok = gnc_sql_do_db_operation( be, op, TT_TABLE_NAME, GNC_ID_TAXTABLE, tt, tt_col_table );
// Now, commit or delete any slots and tax table entries if( is_ok ) {
guid = qof_instance_get_guid( inst ); // Now, commit or delete any slots and tax table entries
if( !qof_instance_get_destroying(inst) ) { guid = qof_instance_get_guid( inst );
gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) ); if( !qof_instance_get_destroying(inst) ) {
save_tt_entries( be, guid, gncTaxTableGetEntries( tt ) ); is_ok = gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
} else { if( is_ok ) {
gnc_sql_slots_delete( be, guid ); is_ok = save_tt_entries( be, guid, gncTaxTableGetEntries( tt ) );
delete_all_tt_entries( be, guid ); }
} } else {
is_ok = gnc_sql_slots_delete( be, guid );
if( is_ok ) {
is_ok = delete_all_tt_entries( be, guid );
}
}
}
return is_ok;
} }
/* ================================================================= */ /* ================================================================= */
typedef struct {
GncSqlBackend* be;
gboolean is_ok;
} write_objects_t;
static void static void
save_next_taxtable( QofInstance* inst, gpointer p2 ) save_next_taxtable( QofInstance* inst, gpointer data )
{ {
save_taxtable( (GncSqlBackend*)p2, inst ); write_objects_t* s = (write_objects_t*)data;
if( s->is_ok ) {
s->is_ok = save_taxtable( s->be, inst );
}
} }
static void static gboolean
write_taxtables( GncSqlBackend* be ) write_taxtables( GncSqlBackend* be )
{ {
g_return_if_fail( be != NULL ); write_objects_t data;
qof_object_foreach( GNC_ID_TAXTABLE, be->primary_book, save_next_taxtable, be ); g_return_val_if_fail( be != NULL, FALSE );
data.be = be;
data.is_ok = TRUE;
qof_object_foreach( GNC_ID_TAXTABLE, be->primary_book, save_next_taxtable, &data );
return data.is_ok;
} }
/* ================================================================= */ /* ================================================================= */

View File

@@ -148,17 +148,18 @@ create_vendor_tables( GncSqlBackend* be )
} }
/* ================================================================= */ /* ================================================================= */
static void static gboolean
save_vendor( GncSqlBackend* be, QofInstance* inst ) save_vendor( GncSqlBackend* be, QofInstance* inst )
{ {
GncVendor* v; GncVendor* v;
const GUID* guid; const GUID* guid;
gint op; gint op;
gboolean is_infant; gboolean is_infant;
gboolean is_ok = TRUE;
g_return_if_fail( inst != NULL ); g_return_val_if_fail( inst != NULL, FALSE );
g_return_if_fail( GNC_IS_VENDOR(inst) ); g_return_val_if_fail( GNC_IS_VENDOR(inst), FALSE );
g_return_if_fail( be != NULL ); g_return_val_if_fail( be != NULL, FALSE );
v = GNC_VENDOR(inst); v = GNC_VENDOR(inst);
@@ -172,17 +173,23 @@ save_vendor( GncSqlBackend* be, QofInstance* inst )
} }
if( op != OP_DB_DELETE ) { if( op != OP_DB_DELETE ) {
// Ensure the commodity is in the db // Ensure the commodity is in the db
gnc_sql_save_commodity( be, gncVendorGetCurrency( v ) ); is_ok = gnc_sql_save_commodity( be, gncVendorGetCurrency( v ) );
}
if( is_ok ) {
is_ok = gnc_sql_do_db_operation( be, op, TABLE_NAME, GNC_ID_VENDOR, v, col_table );
} }
(void)gnc_sql_do_db_operation( be, op, TABLE_NAME, GNC_ID_VENDOR, v, col_table );
// Now, commit or delete any slots if( is_ok ) {
guid = qof_instance_get_guid( inst ); // Now, commit or delete any slots
if( !qof_instance_get_destroying(inst) ) { guid = qof_instance_get_guid( inst );
gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) ); if( !qof_instance_get_destroying(inst) ) {
} else { is_ok = gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
gnc_sql_slots_delete( be, guid ); } else {
} is_ok = gnc_sql_slots_delete( be, guid );
}
}
return is_ok;
} }
/* ================================================================= */ /* ================================================================= */
@@ -202,26 +209,37 @@ vendor_should_be_saved( GncVendor *vendor )
return TRUE; return TRUE;
} }
typedef struct {
GncSqlBackend* be;
gboolean is_ok;
} write_objects_t;
static void static void
write_single_vendor( QofInstance *term_p, gpointer be_p ) write_single_vendor( QofInstance *term_p, gpointer data_p )
{ {
GncSqlBackend* be = (GncSqlBackend*)be_p; write_objects_t* s = (write_objects_t*)data_p;
g_return_if_fail( term_p != NULL ); g_return_if_fail( term_p != NULL );
g_return_if_fail( GNC_IS_VENDOR(term_p) ); g_return_if_fail( GNC_IS_VENDOR(term_p) );
g_return_if_fail( be_p != NULL ); g_return_if_fail( data_p != NULL );
if( vendor_should_be_saved( GNC_VENDOR(term_p) ) ) { if( s->is_ok && vendor_should_be_saved( GNC_VENDOR(term_p) ) ) {
save_vendor( be, term_p ); s->is_ok = save_vendor( s->be, term_p );
} }
} }
static void static gboolean
write_vendors( GncSqlBackend* be ) write_vendors( GncSqlBackend* be )
{ {
g_return_if_fail( be != NULL ); write_objects_t data;
qof_object_foreach( GNC_ID_VENDOR, be->primary_book, write_single_vendor, (gpointer)be ); g_return_val_if_fail( be != NULL, FALSE );
data.be = be;
data.is_ok = TRUE;
qof_object_foreach( GNC_ID_VENDOR, be->primary_book, write_single_vendor, &data );
return data.is_ok;
} }
/* ================================================================= */ /* ================================================================= */