r17606 - gnucash/trunk/src - Improve error handling. If an SQL command fails, set the qof backend error

Phil Longstaff plongstaff at cvs.gnucash.org
Sat Sep 27 13:31:23 EDT 2008


Author: plongstaff
Date: 2008-09-27 13:31:23 -0400 (Sat, 27 Sep 2008)
New Revision: 17606
Trac: http://svn.gnucash.org/trac/changeset/17606

Modified:
   gnucash/trunk/src/backend/dbi/gnc-backend-dbi.c
   gnucash/trunk/src/backend/sql/gnc-account-sql.c
   gnucash/trunk/src/backend/sql/gnc-account-sql.h
   gnucash/trunk/src/backend/sql/gnc-backend-sql.c
   gnucash/trunk/src/backend/sql/gnc-backend-sql.h
   gnucash/trunk/src/backend/sql/gnc-book-sql.c
   gnucash/trunk/src/backend/sql/gnc-book-sql.h
   gnucash/trunk/src/backend/sql/gnc-budget-sql.c
   gnucash/trunk/src/backend/sql/gnc-commodity-sql.c
   gnucash/trunk/src/backend/sql/gnc-commodity-sql.h
   gnucash/trunk/src/backend/sql/gnc-lots-sql.c
   gnucash/trunk/src/backend/sql/gnc-price-sql.c
   gnucash/trunk/src/backend/sql/gnc-recurrence-sql.c
   gnucash/trunk/src/backend/sql/gnc-recurrence-sql.h
   gnucash/trunk/src/backend/sql/gnc-schedxaction-sql.c
   gnucash/trunk/src/backend/sql/gnc-schedxaction-sql.h
   gnucash/trunk/src/backend/sql/gnc-slots-sql.c
   gnucash/trunk/src/backend/sql/gnc-slots-sql.h
   gnucash/trunk/src/backend/sql/gnc-transaction-sql.c
   gnucash/trunk/src/backend/sql/gnc-transaction-sql.h
   gnucash/trunk/src/business/business-core/sql/gnc-bill-term-sql.c
   gnucash/trunk/src/business/business-core/sql/gnc-bill-term-sql.h
   gnucash/trunk/src/business/business-core/sql/gnc-customer-sql.c
   gnucash/trunk/src/business/business-core/sql/gnc-employee-sql.c
   gnucash/trunk/src/business/business-core/sql/gnc-entry-sql.c
   gnucash/trunk/src/business/business-core/sql/gnc-invoice-sql.c
   gnucash/trunk/src/business/business-core/sql/gnc-job-sql.c
   gnucash/trunk/src/business/business-core/sql/gnc-order-sql.c
   gnucash/trunk/src/business/business-core/sql/gnc-tax-table-sql.c
   gnucash/trunk/src/business/business-core/sql/gnc-vendor-sql.c
Log:
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).



Modified: gnucash/trunk/src/backend/dbi/gnc-backend-dbi.c
===================================================================
--- gnucash/trunk/src/backend/dbi/gnc-backend-dbi.c	2008-09-27 12:18:24 UTC (rev 17605)
+++ gnucash/trunk/src/backend/dbi/gnc-backend-dbi.c	2008-09-27 17:31:23 UTC (rev 17606)
@@ -859,7 +859,7 @@
 	result = dbi_conn_query( dbi_conn->conn, dbi_stmt->sql->str );
 	if( result == NULL ) {
 		PERR( "Error executing SQL %s\n", dbi_stmt->sql->str );
-		return 0;
+		return -1;
 	}
 	DEBUG( "SQL: %s\n", dbi_stmt->sql->str );
 	num_rows = dbi_result_get_numrows_affected( result );
@@ -910,22 +910,28 @@
 	}
 }
 
-static void
+static gboolean
 conn_begin_transaction( GncSqlConnection* conn )
 {
 	GncDbiSqlConnection* dbi_conn = (GncDbiSqlConnection*)conn;
+
+	return TRUE;
 }
 
-static void
+static gboolean
 conn_rollback_transaction( GncSqlConnection* conn )
 {
 	GncDbiSqlConnection* dbi_conn = (GncDbiSqlConnection*)conn;
+
+	return TRUE;
 }
 
-static void
+static gboolean
 conn_commit_transaction( GncSqlConnection* conn )
 {
 	GncDbiSqlConnection* dbi_conn = (GncDbiSqlConnection*)conn;
+
+	return TRUE;
 }
 
 static const gchar*
@@ -1009,7 +1015,7 @@
 	}
 }
 
-static void
+static gboolean
 conn_create_table( GncSqlConnection* conn, const gchar* table_name,
 				const GList* col_info_list )
 {
@@ -1019,9 +1025,9 @@
 	guint col_num;
 	dbi_result result;
 
-	g_return_if_fail( conn != NULL );
-	g_return_if_fail( table_name != NULL );
-	g_return_if_fail( col_info_list != NULL );
+	g_return_val_if_fail( conn != NULL, FALSE );
+	g_return_val_if_fail( table_name != NULL, FALSE );
+	g_return_val_if_fail( col_info_list != NULL, FALSE );
     
 	ddl = g_string_new( "" );
 	g_string_printf( ddl, "CREATE TABLE %s (", table_name );
@@ -1040,9 +1046,11 @@
 	result = dbi_conn_query( dbi_conn->conn, ddl->str );
 	dbi_result_free( result );
 	g_string_free( ddl, TRUE );
+
+	return TRUE;
 }
 
-static void
+static gboolean
 conn_create_index( GncSqlConnection* conn, const gchar* index_name,
 					const gchar* table_name, const GncSqlColumnTableEntry* col_table )
 {
@@ -1053,10 +1061,10 @@
 	GncDbiSqlConnection* dbi_conn = (GncDbiSqlConnection*)conn;
 	GError* error = NULL;
     
-    g_return_if_fail( conn != NULL );
-	g_return_if_fail( index_name != NULL );
-	g_return_if_fail( table_name != NULL );
-	g_return_if_fail( col_table != NULL );
+    g_return_val_if_fail( conn != NULL, FALSE );
+	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 );
     
 	cnn = gda_conn->conn;
 	g_return_if_fail( cnn != NULL );
@@ -1123,6 +1131,8 @@
         g_object_unref( op );
     }
 #endif
+
+	return TRUE;
 }
 
 static gchar*

Modified: gnucash/trunk/src/backend/sql/gnc-account-sql.c
===================================================================
--- gnucash/trunk/src/backend/sql/gnc-account-sql.c	2008-09-27 12:18:24 UTC (rev 17605)
+++ gnucash/trunk/src/backend/sql/gnc-account-sql.c	2008-09-27 17:31:23 UTC (rev 17606)
@@ -263,16 +263,17 @@
 }
 
 /* ================================================================= */
-void
+gboolean
 gnc_sql_save_account( GncSqlBackend* be, QofInstance* inst )
 {
     Account* pAcc = GNC_ACCOUNT(inst);
     const GUID* guid;
 	gboolean is_infant;
+	gboolean is_ok = FALSE;
 
-	g_return_if_fail( be != NULL );
-	g_return_if_fail( inst != NULL );
-	g_return_if_fail( GNC_IS_ACCOUNT(inst) );
+	g_return_val_if_fail( be != NULL, FALSE );
+	g_return_val_if_fail( inst != NULL, FALSE );
+	g_return_val_if_fail( GNC_IS_ACCOUNT(inst), FALSE );
 
 	is_infant = qof_instance_get_infant( inst );
 
@@ -293,19 +294,25 @@
 
         // If not deleting the account, ensure the commodity is in the db
 		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
-        guid = qof_instance_get_guid( inst );
-        if( !qof_instance_get_destroying(inst) ) {
-            gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
-        } else {
-            gnc_sql_slots_delete( be, guid );
-        }
+		if( is_ok ) {
+        	// Now, commit or delete any slots
+        	guid = qof_instance_get_guid( inst );
+        	if( !qof_instance_get_destroying(inst) ) {
+            	is_ok = gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
+	        } else {
+            	is_ok = gnc_sql_slots_delete( be, guid );
+			}
+		}
     }
+
+	return is_ok;
 }
 
 /* ================================================================= */
@@ -354,8 +361,8 @@
     {
         GNC_SQL_BACKEND_VERSION,
         GNC_ID_ACCOUNT,
-        gnc_sql_save_account,				/* commit */
-        load_all_accounts,				/* initial_load */
+        gnc_sql_save_account,		/* commit */
+        load_all_accounts,			/* initial_load */
         create_account_tables		/* create_tables */
     };
 

Modified: gnucash/trunk/src/backend/sql/gnc-account-sql.h
===================================================================
--- gnucash/trunk/src/backend/sql/gnc-account-sql.h	2008-09-27 12:18:24 UTC (rev 17605)
+++ gnucash/trunk/src/backend/sql/gnc-account-sql.h	2008-09-27 17:31:23 UTC (rev 17606)
@@ -33,6 +33,6 @@
 #include <gmodule.h>
 
 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_ */

Modified: gnucash/trunk/src/backend/sql/gnc-backend-sql.c
===================================================================
--- gnucash/trunk/src/backend/sql/gnc-backend-sql.c	2008-09-27 12:18:24 UTC (rev 17605)
+++ gnucash/trunk/src/backend/sql/gnc-backend-sql.c	2008-09-27 17:31:23 UTC (rev 17606)
@@ -63,7 +63,7 @@
 static void gnc_sql_init_object_handlers( void );
 static void update_save_progress( GncSqlBackend* be );
 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,
                         			const gchar* table_name,
                         			QofIdTypeConst obj_name, gpointer pObject,
@@ -86,7 +86,8 @@
 
 /* callback structure */
 typedef struct {
-    gboolean ok;
+    gboolean is_known;
+	gboolean is_ok;
     GncSqlBackend* be;
     QofInstance* inst;
     QofQuery* pQuery;
@@ -240,83 +241,110 @@
     }
 }
 
-static void
+static gboolean
 write_account_tree( GncSqlBackend* be, Account* root )
 {
     GList* descendants;
     GList* node;
+	gboolean is_ok = TRUE;
 
-	g_return_if_fail( be != NULL );
-	g_return_if_fail( root != NULL );
+	g_return_val_if_fail( be != NULL, FALSE );
+	g_return_val_if_fail( root != NULL, FALSE );
 
     descendants = gnc_account_get_descendants( root );
-    for( node = descendants; node != NULL; node = g_list_next(node) ) {
-        gnc_sql_save_account( be, QOF_INSTANCE(GNC_ACCOUNT(node->data)) );
+    for( node = descendants; node != NULL && is_ok; node = g_list_next(node) ) {
+        is_ok = gnc_sql_save_account( be, QOF_INSTANCE(GNC_ACCOUNT(node->data)) );
 		update_save_progress( be );
     }
     g_list_free( descendants );
+
+	return is_ok;
 }
 
-static void
+static gboolean
 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
 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( data != NULL, 0 );
 
-    gnc_sql_save_transaction( be, QOF_INSTANCE(tx) );
-	update_save_progress( be );
+    s->is_ok = gnc_sql_save_transaction( s->be, QOF_INSTANCE(tx) );
+	update_save_progress( s->be );
 
-    return 0;
+	if( s->is_ok ) {
+    	return 0;
+	} else {
+		return 1;
+	}
 }
 
-static void
+static gboolean
 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 ),
                                        write_tx,
-                                       (gpointer)be );
+                                       &data );
+	return data.is_ok;
 }
 
-static void
+static gboolean
 write_template_transactions( GncSqlBackend* be )
 {
     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 );
     if( gnc_account_n_descendants( ra ) > 0 ) {
-        write_account_tree( be, ra );
-        xaccAccountTreeForEachTransaction( ra, write_tx, (gpointer)be );
+        data.is_ok = write_account_tree( be, ra );
+		if( data.is_ok ) {
+			data.be = be;
+        	xaccAccountTreeForEachTransaction( ra, write_tx, &data );
+		}
     }
+
+	return data.is_ok;
 }
 
-static void
+static gboolean
 write_schedXactions( GncSqlBackend* be )
 {
     GList* schedXactions;
     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;
 
-    for( ; schedXactions != NULL; schedXactions = schedXactions->next ) {
+    for( ; schedXactions != NULL && is_ok; schedXactions = schedXactions->next ) {
         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
@@ -354,7 +382,7 @@
     GError* error = NULL;
     gint row;
     gint numTables;
-	gboolean status;
+	gboolean is_ok;
 
 	g_return_if_fail( be != NULL );
 	g_return_if_fail( book != NULL );
@@ -379,12 +407,22 @@
 
 	// FIXME: should write the set of commodities that are used 
     //write_commodities( be, book );
-	gnc_sql_save_book( be, QOF_INSTANCE(book) );
-    write_accounts( be );
-    write_transactions( be );
-    write_template_transactions( be );
-    write_schedXactions( be );
-    qof_object_foreach_backend( GNC_SQL_BACKEND, write_cb, be );
+	is_ok = gnc_sql_save_book( be, QOF_INSTANCE(book) );
+	if( is_ok ) {
+    	is_ok = write_accounts( be );
+	}
+	if( is_ok ) {
+    	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 );
 	be->is_pristine_db = FALSE;
@@ -423,11 +461,11 @@
 
     /* 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( be_data->ok ) return;
+    if( be_data->is_known ) return;
 
     if( pData->commit != NULL ) {
-        (pData->commit)( be_data->be, be_data->inst );
-        be_data->ok = TRUE;
+        be_data->is_ok = (pData->commit)( be_data->be, be_data->inst );
+        be_data->is_known = TRUE;
     }
 }
 
@@ -439,7 +477,6 @@
 {
     sql_backend be_data;
 	GError* error;
-	gboolean status;
 	gboolean is_dirty;
 	gboolean is_destroying;
 	gboolean is_infant;
@@ -479,21 +516,30 @@
 	error = NULL;
 	gnc_sql_connection_begin_transaction( be->conn );
 
-    be_data.ok = FALSE;
+    be_data.is_known = FALSE;
     be_data.be = be;
     be_data.inst = inst;
     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 );
 		gnc_sql_connection_rollback_transaction( be->conn );
 
 		// Don't let unknown items still mark the book as being dirty
     	qof_instance_mark_clean(inst);
     	qof_book_mark_saved( be->primary_book );
-		LEAVE( "Rolled back" );
+		LEAVE( "Rolled back - unknown object type" );
         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 );
 
     qof_instance_mark_clean(inst);
@@ -613,13 +659,13 @@
 
 	// Is this the right item?
     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 ) {
         be_data->pQueryInfo->pCompiledQuery = (pData->compile_query)(
                                                             be_data->be,
                                                             be_data->pQuery );
-        be_data->ok = TRUE;
+        be_data->is_ok = TRUE;
     }
 }
 
@@ -643,14 +689,14 @@
     pQueryInfo = g_malloc( sizeof( gnc_sql_query_info ) );
 
     // Try various objects first
-    be_data.ok = FALSE;
+    be_data.is_ok = FALSE;
     be_data.be = be;
     be_data.pQuery = pQuery;
     pQueryInfo->searchObj = searchObj;
     be_data.pQueryInfo = pQueryInfo;
 
     qof_object_foreach_backend( GNC_SQL_BACKEND, compile_query_cb, &be_data );
-    if( be_data.ok ) {
+    if( be_data.is_ok ) {
 		LEAVE( "" );
         return be_data.pQueryInfo;
     }
@@ -697,12 +743,12 @@
 
     g_return_if_fail( type != NULL && pData != NULL && be_data != NULL );
     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( pData->free_query != NULL ) {
         (pData->free_query)( be_data->be, be_data->pCompiledQuery );
-        be_data->ok = TRUE;
+        be_data->is_ok = TRUE;
     }
 }
 
@@ -719,13 +765,13 @@
 	ENTER( " " );
 
     // Try various objects first
-    be_data.ok = FALSE;
+    be_data.is_ok = FALSE;
     be_data.be = be;
     be_data.pCompiledQuery = pQuery;
     be_data.pQueryInfo = pQueryInfo;
 
     qof_object_foreach_backend( GNC_SQL_BACKEND, free_query_cb, &be_data );
-    if( be_data.ok ) {
+    if( be_data.is_ok ) {
 		LEAVE( "" );
         return;
     }
@@ -745,14 +791,14 @@
 
     g_return_if_fail( type != NULL && pData != NULL && be_data != NULL );
     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?
     if( strcmp( type, be_data->pQueryInfo->searchObj ) != 0 ) return;
 
     if( pData->run_query != NULL ) {
         (pData->run_query)( be_data->be, be_data->pCompiledQuery );
-        be_data->ok = TRUE;
+        be_data->is_ok = TRUE;
     }
 }
 
@@ -775,7 +821,7 @@
     qof_event_suspend();
 
     // Try various objects first
-    be_data.ok = FALSE;
+    be_data.is_ok = FALSE;
     be_data.be = be;
     be_data.pCompiledQuery = pQueryInfo->pCompiledQuery;
     be_data.pQueryInfo = pQueryInfo;
@@ -784,7 +830,7 @@
     be->loading = FALSE;
     be->in_query = FALSE;
     qof_event_resume();
-//    if( be_data.ok ) {
+//    if( be_data.is_ok ) {
 //		LEAVE( "" );
 //       	return;
 //    }
@@ -1883,7 +1929,7 @@
 
 /* ================================================================= */
 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;
 
@@ -1895,7 +1941,7 @@
 }
 
 static GncSqlStatement*
-create_single_col_select_statement( const GncSqlBackend* be,
+create_single_col_select_statement( GncSqlBackend* be,
 							const gchar* table_name,
 							const GncSqlColumnTableEntry* table_row )
 {
@@ -1914,15 +1960,14 @@
 GncSqlResult*
 gnc_sql_execute_select_statement( GncSqlBackend* be, GncSqlStatement* stmt )
 {
-    GError* error = NULL;
     GncSqlResult* result;
 
 	g_return_val_if_fail( be != NULL, NULL );
 	g_return_val_if_fail( stmt != NULL, NULL );
 
     result = gnc_sql_connection_execute_select_statement( be->conn, stmt );
-    if( error != NULL ) {
-        PERR( "SQL error: %s\n%s\n", gnc_sql_statement_to_sql( stmt ), error->message );
+    if( result == NULL ) {
+        PERR( "SQL error: %s\n", gnc_sql_statement_to_sql( stmt ) );
 		qof_backend_set_error( &be->be, ERR_BACKEND_SERVER_ERR );
     }
 
@@ -1930,9 +1975,8 @@
 }
 
 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;
 
 	g_return_val_if_fail( be != NULL, NULL );
@@ -1940,17 +1984,17 @@
 
 	stmt = gnc_sql_connection_create_statement_from_sql( be->conn, sql );
     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;
 }
 
 GncSqlResult*
-gnc_sql_execute_select_sql( const GncSqlBackend* be, gchar* sql )
+gnc_sql_execute_select_sql( GncSqlBackend* be, gchar* sql )
 {
 	GncSqlStatement* stmt;
-    GError* error = NULL;
 	GncSqlResult* result = NULL;
 
 	g_return_val_if_fail( be != NULL, NULL );
@@ -1961,15 +2005,16 @@
 		return NULL;
     }
 	result = gnc_sql_connection_execute_select_statement( be->conn, stmt );
-    if( error != NULL ) {
-        PERR( "SQL error: %s\n%s\n", sql, error->message );
+    if( result == NULL ) {
+        PERR( "SQL error: %s\n", sql );
+		qof_backend_set_error( &be->be, ERR_BACKEND_SERVER_ERR );
     }
 
 	return result;
 }
 
 gint
-gnc_sql_execute_nonselect_sql( const GncSqlBackend* be, gchar* sql )
+gnc_sql_execute_nonselect_sql( GncSqlBackend* be, gchar* sql )
 {
 	GncSqlStatement* stmt;
 	gint result;
@@ -1979,7 +2024,7 @@
 
 	stmt = gnc_sql_create_statement_from_sql( be, sql );
     if( stmt == NULL ) {
-		return 0;
+		return -1;
     }
 	result = gnc_sql_connection_execute_nonselect_statement( be->conn, stmt );
 	gnc_sql_statement_dispose( stmt );
@@ -2073,6 +2118,7 @@
                         const GncSqlColumnTableEntry* table )
 {
     GncSqlStatement* stmt;
+	gboolean ok = FALSE;
 
 	g_return_val_if_fail( be != NULL, FALSE );
 	g_return_val_if_fail( table_name != NULL, FALSE );
@@ -2090,13 +2136,19 @@
         g_assert( FALSE );
     }
     if( stmt != NULL ) {
-		gnc_sql_connection_execute_nonselect_statement( be->conn, stmt );
+		gint result;
+
+		result = gnc_sql_connection_execute_nonselect_statement( be->conn, stmt );
+		if( result == -1 ) {
+        	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 TRUE;
-    } else {
-        return FALSE;
-    }
+	return ok;
 }
 
 static GSList*
@@ -2302,13 +2354,14 @@
 }
 
 /* ================================================================= */
-void
+gboolean
 gnc_sql_commit_standard_item( GncSqlBackend* be, QofInstance* inst, const gchar* tableName,
                         	QofIdTypeConst obj_name, const GncSqlColumnTableEntry* col_table )
 {
 	const GUID* guid;
 	gboolean is_infant;
 	gint op;
+	gboolean is_ok;
 
 	is_infant = qof_instance_get_infant( inst );
 	if( qof_instance_get_destroying( inst ) ) {
@@ -2318,24 +2371,29 @@
 	} else {
 		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
-    guid = qof_instance_get_guid( inst );
-    if( !qof_instance_get_destroying(inst) ) {
-        gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
-    } else {
-        gnc_sql_slots_delete( be, guid );
-    }
+	if( is_ok ) {
+    	// Now, commit any slots
+    	guid = qof_instance_get_guid( inst );
+    	if( !qof_instance_get_destroying(inst) ) {
+        	is_ok = gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
+    	} else {
+        	is_ok = gnc_sql_slots_delete( be, guid );
+    	}
+	}
+
+	return is_ok;
 }
 
 /* ================================================================= */
 
 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 )
 {
 	GList* col_info_list = NULL;
+	gboolean ok = FALSE;
     
 	g_return_val_if_fail( be != NULL, FALSE );
 	g_return_val_if_fail( table_name != NULL, FALSE );
@@ -2347,19 +2405,19 @@
         pHandler = get_handler( col_table );
         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 );
-	return TRUE;
+	ok = gnc_sql_connection_create_table( be->conn, table_name, col_info_list );
+	return ok;
 }
 
 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 )
 {
 	gboolean ok;
 
-	ok = create_table( be, table_name, col_table );
+	ok = do_create_table( be, table_name, col_table );
 	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;
 }
@@ -2368,21 +2426,24 @@
 gnc_sql_create_temp_table( const GncSqlBackend* be, const gchar* table_name,
 							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,
 					const gchar* table_name,
                     const GncSqlColumnTableEntry* col_table )
 {
-    g_return_if_fail( be != NULL );
-	g_return_if_fail( index_name != NULL );
-	g_return_if_fail( table_name != NULL );
-	g_return_if_fail( col_table != NULL );
+	gboolean ok;
+
+    g_return_val_if_fail( be != NULL, FALSE );
+	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 );
+	return ok;
 }
 
 gint
@@ -2454,7 +2515,7 @@
 	} else {
 		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 @@
  * It also recreates the version table in the db.
  *
  * @param be Backend struct
+ * @return TRUE if successful, FALSE if error
  */
-static void
+static gboolean
 reset_version_info( GncSqlBackend* be )
 {
 	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 ) {
 		be->versions = g_hash_table_new_full( g_str_hash, g_str_equal, g_free, NULL );
 	} else {
 		g_hash_table_remove_all( be->versions );
 	}
+
+	return ok;
 }
 
 /**
@@ -2502,10 +2566,11 @@
  * @return TRUE if successful, FALSE if unsuccessful
  */
 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;
 	gint cur_version;
+	gint status;
 
 	g_return_val_if_fail( be != NULL, FALSE );
 	g_return_val_if_fail( table_name != NULL, FALSE );
@@ -2521,7 +2586,11 @@
 								VERSION_COL_NAME, version,
 								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) );

Modified: gnucash/trunk/src/backend/sql/gnc-backend-sql.h
===================================================================
--- gnucash/trunk/src/backend/sql/gnc-backend-sql.h	2008-09-27 12:18:24 UTC (rev 17605)
+++ gnucash/trunk/src/backend/sql/gnc-backend-sql.h	2008-09-27 17:31:23 UTC (rev 17606)
@@ -159,16 +159,16 @@
 struct GncSqlConnection
 {
 	void (*dispose)( GncSqlConnection* );
-	GncSqlResult* (*executeSelectStatement)( GncSqlConnection*, GncSqlStatement* );
-	gint (*executeNonSelectStatement)( GncSqlConnection*, GncSqlStatement* );
+	GncSqlResult* (*executeSelectStatement)( GncSqlConnection*, GncSqlStatement* ); /**< Returns NULL if error */
+	gint (*executeNonSelectStatement)( GncSqlConnection*, GncSqlStatement* ); /**< Returns -1 if error */
 	GncSqlStatement* (*createStatementFromSql)( GncSqlConnection*, gchar* );
 	gboolean (*doesTableExist)( GncSqlConnection*, const gchar* );
-	void (*beginTransaction)( GncSqlConnection* );
-	void (*rollbackTransaction)( GncSqlConnection* );
-	void (*commitTransaction)( GncSqlConnection* );
+	gboolean (*beginTransaction)( GncSqlConnection* ); /**< Returns TRUE if successful, FALSE if error */
+	gboolean (*rollbackTransaction)( GncSqlConnection* ); /**< Returns TRUE if successful, FALSE if error */
+	gboolean (*commitTransaction)( GncSqlConnection* ); /**< Returns TRUE if successful, FALSE if error */
 	const gchar* (*getColumnTypeName)( GncSqlConnection*, GType, gint size );
-	void (*createTable)( GncSqlConnection*, const gchar*, const GList* );
-	void (*createIndex)( GncSqlConnection*, const gchar*, const gchar*, const GncSqlColumnTableEntry* );
+	gboolean (*createTable)( GncSqlConnection*, const gchar*, const GList* ); /**< Returns TRUE if successful, FALSE if error */
+	gboolean (*createIndex)( GncSqlConnection*, const gchar*, const gchar*, const GncSqlColumnTableEntry* ); /**< Returns TRUE if successful, FALSE if error */
 	gchar* (*quoteString)( const GncSqlConnection*, gchar* );
 };
 #define gnc_sql_connection_dispose(CONN) (CONN)->dispose(CONN)
@@ -251,8 +251,10 @@
 {
   int		version;		/**< Backend version number */
   const gchar *	type_name;	/**< Engine object type name */
-  /** Commit an instance of this object to the database */
-  void		(*commit)( GncSqlBackend* be, QofInstance* inst );
+  /** Commit an instance of this object to the database
+   * @return TRUE if successful, FALSE if error
+   */
+  gboolean	(*commit)( GncSqlBackend* be, QofInstance* inst );
   /** Load all objects of this type from the database */
   void		(*initial_load)( GncSqlBackend* be );
   /** Create database tables for this object */
@@ -263,8 +265,10 @@
   void		(*run_query)( GncSqlBackend* be, gpointer pQuery );
   /** Free a query on these objects */
   void		(*free_query)( GncSqlBackend* be, gpointer pQuery );
-  /** Write all objects of this type to the database */
-  void		(*write)( GncSqlBackend* be );
+  /** Write all objects of this type to the database
+   * @return TRUE if successful, FALSE if error
+   */
+  gboolean	(*write)( GncSqlBackend* be );
 } GncSqlObjectBackend;
 #define GNC_SQL_BACKEND             "gnc:sql:1"
 #define GNC_SQL_BACKEND_VERSION	1
@@ -417,31 +421,35 @@
 									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 statement Statement
- * @return Results
+ * @return Results, or NULL if an error has occured
  */
 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 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.
  *
  * @param be SQL backend struct
  * @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.
@@ -450,7 +458,7 @@
  * @param sql SQL char string
  * @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.
@@ -497,7 +505,7 @@
  * @param table_version Table version
  * @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,
 									gint table_version );
 
@@ -510,7 +518,7 @@
  * @param col_table DB table description
  * @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,
 								gint table_version,
 								const GncSqlColumnTableEntry* col_table );
@@ -535,8 +543,9 @@
  * @param index_name Index name
  * @param table_name Table name
  * @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 );
 
 /**
@@ -566,7 +575,7 @@
  * @param table_name Table name
  * @return Statement
  */
-GncSqlStatement* gnc_sql_create_select_statement( const GncSqlBackend* be,
+GncSqlStatement* gnc_sql_create_select_statement( GncSqlBackend* be,
 										const gchar* table_name );
 
 /**
@@ -656,8 +665,9 @@
  * @param tableName SQL table name
  * @param obj_name QOF object type name
  * @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 );
 
 void _retrieve_guid_( gpointer pObject, gpointer pValue );

Modified: gnucash/trunk/src/backend/sql/gnc-book-sql.c
===================================================================
--- gnucash/trunk/src/backend/sql/gnc-book-sql.c	2008-09-27 12:18:24 UTC (rev 17605)
+++ gnucash/trunk/src/backend/sql/gnc-book-sql.c	2008-09-27 17:31:23 UTC (rev 17606)
@@ -190,18 +190,18 @@
 }
 
 /* ================================================================= */
-void
+gboolean
 gnc_sql_save_book( GncSqlBackend* be, QofInstance* inst)
 {
     const GUID* guid;
 	gint op;
 	gboolean is_infant;
 
-	g_return_if_fail( be != NULL );
-	g_return_if_fail( inst != NULL );
-	g_return_if_fail( QOF_IS_BOOK(inst) );
+	g_return_val_if_fail( be != NULL, FALSE );
+	g_return_val_if_fail( inst != NULL, FALSE );
+	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 );
 }
 
 /* ================================================================= */

Modified: gnucash/trunk/src/backend/sql/gnc-book-sql.h
===================================================================
--- gnucash/trunk/src/backend/sql/gnc-book-sql.h	2008-09-27 12:18:24 UTC (rev 17605)
+++ gnucash/trunk/src/backend/sql/gnc-book-sql.h	2008-09-27 17:31:23 UTC (rev 17606)
@@ -33,6 +33,6 @@
 #include <gmodule.h>
 
 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_ */

Modified: gnucash/trunk/src/backend/sql/gnc-budget-sql.c
===================================================================
--- gnucash/trunk/src/backend/sql/gnc-budget-sql.c	2008-09-27 12:18:24 UTC (rev 17605)
+++ gnucash/trunk/src/backend/sql/gnc-budget-sql.c	2008-09-27 17:31:23 UTC (rev 17606)
@@ -135,17 +135,18 @@
 }
 
 /* ================================================================= */
-static void
+static gboolean
 save_budget( GncSqlBackend* be, QofInstance* inst )
 {
     GncBudget* pBudget = GNC_BUDGET(inst);
     const GUID* guid;
 	gint op;
 	gboolean is_infant;
+	gboolean is_ok;
 
-	g_return_if_fail( be != NULL );
-	g_return_if_fail( inst != NULL );
-	g_return_if_fail( GNC_IS_BUDGET(inst) );
+	g_return_val_if_fail( be != NULL, FALSE );
+	g_return_val_if_fail( inst != NULL, FALSE );
+	g_return_val_if_fail( GNC_IS_BUDGET(inst), FALSE );
 
 	is_infant = qof_instance_get_infant( inst );
 	if( qof_instance_get_destroying( inst ) ) {
@@ -155,32 +156,55 @@
 	} else {
 		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
-    guid = qof_instance_get_guid( inst );
-    if( !qof_instance_get_destroying(inst) ) {
-		gnc_sql_recurrence_save( be, guid, gnc_budget_get_recurrence( pBudget ) );
-        gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
-    } else {
-        gnc_sql_recurrence_delete( be, guid );
-        gnc_sql_slots_delete( be, guid );
-    }
+	if( is_ok ) {
+    	guid = qof_instance_get_guid( inst );
+    	if( !qof_instance_get_destroying(inst) ) {
+			is_ok = gnc_sql_recurrence_save( be, guid, gnc_budget_get_recurrence( pBudget ) );
+			if( is_ok ) {
+        		is_ok = gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
+			}
+    	} 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
 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 )
 {
-	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 ),
-                            (QofInstanceForeachCB)do_save_budget, be );
+                            (QofInstanceForeachCB)do_save_budget, &data );
+
+	return data.is_ok;
 }
 
 /* ================================================================= */

Modified: gnucash/trunk/src/backend/sql/gnc-commodity-sql.c
===================================================================
--- gnucash/trunk/src/backend/sql/gnc-commodity-sql.c	2008-09-27 12:18:24 UTC (rev 17605)
+++ gnucash/trunk/src/backend/sql/gnc-commodity-sql.c	2008-09-27 17:31:23 UTC (rev 17606)
@@ -169,16 +169,16 @@
 }
 
 /* ================================================================= */
-static void
+static gboolean
 commit_commodity( GncSqlBackend* be, QofInstance* inst )
 {
     const GUID* guid;
 
-	g_return_if_fail( be != NULL );
-	g_return_if_fail( inst != NULL );
-	g_return_if_fail( GNC_IS_COMMODITY(inst) );
+	g_return_val_if_fail( be != NULL, FALSE );
+	g_return_val_if_fail( inst != NULL, FALSE );
+	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
@@ -191,15 +191,19 @@
                                 pCommodity, col_table );
 }
 
-void
+gboolean
 gnc_sql_save_commodity( GncSqlBackend* be, gnc_commodity* pCommodity )
 {
-	g_return_if_fail( be != NULL );
-	g_return_if_fail( pCommodity != NULL );
+	gboolean is_ok = TRUE;
 
+	g_return_val_if_fail( be != NULL, FALSE );
+	g_return_val_if_fail( pCommodity != NULL, FALSE );
+
     if( !is_commodity_in_db( be, pCommodity ) ) {
-        commit_commodity( be, QOF_INSTANCE(pCommodity) );
+        is_ok = commit_commodity( be, QOF_INSTANCE(pCommodity) );
     }
+
+	return is_ok;
 }
 
 /* ----------------------------------------------------------------- */

Modified: gnucash/trunk/src/backend/sql/gnc-commodity-sql.h
===================================================================
--- gnucash/trunk/src/backend/sql/gnc-commodity-sql.h	2008-09-27 12:18:24 UTC (rev 17605)
+++ gnucash/trunk/src/backend/sql/gnc-commodity-sql.h	2008-09-27 17:31:23 UTC (rev 17606)
@@ -33,6 +33,6 @@
 #include <gmodule.h>
 
 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_ */

Modified: gnucash/trunk/src/backend/sql/gnc-lots-sql.c
===================================================================
--- gnucash/trunk/src/backend/sql/gnc-lots-sql.c	2008-09-27 12:18:24 UTC (rev 17605)
+++ gnucash/trunk/src/backend/sql/gnc-lots-sql.c	2008-09-27 17:31:23 UTC (rev 17606)
@@ -187,29 +187,43 @@
 
 /* ================================================================= */
 
-static void
+static gboolean
 commit_lot( GncSqlBackend* be, QofInstance* inst )
 {
-	g_return_if_fail( be != NULL );
-	g_return_if_fail( inst != NULL );
-	g_return_if_fail( GNC_IS_LOT(inst) );
+	g_return_val_if_fail( be != NULL, FALSE );
+	g_return_val_if_fail( inst != NULL, FALSE );
+	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
 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 )
 {
-	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 ),
-                            (QofInstanceForeachCB)do_save_lot, be );
+                            (QofInstanceForeachCB)do_save_lot, &data );
+	return data.is_ok;
 }
 
 /* ================================================================= */

Modified: gnucash/trunk/src/backend/sql/gnc-price-sql.c
===================================================================
--- gnucash/trunk/src/backend/sql/gnc-price-sql.c	2008-09-27 12:18:24 UTC (rev 17605)
+++ gnucash/trunk/src/backend/sql/gnc-price-sql.c	2008-09-27 17:31:23 UTC (rev 17606)
@@ -132,16 +132,17 @@
 
 /* ================================================================= */
 
-static void
+static gboolean
 save_price( GncSqlBackend* be, QofInstance* inst )
 {
     GNCPrice* pPrice = GNC_PRICE(inst);
 	gint op;
 	gboolean is_infant;
+	gboolean is_ok;
 
-	g_return_if_fail( be != NULL );
-	g_return_if_fail( inst != NULL );
-	g_return_if_fail( GNC_IS_PRICE(inst) );
+	g_return_val_if_fail( be != NULL, FALSE );
+	g_return_val_if_fail( inst != NULL, FALSE );
+	g_return_val_if_fail( GNC_IS_PRICE(inst), FALSE );
 
 	is_infant = qof_instance_get_infant( inst );
 	if( qof_instance_get_destroying( inst ) ) {
@@ -155,35 +156,49 @@
 	if( op != OP_DB_DELETE ) {
     	/* 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_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
 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( 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 )
 {
     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 );
 
-    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 );
 }
 
 /* ================================================================= */

Modified: gnucash/trunk/src/backend/sql/gnc-recurrence-sql.c
===================================================================
--- gnucash/trunk/src/backend/sql/gnc-recurrence-sql.c	2008-09-27 12:18:24 UTC (rev 17605)
+++ gnucash/trunk/src/backend/sql/gnc-recurrence-sql.c	2008-09-27 17:31:23 UTC (rev 17606)
@@ -173,21 +173,21 @@
 
 /* ================================================================= */
 
-void
+gboolean
 gnc_sql_recurrence_save( GncSqlBackend* be, const GUID* guid, const Recurrence* r )
 {
     recurrence_info_t recurrence_info;
 
-	g_return_if_fail( be != NULL );
-	g_return_if_fail( guid != NULL );
-	g_return_if_fail( r != NULL );
+	g_return_val_if_fail( be != NULL, FALSE );
+	g_return_val_if_fail( guid != NULL, FALSE );
+	g_return_val_if_fail( r != NULL, FALSE );
 
 	gnc_sql_recurrence_delete( be, guid );
 
     recurrence_info.be = be;
     recurrence_info.guid = guid;
 	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 );
 }
 
@@ -211,17 +211,17 @@
 	}
 }
 
-void
+gboolean
 gnc_sql_recurrence_delete( GncSqlBackend* be, const GUID* guid )
 {
     recurrence_info_t recurrence_info;
 
-	g_return_if_fail( be != NULL );
-	g_return_if_fail( guid != NULL );
+	g_return_val_if_fail( be != NULL, FALSE );
+	g_return_val_if_fail( guid != NULL, FALSE );
 
     recurrence_info.be = be;
     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 );
 }
 

Modified: gnucash/trunk/src/backend/sql/gnc-recurrence-sql.h
===================================================================
--- gnucash/trunk/src/backend/sql/gnc-recurrence-sql.h	2008-09-27 12:18:24 UTC (rev 17605)
+++ gnucash/trunk/src/backend/sql/gnc-recurrence-sql.h	2008-09-27 17:31:23 UTC (rev 17606)
@@ -32,9 +32,9 @@
 #include "qof.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_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_list( GncSqlBackend* be, const GUID* guid, GList** pSchedule );
 

Modified: gnucash/trunk/src/backend/sql/gnc-schedxaction-sql.c
===================================================================
--- gnucash/trunk/src/backend/sql/gnc-schedxaction-sql.c	2008-09-27 12:18:24 UTC (rev 17605)
+++ gnucash/trunk/src/backend/sql/gnc-schedxaction-sql.c	2008-09-27 17:31:23 UTC (rev 17606)
@@ -260,17 +260,18 @@
 }
 
 /* ================================================================= */
-void
+gboolean
 gnc_sql_save_schedxaction( GncSqlBackend* be, QofInstance* inst )
 {
     SchedXaction* pSx;
     const GUID* guid;
 	gint op;
 	gboolean is_infant;
+	gboolean is_ok;
 
-	g_return_if_fail( be != NULL );
-	g_return_if_fail( inst != NULL );
-	g_return_if_fail( GNC_IS_SX(inst) );
+	g_return_val_if_fail( be != NULL, FALSE );
+	g_return_val_if_fail( inst != NULL, FALSE );
+	g_return_val_if_fail( GNC_IS_SX(inst), FALSE );
 
     pSx = GNC_SX(inst);
 
@@ -282,16 +283,20 @@
 	} else {
 		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 );
 	gnc_sql_recurrence_save_list( be, guid, gnc_sx_get_schedule( pSx ) );
 
-    // Now, commit any slots
-    if( !qof_instance_get_destroying(inst) ) {
-        gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
-    } else {
-        gnc_sql_slots_delete( be, guid );
-    }
+	if( is_ok ) {
+    	// Now, commit any slots
+    	if( !qof_instance_get_destroying(inst) ) {
+        	is_ok = gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
+    	} else {
+        	is_ok = gnc_sql_slots_delete( be, guid );
+    	}
+	}
+
+	return is_ok;
 }
 
 /* ================================================================= */

Modified: gnucash/trunk/src/backend/sql/gnc-schedxaction-sql.h
===================================================================
--- gnucash/trunk/src/backend/sql/gnc-schedxaction-sql.h	2008-09-27 12:18:24 UTC (rev 17605)
+++ gnucash/trunk/src/backend/sql/gnc-schedxaction-sql.h	2008-09-27 17:31:23 UTC (rev 17606)
@@ -33,6 +33,6 @@
 #include <gmodule.h>
 
 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_ */

Modified: gnucash/trunk/src/backend/sql/gnc-slots-sql.c
===================================================================
--- gnucash/trunk/src/backend/sql/gnc-slots-sql.c	2008-09-27 12:18:24 UTC (rev 17605)
+++ gnucash/trunk/src/backend/sql/gnc-slots-sql.c	2008-09-27 17:31:23 UTC (rev 17606)
@@ -45,6 +45,7 @@
 typedef struct {
     GncSqlBackend* be;
     const GUID* guid;
+	gboolean is_ok;
     KvpFrame* pKvpFrame;
     KvpValueType value_type;
     KvpValue* pKvpValue;
@@ -324,11 +325,17 @@
 {
     slot_info_t* pSlot_info = (slot_info_t*)data;
     gint curlen;
+	gboolean is_ok = FALSE;
 
 	g_return_if_fail( key != NULL );
 	g_return_if_fail( value != 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;
     pSlot_info->pKvpValue = value;
     if( curlen != 0 ) {
@@ -340,21 +347,23 @@
         KvpFrame* pKvpFrame = kvp_value_get_frame( value );
         kvp_frame_for_each_slot( pKvpFrame, save_slot, pSlot_info );
     } else {
-        (void)gnc_sql_do_db_operation( pSlot_info->be, OP_DB_INSERT, TABLE_NAME,
-                                        TABLE_NAME, pSlot_info, col_table );
+        pSlot_info->is_ok = gnc_sql_do_db_operation( pSlot_info->be,
+												OP_DB_INSERT, TABLE_NAME,
+												TABLE_NAME, pSlot_info,
+												col_table );
     }
 
     g_string_truncate( pSlot_info->path, curlen );
 }
 
-void
+gboolean
 gnc_sql_slots_save( GncSqlBackend* be, const GUID* guid, gboolean is_infant, KvpFrame* pFrame )
 {
     slot_info_t slot_info;
 
-	g_return_if_fail( be != NULL );
-	g_return_if_fail( guid != NULL );
-	g_return_if_fail( pFrame != NULL );
+	g_return_val_if_fail( be != NULL, FALSE );
+	g_return_val_if_fail( guid != NULL, FALSE );
+	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( !be->is_pristine_db && !is_infant ) {
@@ -364,22 +373,28 @@
     slot_info.be = be;
     slot_info.guid = guid;
     slot_info.path = g_string_new( "" );
+	slot_info.is_ok = TRUE;
     kvp_frame_for_each_slot( pFrame, save_slot, &slot_info );
     g_string_free( slot_info.path, TRUE );
+
+	return slot_info.is_ok;
 }
 
-void
+gboolean
 gnc_sql_slots_delete( GncSqlBackend* be, const GUID* guid )
 {
     slot_info_t slot_info;
 
-	g_return_if_fail( be != NULL );
-	g_return_if_fail( guid != NULL );
+	g_return_val_if_fail( be != NULL, FALSE );
+	g_return_val_if_fail( guid != NULL, FALSE );
 
     slot_info.be = be;
     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 );
+
+	return slot_info.is_ok;
 }
 
 static void

Modified: gnucash/trunk/src/backend/sql/gnc-slots-sql.h
===================================================================
--- gnucash/trunk/src/backend/sql/gnc-slots-sql.h	2008-09-27 12:18:24 UTC (rev 17605)
+++ gnucash/trunk/src/backend/sql/gnc-slots-sql.h	2008-09-27 17:31:23 UTC (rev 17606)
@@ -33,14 +33,15 @@
 #include <gmodule.h>
 
 /**
-* gnc_sql_slots_save - Saves slots for an object to the db.
-*
-* @param be SQL backend
-* @param guid Object guid
-* @param is_infant Is this an infant object?
-* @param pFrame Top-level KVP frame
-*/
-void gnc_sql_slots_save( GncSqlBackend* be, const GUID* guid,
+ * gnc_sql_slots_save - Saves slots for an object to the db.
+ *
+ * @param be SQL backend
+ * @param guid Object guid
+ * @param is_infant Is this an infant object?
+ * @param pFrame Top-level KVP frame
+ * @return TRUE if successful, FALSE if error
+ */
+gboolean gnc_sql_slots_save( GncSqlBackend* be, const GUID* guid,
 					gboolean is_infant, KvpFrame* pFrame );
 
 /**
@@ -48,8 +49,9 @@
 *
 * @param be SQL backend
 * @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.

Modified: gnucash/trunk/src/backend/sql/gnc-transaction-sql.c
===================================================================
--- gnucash/trunk/src/backend/sql/gnc-transaction-sql.c	2008-09-27 12:18:24 UTC (rev 17605)
+++ gnucash/trunk/src/backend/sql/gnc-transaction-sql.c	2008-09-27 17:31:23 UTC (rev 17606)
@@ -57,6 +57,7 @@
 typedef struct {
     GncSqlBackend* be;
     const GUID* guid;
+	gboolean is_ok;
 } split_info_t;
 
 #define TX_MAX_NUM_LEN 2048
@@ -439,33 +440,41 @@
 	g_return_if_fail( GNC_IS_SPLIT(data) );
 	g_return_if_fail( user_data != NULL );
 
-    gnc_sql_slots_delete( split_info->be,
-                    qof_instance_get_guid( QOF_INSTANCE(pSplit) ) );
+	if( split_info->is_ok ) {
+    	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 )
 {
     split_info_t split_info;
 
-	g_return_if_fail( be != NULL );
-	g_return_if_fail( pTx != NULL );
+	g_return_val_if_fail( be != NULL, FALSE );
+	g_return_val_if_fail( pTx != NULL, FALSE );
 
-    (void)gnc_sql_do_db_operation( be, OP_DB_DELETE, SPLIT_TABLE,
-                                SPLIT_TABLE, pTx, guid_col_table );
+    if( !gnc_sql_do_db_operation( be, OP_DB_DELETE, SPLIT_TABLE,
+                                SPLIT_TABLE, pTx, guid_col_table ) ) {
+		return FALSE;
+	}
     split_info.be = be;
+	split_info.is_ok = TRUE;
 
     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 )
 {
 	gint op;
 	gboolean is_infant;
+	gboolean is_ok;
 
-	g_return_if_fail( inst != NULL );
-	g_return_if_fail( be != NULL );
+	g_return_val_if_fail( inst != NULL, FALSE );
+	g_return_val_if_fail( be != NULL, FALSE );
 
 	is_infant = qof_instance_get_infant( inst );
 	if( qof_instance_get_destroying( inst ) ) {
@@ -475,11 +484,15 @@
 	} else {
 		op = OP_DB_UPDATE;
 	}
-    (void)gnc_sql_do_db_operation( be, op, SPLIT_TABLE, GNC_ID_SPLIT, inst, split_col_table );
-    gnc_sql_slots_save( be,
+    is_ok = gnc_sql_do_db_operation( be, op, SPLIT_TABLE, GNC_ID_SPLIT, inst, split_col_table );
+	if( is_ok ) {
+		is_ok = gnc_sql_slots_save( be,
                         qof_instance_get_guid( inst ),
 						is_infant,
                         qof_instance_get_slots( inst ) );
+	}
+
+	return is_ok;
 }
 
 static void
@@ -492,33 +505,39 @@
 	g_return_if_fail( GNC_IS_SPLIT(data) );
 	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 )
 {
     split_info_t split_info;
 
-	g_return_if_fail( be != NULL );
-	g_return_if_fail( tx_guid != NULL );
-	g_return_if_fail( pSplitList != NULL );
+	g_return_val_if_fail( be != NULL, FALSE );
+	g_return_val_if_fail( tx_guid != NULL, FALSE );
+	g_return_val_if_fail( pSplitList != NULL, FALSE );
 
     split_info.be = be;
     split_info.guid = tx_guid;
+	split_info.is_ok = TRUE;
     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 )
 {
     const GUID* guid;
 	gint op;
 	gboolean is_infant;
 	QofInstance* inst;
+	gboolean is_ok = TRUE;
 
-	g_return_if_fail( be != NULL );
-	g_return_if_fail( pTx != NULL );
+	g_return_val_if_fail( be != NULL, FALSE );
+	g_return_val_if_fail( pTx != NULL, FALSE );
 
 	inst = QOF_INSTANCE(pTx);
 	is_infant = qof_instance_get_infant( inst );
@@ -532,42 +551,50 @@
 
 	if( op != OP_DB_DELETE ) {
     	// 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
-    guid = qof_instance_get_guid( inst );
-    if( !qof_instance_get_destroying(inst) ) {
-        gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
-		if( do_save_splits ) {
-			save_splits( be, guid, xaccTransGetSplitList( pTx ) );
-		}
-    } else {
-        gnc_sql_slots_delete( be, guid );
-    	delete_splits( be, pTx );
-    }
+	if( is_ok ) {
+    	// Commit slots and splits
+    	guid = qof_instance_get_guid( inst );
+    	if( !qof_instance_get_destroying(inst) ) {
+        	is_ok = gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
+			if( is_ok && do_save_splits ) {
+				is_ok = save_splits( be, guid, xaccTransGetSplitList( pTx ) );
+			}
+    	} else {
+        	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 )
 {
-	g_return_if_fail( be != NULL );
-	g_return_if_fail( inst != NULL );
-	g_return_if_fail( GNC_IS_TRANS(inst) );
+	g_return_val_if_fail( be != NULL, FALSE );
+	g_return_val_if_fail( inst != NULL, FALSE );
+	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 )
 {
-	g_return_if_fail( be != NULL );
-	g_return_if_fail( inst != NULL );
-	g_return_if_fail( GNC_IS_TRANS(inst) );
+	g_return_val_if_fail( be != NULL, FALSE );
+	g_return_val_if_fail( inst != NULL, FALSE );
+	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 );
 }
 
 /* ================================================================= */

Modified: gnucash/trunk/src/backend/sql/gnc-transaction-sql.h
===================================================================
--- gnucash/trunk/src/backend/sql/gnc-transaction-sql.h	2008-09-27 12:18:24 UTC (rev 17605)
+++ gnucash/trunk/src/backend/sql/gnc-transaction-sql.h	2008-09-27 17:31:23 UTC (rev 17606)
@@ -34,7 +34,7 @@
 
 void gnc_sql_init_transaction_handler( void );
 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, 
 								    gnc_numeric* start_balance,
 								    gnc_numeric* cleared_balance,

Modified: gnucash/trunk/src/business/business-core/sql/gnc-bill-term-sql.c
===================================================================
--- gnucash/trunk/src/business/business-core/sql/gnc-bill-term-sql.c	2008-09-27 12:18:24 UTC (rev 17605)
+++ gnucash/trunk/src/business/business-core/sql/gnc-bill-term-sql.c	2008-09-27 17:31:23 UTC (rev 17606)
@@ -143,18 +143,32 @@
 }
 
 /* ================================================================= */
+typedef struct {
+	GncSqlBackend* be;
+	gboolean is_ok;
+} write_billterms_t;
+
 static void
 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 )
 {
-	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 @@
 }
 
 /* ================================================================= */
-void
+gboolean
 gnc_sql_save_billterm( GncSqlBackend* be, QofInstance* inst )
 {
-	g_return_if_fail( inst != NULL );
-	g_return_if_fail( GNC_IS_BILLTERM(inst) );
-	g_return_if_fail( be != NULL );
+	g_return_val_if_fail( inst != NULL, FALSE );
+	g_return_val_if_fail( GNC_IS_BILLTERM(inst), FALSE );
+	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 );
 }
 
 /* ================================================================= */

Modified: gnucash/trunk/src/business/business-core/sql/gnc-bill-term-sql.h
===================================================================
--- gnucash/trunk/src/business/business-core/sql/gnc-bill-term-sql.h	2008-09-27 12:18:24 UTC (rev 17605)
+++ gnucash/trunk/src/business/business-core/sql/gnc-bill-term-sql.h	2008-09-27 17:31:23 UTC (rev 17606)
@@ -35,6 +35,6 @@
 #define CT_BILLTERMREF "billterm"
 
 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 */

Modified: gnucash/trunk/src/business/business-core/sql/gnc-customer-sql.c
===================================================================
--- gnucash/trunk/src/business/business-core/sql/gnc-customer-sql.c	2008-09-27 12:18:24 UTC (rev 17605)
+++ gnucash/trunk/src/business/business-core/sql/gnc-customer-sql.c	2008-09-27 17:31:23 UTC (rev 17606)
@@ -147,17 +147,22 @@
 }
 
 /* ================================================================= */
-static void
+static gboolean
 save_customer( GncSqlBackend* be, QofInstance* inst )
 {
-	g_return_if_fail( inst != NULL );
-	g_return_if_fail( GNC_CUSTOMER(inst) );
-	g_return_if_fail( be != NULL );
+	g_return_val_if_fail( inst != NULL, FALSE );
+	g_return_val_if_fail( GNC_CUSTOMER(inst), FALSE );
+	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
 customer_should_be_saved( GncCustomer *customer )
 {
@@ -175,25 +180,30 @@
 }
 
 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( 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) ) ) {
-    	save_customer( be, term_p );
+	if( customer_should_be_saved( GNC_CUSTOMER(term_p) ) && data->is_ok ) {
+    	data->is_ok = save_customer( data->be, term_p );
 	}
 }
 
-static void
+static gboolean
 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;
 }
 
 /* ================================================================= */

Modified: gnucash/trunk/src/business/business-core/sql/gnc-employee-sql.c
===================================================================
--- gnucash/trunk/src/business/business-core/sql/gnc-employee-sql.c	2008-09-27 12:18:24 UTC (rev 17605)
+++ gnucash/trunk/src/business/business-core/sql/gnc-employee-sql.c	2008-09-27 17:31:23 UTC (rev 17606)
@@ -144,17 +144,18 @@
 }
 
 /* ================================================================= */
-static void
+static gboolean
 save_employee( GncSqlBackend* be, QofInstance* inst )
 {
     GncEmployee* emp;
     const GUID* guid;
 	gint op;
 	gboolean is_infant;
+	gboolean is_ok = TRUE;
 
-	g_return_if_fail( inst != NULL );
-	g_return_if_fail( GNC_IS_EMPLOYEE(inst) );
-	g_return_if_fail( be != NULL );
+	g_return_val_if_fail( inst != NULL, FALSE );
+	g_return_val_if_fail( GNC_IS_EMPLOYEE(inst), FALSE );
+	g_return_val_if_fail( be != NULL, FALSE );
 
     emp = GNC_EMPLOYEE(inst);
 
@@ -168,18 +169,24 @@
 	}
 	if( op != OP_DB_DELETE ) {
     	// 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
-    guid = qof_instance_get_guid( inst );
-    if( !qof_instance_get_destroying(inst) ) {
-        gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
-    } else {
-        gnc_sql_slots_delete( be, guid );
-    }
+	if( is_ok ) {
+		// Now, commit or delete any slots
+    	guid = qof_instance_get_guid( inst );
+    	if( !qof_instance_get_destroying(inst) ) {
+        	is_ok = gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
+    	} else {
+        	is_ok = gnc_sql_slots_delete( be, guid );
+    	}
+	}
+
+	return is_ok;
 }
 
 /* ================================================================= */
@@ -198,26 +205,38 @@
 
     return TRUE;
 }
+
+typedef struct {
+	GncSqlBackend* be;
+	gboolean is_ok;
+} write_objects_t;
+
 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( 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) ) ) {
-    	save_employee( be, term_p );
+	if( s->is_ok && employee_should_be_saved( GNC_EMPLOYEE(term_p) ) ) {
+    	s->is_ok = save_employee( s->be, term_p );
 	}
 }
 
-static void
+static gboolean
 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;
 }
 
 /* ================================================================= */

Modified: gnucash/trunk/src/business/business-core/sql/gnc-entry-sql.c
===================================================================
--- gnucash/trunk/src/business/business-core/sql/gnc-entry-sql.c	2008-09-27 12:18:24 UTC (rev 17605)
+++ gnucash/trunk/src/business/business-core/sql/gnc-entry-sql.c	2008-09-27 17:31:23 UTC (rev 17606)
@@ -167,40 +167,51 @@
 }
 
 /* ================================================================= */
-static void
+static gboolean
 save_entry( GncSqlBackend* be, QofInstance* inst )
 {
-	g_return_if_fail( inst != NULL );
-	g_return_if_fail( GNC_IS_ENTRY(inst) );
-	g_return_if_fail( be != NULL );
+	g_return_val_if_fail( inst != NULL, FALSE );
+	g_return_val_if_fail( GNC_IS_ENTRY(inst), FALSE );
+	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
-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);
 
 	g_return_if_fail( term_p != NULL );
 	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 */
-  	if( gncEntryGetOrder( entry ) != NULL || gncEntryGetInvoice( entry ) != NULL ||
-			gncEntryGetBill( entry ) != NULL ) {
-    	save_entry( be, term_p );
+  	if( s->is_ok && (gncEntryGetOrder( entry ) != NULL || gncEntryGetInvoice( entry ) != NULL ||
+			gncEntryGetBill( entry ) != NULL) ) {
+    	s->is_ok = save_entry( s->be, term_p );
 	}
 }
 
-static void
+static gboolean
 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;
 }
 
 /* ================================================================= */

Modified: gnucash/trunk/src/business/business-core/sql/gnc-invoice-sql.c
===================================================================
--- gnucash/trunk/src/business/business-core/sql/gnc-invoice-sql.c	2008-09-27 12:18:24 UTC (rev 17605)
+++ gnucash/trunk/src/business/business-core/sql/gnc-invoice-sql.c	2008-09-27 17:31:23 UTC (rev 17606)
@@ -151,17 +151,18 @@
 }
 
 /* ================================================================= */
-static void
+static gboolean
 save_invoice( GncSqlBackend* be, QofInstance* inst )
 {
     const GUID* guid;
 	GncInvoice* invoice;
 	gint op;
 	gboolean is_infant;
+	gboolean is_ok = TRUE;
 
-	g_return_if_fail( inst != NULL );
-	g_return_if_fail( GNC_IS_INVOICE(inst) );
-	g_return_if_fail( be != NULL );
+	g_return_val_if_fail( inst != NULL, FALSE );
+	g_return_val_if_fail( GNC_IS_INVOICE(inst), FALSE );
+	g_return_val_if_fail( be != NULL, FALSE );
 
 	invoice = GNC_INVOICE(inst);
 
@@ -175,18 +176,24 @@
 	}
 	if( op != OP_DB_DELETE ) {
     	// 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
-    guid = qof_instance_get_guid( inst );
-    if( !qof_instance_get_destroying(inst) ) {
-        gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
-    } else {
-        gnc_sql_slots_delete( be, guid );
-    }
+	if( is_ok ) {
+    	// Now, commit or delete any slots
+    	guid = qof_instance_get_guid( inst );
+    	if( !qof_instance_get_destroying(inst) ) {
+        	is_ok = gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
+    	} else {
+        	is_ok = gnc_sql_slots_delete( be, guid );
+    	}
+	}
+
+	return is_ok;
 }
 
 /* ================================================================= */
@@ -206,26 +213,37 @@
     return TRUE;
 }
 
+typedef struct {
+	GncSqlBackend* be;
+	gboolean is_ok;
+} write_objects_t;
+
 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( 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) ) ) {
-    	save_invoice( be, term_p );
+	if( s->is_ok && invoice_should_be_saved( GNC_INVOICE(term_p) ) ) {
+    	s->is_ok = save_invoice( s->be, term_p );
 	}
 }
 
-static void
+static gboolean
 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;
 }
 
 /* ================================================================= */

Modified: gnucash/trunk/src/business/business-core/sql/gnc-job-sql.c
===================================================================
--- gnucash/trunk/src/business/business-core/sql/gnc-job-sql.c	2008-09-27 12:18:24 UTC (rev 17605)
+++ gnucash/trunk/src/business/business-core/sql/gnc-job-sql.c	2008-09-27 17:31:23 UTC (rev 17606)
@@ -134,14 +134,14 @@
 }
 
 /* ================================================================= */
-static void
+static gboolean
 save_job( GncSqlBackend* be, QofInstance* inst )
 {
-	g_return_if_fail( inst != NULL );
-	g_return_if_fail( GNC_IS_JOB(inst) );
-	g_return_if_fail( be != NULL );
+	g_return_val_if_fail( inst != NULL, FALSE );
+	g_return_val_if_fail( GNC_IS_JOB(inst), FALSE );
+	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 @@
     return TRUE;
 }
 
+typedef struct {
+	GncSqlBackend* be;
+	gboolean is_ok;
+} write_objects_t;
+
 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( 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) ) ) {
-    	save_job( be, term_p );
+	if( s->is_ok && job_should_be_saved( GNC_JOB(term_p) ) ) {
+    	s->is_ok = save_job( s->be, term_p );
 	}
 }
 
-static void
+static gboolean
 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;
 }
 
 /* ================================================================= */

Modified: gnucash/trunk/src/business/business-core/sql/gnc-order-sql.c
===================================================================
--- gnucash/trunk/src/business/business-core/sql/gnc-order-sql.c	2008-09-27 12:18:24 UTC (rev 17605)
+++ gnucash/trunk/src/business/business-core/sql/gnc-order-sql.c	2008-09-27 17:31:23 UTC (rev 17606)
@@ -135,14 +135,14 @@
 }
 
 /* ================================================================= */
-static void
+static gboolean
 save_order( GncSqlBackend* be, QofInstance* inst )
 {
-	g_return_if_fail( inst != NULL );
-	g_return_if_fail( GNC_IS_ORDER(inst) );
-	g_return_if_fail( be != NULL );
+	g_return_val_if_fail( inst != NULL, FALSE );
+	g_return_val_if_fail( GNC_IS_ORDER(inst), FALSE );
+	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 @@
     return TRUE;
 }
 
+typedef struct {
+	GncSqlBackend* be;
+	gboolean is_ok;
+} write_objects_t;
+
 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( 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) ) ) {
-    	save_order( be, term_p );
+	if( s->is_ok && order_should_be_saved( GNC_ORDER(term_p) ) ) {
+    	s->is_ok = save_order( s->be, term_p );
 	}
 }
 
-static void
+static gboolean
 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;
 }
 
 /* ================================================================= */

Modified: gnucash/trunk/src/business/business-core/sql/gnc-tax-table-sql.c
===================================================================
--- gnucash/trunk/src/business/business-core/sql/gnc-tax-table-sql.c	2008-09-27 12:18:24 UTC (rev 17605)
+++ gnucash/trunk/src/business/business-core/sql/gnc-tax-table-sql.c	2008-09-27 17:31:23 UTC (rev 17606)
@@ -268,52 +268,56 @@
 }
 
 /* ================================================================= */
-static void
+static gboolean
 delete_all_tt_entries( GncSqlBackend* be, const GUID* guid )
 {
     guid_info_t guid_info;
 
-	g_return_if_fail( be != NULL );
-	g_return_if_fail( guid != NULL );
+	g_return_val_if_fail( be != NULL, FALSE );
+	g_return_val_if_fail( guid != NULL, FALSE );
 
     guid_info.be = be;
     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 );
 }
 
-static void
+static gboolean
 save_tt_entries( GncSqlBackend* be, const GUID* guid, GList* entries )
 {
 	GList* entry;
+	gboolean is_ok;
 
-	g_return_if_fail( be != NULL );
-	g_return_if_fail( guid != NULL );
+	g_return_val_if_fail( be != NULL, FALSE );
+	g_return_val_if_fail( guid != NULL, FALSE );
 
     /* 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;
-    	(void)gnc_sql_do_db_operation( be,
-                        OP_DB_INSERT,
-                        TTENTRIES_TABLE_NAME,
-                        GNC_ID_TAXTABLE, e,
-                        ttentries_col_table );
+    	is_ok = gnc_sql_do_db_operation( be,
+                        			OP_DB_INSERT,
+                        			TTENTRIES_TABLE_NAME,
+                        			GNC_ID_TAXTABLE, e,
+                        			ttentries_col_table );
     }
+
+	return is_ok;
 }
 
-static void
+static gboolean
 save_taxtable( GncSqlBackend* be, QofInstance* inst )
 {
     GncTaxTable* tt;
     const GUID* guid;
 	gint op;
 	gboolean is_infant;
+	gboolean is_ok;
 
-	g_return_if_fail( inst != NULL );
-	g_return_if_fail( GNC_IS_TAXTABLE(inst) );
-	g_return_if_fail( be != NULL );
+	g_return_val_if_fail( inst != NULL, FALSE );
+	g_return_val_if_fail( GNC_IS_TAXTABLE(inst), FALSE );
+	g_return_val_if_fail( be != NULL, FALSE );
 
     tt = GNC_TAXTABLE(inst);
 
@@ -325,32 +329,55 @@
 	} else {
 		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
-    guid = qof_instance_get_guid( inst );
-    if( !qof_instance_get_destroying(inst) ) {
-        gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
-		save_tt_entries( be, guid, gncTaxTableGetEntries( tt ) );
-    } else {
-        gnc_sql_slots_delete( be, guid );
-		delete_all_tt_entries( be, guid );
-    }
+	if( is_ok ) {
+    	// Now, commit or delete any slots and tax table entries
+    	guid = qof_instance_get_guid( inst );
+    	if( !qof_instance_get_destroying(inst) ) {
+        	is_ok = gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
+			if( is_ok ) {
+				is_ok = save_tt_entries( be, guid, gncTaxTableGetEntries( tt ) );
+			}
+    	} 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
-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 )
 {
-	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;
 }
 
 /* ================================================================= */

Modified: gnucash/trunk/src/business/business-core/sql/gnc-vendor-sql.c
===================================================================
--- gnucash/trunk/src/business/business-core/sql/gnc-vendor-sql.c	2008-09-27 12:18:24 UTC (rev 17605)
+++ gnucash/trunk/src/business/business-core/sql/gnc-vendor-sql.c	2008-09-27 17:31:23 UTC (rev 17606)
@@ -148,17 +148,18 @@
 }
 
 /* ================================================================= */
-static void
+static gboolean
 save_vendor( GncSqlBackend* be, QofInstance* inst )
 {
     GncVendor* v;
     const GUID* guid;
 	gint op;
 	gboolean is_infant;
+	gboolean is_ok = TRUE;
 
-	g_return_if_fail( inst != NULL );
-	g_return_if_fail( GNC_IS_VENDOR(inst) );
-	g_return_if_fail( be != NULL );
+	g_return_val_if_fail( inst != NULL, FALSE );
+	g_return_val_if_fail( GNC_IS_VENDOR(inst), FALSE );
+	g_return_val_if_fail( be != NULL, FALSE );
 
     v = GNC_VENDOR(inst);
 
@@ -172,17 +173,23 @@
 	}
 	if( op != OP_DB_DELETE ) {
     	// Ensure the commodity is in the db
-    	gnc_sql_save_commodity( be, gncVendorGetCurrency( v ) );
+    	is_ok = gnc_sql_save_commodity( be, gncVendorGetCurrency( v ) );
 	}
-    (void)gnc_sql_do_db_operation( be, op, TABLE_NAME, GNC_ID_VENDOR, v, col_table );
+	if( is_ok ) {
+    	is_ok = gnc_sql_do_db_operation( be, op, TABLE_NAME, GNC_ID_VENDOR, v, col_table );
+	}
 
-    // Now, commit or delete any slots
-    guid = qof_instance_get_guid( inst );
-    if( !qof_instance_get_destroying(inst) ) {
-        gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
-    } else {
-        gnc_sql_slots_delete( be, guid );
-    }
+	if( is_ok ) {
+    	// Now, commit or delete any slots
+    	guid = qof_instance_get_guid( inst );
+    	if( !qof_instance_get_destroying(inst) ) {
+        	is_ok = gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
+    	} else {
+        	is_ok = gnc_sql_slots_delete( be, guid );
+    	}
+	}
+
+	return is_ok;
 }
 
 /* ================================================================= */
@@ -202,26 +209,37 @@
     return TRUE;
 }
 
+typedef struct {
+	GncSqlBackend* be;
+	gboolean is_ok;
+} write_objects_t;
+
 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( 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) ) ) {
-    	save_vendor( be, term_p );
+	if( s->is_ok && vendor_should_be_saved( GNC_VENDOR(term_p) ) ) {
+    	s->is_ok = save_vendor( s->be, term_p );
 	}
 }
 
-static void
+static gboolean
 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;
 }
 
 /* ================================================================= */



More information about the gnucash-changes mailing list