r17320 - gnucash/branches/gda-dev2 - 1) In business code, load all slots for all items of each item type with 1 query.

Phil Longstaff plongstaff at cvs.gnucash.org
Sat Jul 12 23:14:25 EDT 2008


Author: plongstaff
Date: 2008-07-12 23:14:24 -0400 (Sat, 12 Jul 2008)
New Revision: 17320
Trac: http://svn.gnucash.org/trac/changeset/17320

Modified:
   gnucash/branches/gda-dev2/GDA_STATUS
   gnucash/branches/gda-dev2/src/backend/dbi/gnc-backend-dbi.c
   gnucash/branches/gda-dev2/src/backend/sql/gnc-account-sql.c
   gnucash/branches/gda-dev2/src/backend/sql/gnc-backend-sql.c
   gnucash/branches/gda-dev2/src/backend/sql/gnc-backend-sql.h
   gnucash/branches/gda-dev2/src/backend/sql/gnc-book-sql.c
   gnucash/branches/gda-dev2/src/backend/sql/gnc-budget-sql.c
   gnucash/branches/gda-dev2/src/backend/sql/gnc-commodity-sql.c
   gnucash/branches/gda-dev2/src/backend/sql/gnc-lots-sql.c
   gnucash/branches/gda-dev2/src/backend/sql/gnc-price-sql.c
   gnucash/branches/gda-dev2/src/backend/sql/gnc-recurrence-sql.c
   gnucash/branches/gda-dev2/src/backend/sql/gnc-schedxaction-sql.c
   gnucash/branches/gda-dev2/src/backend/sql/gnc-slots-sql.c
   gnucash/branches/gda-dev2/src/backend/sql/gnc-transaction-sql.c
   gnucash/branches/gda-dev2/src/business/business-core/sql/gnc-bill-term-sql.c
   gnucash/branches/gda-dev2/src/business/business-core/sql/gnc-customer-sql.c
   gnucash/branches/gda-dev2/src/business/business-core/sql/gnc-employee-sql.c
   gnucash/branches/gda-dev2/src/business/business-core/sql/gnc-entry-sql.c
   gnucash/branches/gda-dev2/src/business/business-core/sql/gnc-invoice-sql.c
   gnucash/branches/gda-dev2/src/business/business-core/sql/gnc-job-sql.c
   gnucash/branches/gda-dev2/src/business/business-core/sql/gnc-order-sql.c
   gnucash/branches/gda-dev2/src/business/business-core/sql/gnc-tax-table-sql.c
   gnucash/branches/gda-dev2/src/business/business-core/sql/gnc-vendor-sql.c
Log:
1) In business code, load all slots for all items of each item type with 1 query.
2) Factor out simple of case of commit code and call from individual item cases where applicable.
3) When deleting an item that has a reference to a commodity, don't save the commodity to the db.
4) Start to add mysql and postgresql support in dbi backend.  The biggest differences are a) url
format (and information), and b) differences in data definition statements.



Modified: gnucash/branches/gda-dev2/GDA_STATUS
===================================================================
--- gnucash/branches/gda-dev2/GDA_STATUS	2008-07-13 00:04:16 UTC (rev 17319)
+++ gnucash/branches/gda-dev2/GDA_STATUS	2008-07-13 03:14:24 UTC (rev 17320)
@@ -23,6 +23,6 @@
 This can result in trying to save invalid objects:
 	- Price editor (new price has no commodity or currency)
 	- New invoice
-* Use the "infant" flag to avoid checking whether a new object is already in
-the db.
 * Need transactions to group updates to multiple objects
+* Possibly mark commodities that are in the db so that they don't need to be
+queried every time.

Modified: gnucash/branches/gda-dev2/src/backend/dbi/gnc-backend-dbi.c
===================================================================
--- gnucash/branches/gda-dev2/src/backend/dbi/gnc-backend-dbi.c	2008-07-13 00:04:16 UTC (rev 17319)
+++ gnucash/branches/gda-dev2/src/backend/dbi/gnc-backend-dbi.c	2008-07-13 03:14:24 UTC (rev 17320)
@@ -83,12 +83,58 @@
 }
 
 static void
-gnc_dbi_session_begin( QofBackend *qbe, QofSession *session, 
+gnc_dbi_sqlite3_session_begin( QofBackend *qbe, QofSession *session, 
 	                   const gchar *book_id,
                        gboolean ignore_lock,
 				       gboolean create_if_nonexistent )
 {
     GncDbiBackend *be = (GncDbiBackend*)qbe;
+	gint result;
+	gchar* dirname;
+	gchar* basename;
+
+	g_return_if_fail( qbe != NULL );
+	g_return_if_fail( session != NULL );
+	g_return_if_fail( book_id != NULL );
+
+    ENTER (" ");
+
+	dirname = g_path_get_dirname( book_id );
+	basename = g_path_get_basename( book_id );
+
+	be->conn = dbi_conn_new( "sqlite3" );
+	if( be->conn == NULL ) {
+		PERR( "Unable to create sqlite3 dbi connection\n" );
+        qof_backend_set_error( qbe, ERR_BACKEND_BAD_URL );
+		LEAVE( " " );
+		return;
+	}
+	dbi_conn_error_handler( be->conn, error_fn, be );
+	dbi_conn_set_option( be->conn, "host", "localhost" );
+	dbi_conn_set_option( be->conn, "dbname", basename );
+	dbi_conn_set_option( be->conn, "sqlite3_dbdir", dirname );
+	result = dbi_conn_connect( be->conn );
+	g_free( basename );
+	g_free( dirname );
+	if( result < 0 ) {
+		PERR( "Unable to connect to %s: %d\n", book_id, result );
+        qof_backend_set_error( qbe, ERR_BACKEND_BAD_URL );
+        LEAVE( " " );
+        return;
+	}
+
+	be->sql_be.conn = create_dbi_connection( be->conn );
+
+    LEAVE (" ");
+}
+
+static void
+gnc_dbi_mysql_session_begin( QofBackend *qbe, QofSession *session, 
+	                   const gchar *book_id,
+                       gboolean ignore_lock,
+				       gboolean create_if_nonexistent )
+{
+    GncDbiBackend *be = (GncDbiBackend*)qbe;
     GError* error = NULL;
     gchar* dsn;
     gchar* username;
@@ -134,6 +180,58 @@
     LEAVE (" ");
 }
 
+static void
+gnc_dbi_postgres_session_begin( QofBackend *qbe, QofSession *session, 
+	                   const gchar *book_id,
+                       gboolean ignore_lock,
+				       gboolean create_if_nonexistent )
+{
+    GncDbiBackend *be = (GncDbiBackend*)qbe;
+    GError* error = NULL;
+    gchar* dsn;
+    gchar* username;
+    gchar* password;
+	gchar* provider;
+	gboolean uriOK;
+	gint result;
+	gchar* dirname;
+	gchar* basename;
+
+	g_return_if_fail( qbe != NULL );
+	g_return_if_fail( session != NULL );
+	g_return_if_fail( book_id != NULL );
+
+    ENTER (" ");
+
+	dirname = g_path_get_dirname( book_id );
+	basename = g_path_get_basename( book_id );
+
+	be->conn = dbi_conn_new( "sqlite3" );
+	if( be->conn == NULL ) {
+		PERR( "Unable to create sqlite3 dbi connection\n" );
+        qof_backend_set_error( qbe, ERR_BACKEND_BAD_URL );
+		LEAVE( " " );
+		return;
+	}
+	dbi_conn_error_handler( be->conn, error_fn, be );
+	dbi_conn_set_option( be->conn, "host", "localhost" );
+	dbi_conn_set_option( be->conn, "dbname", basename );
+	dbi_conn_set_option( be->conn, "sqlite3_dbdir", dirname );
+	result = dbi_conn_connect( be->conn );
+	g_free( basename );
+	g_free( dirname );
+	if( result < 0 ) {
+		PERR( "Unable to connect to %s: %d\n", book_id, result );
+        qof_backend_set_error( qbe, ERR_BACKEND_BAD_URL );
+        LEAVE( " " );
+        return;
+	}
+
+	be->sql_be.conn = create_dbi_connection( be->conn );
+
+    LEAVE (" ");
+}
+
 /* ================================================================= */
 
 static void
@@ -280,18 +378,14 @@
 
 /* ================================================================= */
 
-static QofBackend*
-gnc_dbi_backend_new(void)
+static void
+init_sql_backend( GncDbiBackend* dbi_be )
 {
-    GncDbiBackend *gnc_be;
-    QofBackend *be;
     static gboolean initialized = FALSE;
+	QofBackend* be;
 
-    gnc_be = g_new0(GncDbiBackend, 1);
-    be = (QofBackend*) gnc_be;
-    qof_backend_init(be);
+    be = (QofBackend*)dbi_be;
 
-    be->session_begin = gnc_dbi_session_begin;
     be->session_end = gnc_dbi_session_end;
     be->destroy_backend = gnc_dbi_destroy_backend;
 
@@ -315,8 +409,6 @@
 
     be->export = NULL;
 
-    gnc_be->primary_book = NULL;
-
     if( !initialized ) {
 #define DEFAULT_DBD_DIR "/usr/lib/dbd"
 		const gchar* driver_dir;
@@ -342,13 +434,59 @@
 				}
 			} while( driver != NULL );
 		}
-		gnc_sql_init( &gnc_be->sql_be );
+		gnc_sql_init( &dbi_be->sql_be );
         initialized = TRUE;
     }
+}
 
+static QofBackend*
+gnc_dbi_backend_sqlite3_new( void )
+{
+    GncDbiBackend *dbi_be;
+    QofBackend *be;
+
+    dbi_be = g_new0( GncDbiBackend, 1 );
+    be = (QofBackend*)dbi_be;
+    qof_backend_init( be );
+
+    be->session_begin = gnc_dbi_sqlite3_session_begin;
+	init_sql_backend( dbi_be );
+
     return be;
 }
 
+static QofBackend*
+gnc_dbi_backend_mysql_new( void )
+{
+    GncDbiBackend *dbi_be;
+    QofBackend *be;
+
+    dbi_be = g_new0( GncDbiBackend, 1 );
+    be = (QofBackend*)dbi_be;
+    qof_backend_init( be );
+
+    be->session_begin = gnc_dbi_mysql_session_begin;
+	init_sql_backend( dbi_be );
+
+    return be;
+}
+
+static QofBackend*
+gnc_dbi_backend_postgres_new( void )
+{
+    GncDbiBackend *dbi_be;
+    QofBackend *be;
+
+    dbi_be = g_new0( GncDbiBackend, 1 );
+    be = (QofBackend*)dbi_be;
+    qof_backend_init( be );
+
+    be->session_begin = gnc_dbi_postgres_session_begin;
+	init_sql_backend( dbi_be );
+
+    return be;
+}
+
 static void
 gnc_dbi_provider_free( QofBackendProvider *prov )
 {
@@ -364,7 +502,7 @@
  *
  */
 static gboolean
-gnc_dbi_check_sqlite_file( const gchar *path )
+gnc_dbi_check_sqlite3_file( const gchar *path )
 {
 	FILE* f;
 	gchar buf[50];
@@ -399,13 +537,29 @@
     QofBackendProvider *prov;
 
     prov = g_new0 (QofBackendProvider, 1);
-    prov->provider_name = "GnuCash Libdbi Backend";
+    prov->provider_name = "GnuCash Libdbi (SQLITE3) Backend";
     prov->access_method = "file";
     prov->partial_book_supported = FALSE;
-    prov->backend_new = gnc_dbi_backend_new;
+    prov->backend_new = gnc_dbi_backend_sqlite3_new;
     prov->provider_free = gnc_dbi_provider_free;
-    prov->check_data_type = gnc_dbi_check_sqlite_file;
-    qof_backend_register_provider (prov);
+    prov->check_data_type = gnc_dbi_check_sqlite3_file;
+    qof_backend_register_provider( prov );
+
+    prov = g_new0 (QofBackendProvider, 1);
+    prov->provider_name = "GnuCash Libdbi (MYSQL) Backend";
+    prov->access_method = "mysql";
+    prov->partial_book_supported = FALSE;
+    prov->backend_new = gnc_dbi_backend_mysql_new;
+    prov->provider_free = gnc_dbi_provider_free;
+    qof_backend_register_provider( prov );
+
+    prov = g_new0 (QofBackendProvider, 1);
+    prov->provider_name = "GnuCash Libdbi (POSTGRESQL) Backend";
+    prov->access_method = "postgres";
+    prov->partial_book_supported = FALSE;
+    prov->backend_new = gnc_dbi_backend_postgres_new;
+    prov->provider_free = gnc_dbi_provider_free;
+    qof_backend_register_provider( prov );
 }
 
 /* --------------------------------------------------------- */

Modified: gnucash/branches/gda-dev2/src/backend/sql/gnc-account-sql.c
===================================================================
--- gnucash/branches/gda-dev2/src/backend/sql/gnc-account-sql.c	2008-07-13 00:04:16 UTC (rev 17319)
+++ gnucash/branches/gda-dev2/src/backend/sql/gnc-account-sql.c	2008-07-13 03:14:24 UTC (rev 17320)
@@ -283,17 +283,19 @@
     if( xaccAccountGetCommodity( pAcc ) != NULL ) {
 		gint op;
 
-        // Ensure the commodity is in the db
-        gnc_sql_save_commodity( be, xaccAccountGetCommodity( pAcc ) );
-
 		if( qof_instance_get_destroying( inst ) ) {
 			op = OP_DB_DELETE;
 		} else if( be->is_pristine_db || is_infant ) {
-			op = OP_DB_ADD;
+			op = OP_DB_INSERT;
 		} else {
-			op = OP_DB_ADD_OR_UPDATE;
+			op = OP_DB_UPDATE;
 		}
 
+        // If not deleting the account, ensure the commodity is in the db
+		if( op != OP_DB_DELETE ) {
+        	gnc_sql_save_commodity( be, xaccAccountGetCommodity( pAcc ) );
+		}
+
         (void)gnc_sql_do_db_operation( be, op, TABLE_NAME, GNC_ID_ACCOUNT, pAcc, col_table );
 
         // Now, commit or delete any slots

Modified: gnucash/branches/gda-dev2/src/backend/sql/gnc-backend-sql.c
===================================================================
--- gnucash/branches/gda-dev2/src/backend/sql/gnc-backend-sql.c	2008-07-13 00:04:16 UTC (rev 17319)
+++ gnucash/branches/gda-dev2/src/backend/sql/gnc-backend-sql.c	2008-07-13 03:14:24 UTC (rev 17320)
@@ -2126,16 +2126,12 @@
 	g_return_val_if_fail( pObject != NULL, FALSE );
 	g_return_val_if_fail( table != NULL, FALSE );
 
-    if( op == OP_DB_ADD_OR_UPDATE ) {
-        if( gnc_sql_object_is_it_in_db( be, table_name, obj_name, pObject, table ) ) {
-            stmt = build_update_statement( be, table_name, obj_name, pObject, table );
-        } else {
-            stmt = build_insert_statement( be, table_name, obj_name, pObject, table );
-        }
+	if( op == OP_DB_INSERT ) {
+        stmt = build_insert_statement( be, table_name, obj_name, pObject, table );
+    } else if( op == OP_DB_UPDATE ) {
+        stmt = build_update_statement( be, table_name, obj_name, pObject, table );
     } else if( op == OP_DB_DELETE ) {
         stmt = build_delete_statement( be, table_name, obj_name, pObject, table );
-    } else if( op == OP_DB_ADD ) {
-        stmt = build_insert_statement( be, table_name, obj_name, pObject, table );
     } else {
         g_assert( FALSE );
     }
@@ -2336,7 +2332,35 @@
 }
 
 /* ================================================================= */
+void
+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;
 
+	is_infant = qof_instance_get_infant( inst );
+	if( qof_instance_get_destroying( inst ) ) {
+		op = OP_DB_DELETE;
+	} else if( be->is_pristine_db || is_infant ) {
+		op = OP_DB_INSERT;
+	} else {
+		op = OP_DB_UPDATE;
+	}
+    (void)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 );
+    }
+}
+
+/* ================================================================= */
+
 static gboolean
 create_table( const GncSqlBackend* be, const gchar* table_name,
 				const GncSqlColumnTableEntry* col_table )

Modified: gnucash/branches/gda-dev2/src/backend/sql/gnc-backend-sql.h
===================================================================
--- gnucash/branches/gda-dev2/src/backend/sql/gnc-backend-sql.h	2008-07-13 00:04:16 UTC (rev 17319)
+++ gnucash/branches/gda-dev2/src/backend/sql/gnc-backend-sql.h	2008-07-13 03:14:24 UTC (rev 17320)
@@ -319,8 +319,8 @@
 };
 
 typedef enum {
-	OP_DB_ADD,
-	OP_DB_ADD_OR_UPDATE,
+	OP_DB_INSERT,
+	OP_DB_UPDATE,
 	OP_DB_DELETE
 } E_DB_OPERATION;
 
@@ -573,6 +573,20 @@
  */
 void gnc_sql_finalize_version_info( GncSqlBackend* be );
 
+/**
+ *
+ * Commits a "standard" item to the database.  In most cases, a commit of one object vs
+ * another differs only in the table name and column table.
+ *
+ * @param be SQL backend
+ * @param inst Instance
+ * @param tableName SQL table name
+ * @param obj_name QOF object type name
+ * @param col_table Column table
+ */
+void 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 );
 
 #endif /* GNC_BACKEND_SQL_H_ */

Modified: gnucash/branches/gda-dev2/src/backend/sql/gnc-book-sql.c
===================================================================
--- gnucash/branches/gda-dev2/src/backend/sql/gnc-book-sql.c	2008-07-13 00:04:16 UTC (rev 17319)
+++ gnucash/branches/gda-dev2/src/backend/sql/gnc-book-sql.c	2008-07-13 03:14:24 UTC (rev 17320)
@@ -201,25 +201,7 @@
 	g_return_if_fail( inst != NULL );
 	g_return_if_fail( QOF_IS_BOOK(inst) );
 
-	is_infant = qof_instance_get_infant( inst );
-	if( qof_instance_get_destroying( inst ) ) {
-		op = OP_DB_DELETE;
-	} else if( be->is_pristine_db || is_infant ) {
-		op = OP_DB_ADD;
-	} else {
-		op = OP_DB_ADD_OR_UPDATE;
-	}
-    (void)gnc_sql_do_db_operation( be, op, BOOK_TABLE, GNC_ID_BOOK, inst, col_table );
-
-    // Delete old slot info
-    guid = qof_instance_get_guid( inst );
-
-    // 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 );
-    }
+	gnc_sql_commit_standard_item( be, inst, BOOK_TABLE, GNC_ID_BOOK, col_table );
 }
 
 /* ================================================================= */

Modified: gnucash/branches/gda-dev2/src/backend/sql/gnc-budget-sql.c
===================================================================
--- gnucash/branches/gda-dev2/src/backend/sql/gnc-budget-sql.c	2008-07-13 00:04:16 UTC (rev 17319)
+++ gnucash/branches/gda-dev2/src/backend/sql/gnc-budget-sql.c	2008-07-13 03:14:24 UTC (rev 17320)
@@ -151,9 +151,9 @@
 	if( qof_instance_get_destroying( inst ) ) {
 		op = OP_DB_DELETE;
 	} else if( be->is_pristine_db || is_infant ) {
-		op = OP_DB_ADD;
+		op = OP_DB_INSERT;
 	} else {
-		op = OP_DB_ADD_OR_UPDATE;
+		op = OP_DB_UPDATE;
 	}
     (void)gnc_sql_do_db_operation( be, op, BUDGET_TABLE, GNC_ID_BUDGET, pBudget, col_table );
 

Modified: gnucash/branches/gda-dev2/src/backend/sql/gnc-commodity-sql.c
===================================================================
--- gnucash/branches/gda-dev2/src/backend/sql/gnc-commodity-sql.c	2008-07-13 00:04:16 UTC (rev 17319)
+++ gnucash/branches/gda-dev2/src/backend/sql/gnc-commodity-sql.c	2008-07-13 03:14:24 UTC (rev 17320)
@@ -185,31 +185,12 @@
 commit_commodity( 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( GNC_IS_COMMODITY(inst) );
 
-	is_infant = qof_instance_get_infant( inst );
-	if( qof_instance_get_destroying( inst ) ) {
-		op = OP_DB_DELETE;
-	} else if( be->is_pristine_db || is_infant ) {
-		op = OP_DB_ADD;
-	} else {
-		op = OP_DB_ADD_OR_UPDATE;
-	}
-    (void)gnc_sql_do_db_operation( be, op, COMMODITIES_TABLE, GNC_ID_COMMODITY, inst, col_table );
-
-    // Delete old slot info
-    guid = qof_instance_get_guid( inst );
-    // Now, commit or delete 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 );
-    }
+    gnc_sql_commit_standard_item( be, inst, COMMODITIES_TABLE, GNC_ID_COMMODITY, col_table );
 }
 
 static gboolean

Modified: gnucash/branches/gda-dev2/src/backend/sql/gnc-lots-sql.c
===================================================================
--- gnucash/branches/gda-dev2/src/backend/sql/gnc-lots-sql.c	2008-07-13 00:04:16 UTC (rev 17319)
+++ gnucash/branches/gda-dev2/src/backend/sql/gnc-lots-sql.c	2008-07-13 03:14:24 UTC (rev 17320)
@@ -166,31 +166,11 @@
 static void
 commit_lot( GncSqlBackend* be, QofInstance* inst )
 {
-	gint op;
-	gboolean is_infant;
-
 	g_return_if_fail( be != NULL );
 	g_return_if_fail( inst != NULL );
 	g_return_if_fail( GNC_IS_LOT(inst) );
 
-	is_infant = qof_instance_get_infant( inst );
-	if( qof_instance_get_destroying( inst ) ) {
-		op = OP_DB_DELETE;
-	} else if( be->is_pristine_db || is_infant ) {
-		op = OP_DB_ADD;
-	} else {
-		op = OP_DB_ADD_OR_UPDATE;
-	}
-    (void)gnc_sql_do_db_operation( be, op, TABLE_NAME, GNC_ID_LOT, inst, col_table );
-
-    // Now, commit any slots
-	if( !qof_instance_get_destroying( inst ) ) {
-    	gnc_sql_slots_save( be, qof_instance_get_guid( inst ),
-							is_infant,
-                        	qof_instance_get_slots( inst ) );
-	} else {
-    	gnc_sql_slots_delete( be, qof_instance_get_guid( inst ) );
-	}
+    gnc_sql_commit_standard_item( be, inst, TABLE_NAME, GNC_ID_LOT, col_table );
 }
 
 /* ----------------------------------------------------------------- */

Modified: gnucash/branches/gda-dev2/src/backend/sql/gnc-price-sql.c
===================================================================
--- gnucash/branches/gda-dev2/src/backend/sql/gnc-price-sql.c	2008-07-13 00:04:16 UTC (rev 17319)
+++ gnucash/branches/gda-dev2/src/backend/sql/gnc-price-sql.c	2008-07-13 03:14:24 UTC (rev 17320)
@@ -143,18 +143,21 @@
 	g_return_if_fail( inst != NULL );
 	g_return_if_fail( GNC_IS_PRICE(inst) );
 
-    /* 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_infant = qof_instance_get_infant( inst );
 	if( qof_instance_get_destroying( inst ) ) {
 		op = OP_DB_DELETE;
 	} else if( be->is_pristine_db || is_infant ) {
-		op = OP_DB_ADD;
+		op = OP_DB_INSERT;
 	} else {
-		op = OP_DB_ADD_OR_UPDATE;
+		op = OP_DB_UPDATE;
 	}
+
+	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 ) );
+	}
+
     (void)gnc_sql_do_db_operation( be, op, TABLE_NAME, GNC_ID_PRICE, pPrice, col_table );
 }
 

Modified: gnucash/branches/gda-dev2/src/backend/sql/gnc-recurrence-sql.c
===================================================================
--- gnucash/branches/gda-dev2/src/backend/sql/gnc-recurrence-sql.c	2008-07-13 00:04:16 UTC (rev 17319)
+++ gnucash/branches/gda-dev2/src/backend/sql/gnc-recurrence-sql.c	2008-07-13 03:14:24 UTC (rev 17320)
@@ -187,7 +187,7 @@
     recurrence_info.be = be;
     recurrence_info.guid = guid;
 	recurrence_info.pRecurrence = (Recurrence*)r;
-    (void)gnc_sql_do_db_operation( be, OP_DB_ADD, TABLE_NAME,
+    (void)gnc_sql_do_db_operation( be, OP_DB_INSERT, TABLE_NAME,
                                 TABLE_NAME, &recurrence_info, col_table );
 }
 
@@ -206,7 +206,7 @@
     recurrence_info.guid = guid;
 	for( l = schedule; l != NULL; l = g_list_next( l ) ) {
 		recurrence_info.pRecurrence = (Recurrence*)l->data;
-    	(void)gnc_sql_do_db_operation( be, OP_DB_ADD, TABLE_NAME,
+    	(void)gnc_sql_do_db_operation( be, OP_DB_INSERT, TABLE_NAME,
                                 TABLE_NAME, &recurrence_info, col_table );
 	}
 }

Modified: gnucash/branches/gda-dev2/src/backend/sql/gnc-schedxaction-sql.c
===================================================================
--- gnucash/branches/gda-dev2/src/backend/sql/gnc-schedxaction-sql.c	2008-07-13 00:04:16 UTC (rev 17319)
+++ gnucash/branches/gda-dev2/src/backend/sql/gnc-schedxaction-sql.c	2008-07-13 03:14:24 UTC (rev 17320)
@@ -263,22 +263,24 @@
 void
 gnc_sql_save_schedxaction( GncSqlBackend* be, QofInstance* inst )
 {
-    SchedXaction* pSx = GNC_SX(inst);
+    SchedXaction* pSx;
     const GUID* guid;
 	gint op;
 	gboolean is_infant;
 
+	g_return_if_fail( be != NULL );
 	g_return_if_fail( inst != NULL );
 	g_return_if_fail( GNC_IS_SX(inst) );
-	g_return_if_fail( be != NULL );
 
+    pSx = GNC_SX(inst);
+
 	is_infant = qof_instance_get_infant( inst );
 	if( qof_instance_get_destroying( inst ) ) {
 		op = OP_DB_DELETE;
 	} else if( be->is_pristine_db || is_infant ) {
-		op = OP_DB_ADD;
+		op = OP_DB_INSERT;
 	} else {
-		op = OP_DB_ADD_OR_UPDATE;
+		op = OP_DB_UPDATE;
 	}
     (void)gnc_sql_do_db_operation( be, op, SCHEDXACTION_TABLE, GNC_SX_ID, pSx, col_table );
     guid = qof_instance_get_guid( inst );

Modified: gnucash/branches/gda-dev2/src/backend/sql/gnc-slots-sql.c
===================================================================
--- gnucash/branches/gda-dev2/src/backend/sql/gnc-slots-sql.c	2008-07-13 00:04:16 UTC (rev 17319)
+++ gnucash/branches/gda-dev2/src/backend/sql/gnc-slots-sql.c	2008-07-13 03:14:24 UTC (rev 17320)
@@ -340,7 +340,7 @@
         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_ADD, TABLE_NAME,
+        (void)gnc_sql_do_db_operation( pSlot_info->be, OP_DB_INSERT, TABLE_NAME,
                                         TABLE_NAME, pSlot_info, col_table );
     }
 

Modified: gnucash/branches/gda-dev2/src/backend/sql/gnc-transaction-sql.c
===================================================================
--- gnucash/branches/gda-dev2/src/backend/sql/gnc-transaction-sql.c	2008-07-13 00:04:16 UTC (rev 17319)
+++ gnucash/branches/gda-dev2/src/backend/sql/gnc-transaction-sql.c	2008-07-13 03:14:24 UTC (rev 17320)
@@ -471,9 +471,9 @@
 	if( qof_instance_get_destroying( inst ) ) {
 		op = OP_DB_DELETE;
 	} else if( be->is_pristine_db || is_infant ) {
-		op = OP_DB_ADD;
+		op = OP_DB_INSERT;
 	} else {
-		op = OP_DB_ADD_OR_UPDATE;
+		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,
@@ -521,18 +521,20 @@
 	g_return_if_fail( GNC_IS_TRANS(inst) );
 	g_return_if_fail( be != NULL );
 
-    // Ensure the commodity is in the db
-    gnc_sql_save_commodity( be, xaccTransGetCurrency( pTx ) );
-
 	is_infant = qof_instance_get_infant( inst );
 	if( qof_instance_get_destroying( inst ) ) {
 		op = OP_DB_DELETE;
 	} else if( be->is_pristine_db || is_infant ) {
-		op = OP_DB_ADD;
+		op = OP_DB_INSERT;
 	} else {
-		op = OP_DB_ADD_OR_UPDATE;
+		op = OP_DB_UPDATE;
 	}
 
+	if( op != OP_DB_DELETE ) {
+    	// Ensure the commodity is in the db
+    	gnc_sql_save_commodity( be, xaccTransGetCurrency( pTx ) );
+	}
+
     (void)gnc_sql_do_db_operation( be, op, TRANSACTION_TABLE, GNC_ID_TRANS, pTx, tx_col_table );
 
     guid = qof_instance_get_guid( inst );

Modified: gnucash/branches/gda-dev2/src/business/business-core/sql/gnc-bill-term-sql.c
===================================================================
--- gnucash/branches/gda-dev2/src/business/business-core/sql/gnc-bill-term-sql.c	2008-07-13 00:04:16 UTC (rev 17319)
+++ gnucash/branches/gda-dev2/src/business/business-core/sql/gnc-bill-term-sql.c	2008-07-13 03:14:24 UTC (rev 17320)
@@ -88,14 +88,14 @@
 	}
 }
 
-static void
+static GncBillTerm*
 load_single_billterm( GncSqlBackend* be, GncSqlRow* row )
 {
     const GUID* guid;
 	GncBillTerm* pBillTerm;
 
-	g_return_if_fail( be != NULL );
-	g_return_if_fail( row != NULL );
+	g_return_val_if_fail( be != NULL, NULL );
+	g_return_val_if_fail( row != NULL, NULL );
 
     guid = gnc_sql_load_guid( be, row );
     pBillTerm = gncBillTermLookup( be->primary_book, guid );
@@ -103,9 +103,9 @@
         pBillTerm = gncBillTermCreate( be->primary_book );
     }
     gnc_sql_load_object( be, row, GNC_ID_BILLTERM, pBillTerm, col_table );
-    gnc_sql_slots_load( be, QOF_INSTANCE( pBillTerm ) );
-
     qof_instance_mark_clean( QOF_INSTANCE(pBillTerm) );
+
+	return pBillTerm;
 }
 
 static void
@@ -124,13 +124,21 @@
 	gnc_sql_statement_dispose( stmt );
     if( result != NULL ) {
 		GncSqlRow* row;
+		GList* list = NULL;
 
 		row = gnc_sql_result_get_first_row( result );
         while( row != NULL ) {
-            load_single_billterm( be, row );
+            GncBillTerm* pBillTerm = load_single_billterm( be, row );
+			if( pBillTerm != NULL ) {
+				list = g_list_append( list, pBillTerm );
+			}
 			row = gnc_sql_result_get_next_row( result );
 		}
 		gnc_sql_result_dispose( result );
+
+		if( list != NULL ) {
+			gnc_sql_slots_load_for_list( be, list );
+		}
     }
 }
 
@@ -161,31 +169,11 @@
 void
 gnc_sql_save_billterm( GncSqlBackend* be, QofInstance* inst )
 {
-    const GUID* guid;
-	gboolean is_infant;
-	gint op;
-
 	g_return_if_fail( inst != NULL );
 	g_return_if_fail( !GNC_IS_BILLTERM(inst) );
 	g_return_if_fail( be != NULL );
 
-	is_infant = qof_instance_get_infant( inst );
-    if( qof_instance_get_destroying(inst) ) {
-		op = OP_DB_DELETE;
-	} else if( be->is_pristine_db || is_infant ) {
-		op = OP_DB_ADD;
-	} else {
-		op = OP_DB_ADD_OR_UPDATE;
-	}
-    (void)gnc_sql_do_db_operation( be, op, TABLE_NAME, GNC_ID_BILLTERM, 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 );
-    }
+    gnc_sql_commit_standard_item( be, inst, TABLE_NAME, GNC_ID_BILLTERM, col_table );
 }
 
 /* ================================================================= */

Modified: gnucash/branches/gda-dev2/src/business/business-core/sql/gnc-customer-sql.c
===================================================================
--- gnucash/branches/gda-dev2/src/business/business-core/sql/gnc-customer-sql.c	2008-07-13 00:04:16 UTC (rev 17319)
+++ gnucash/branches/gda-dev2/src/business/business-core/sql/gnc-customer-sql.c	2008-07-13 03:14:24 UTC (rev 17320)
@@ -78,14 +78,14 @@
 	{ NULL }
 };
 
-static void
+static GncCustomer*
 load_single_customer( GncSqlBackend* be, GncSqlRow* row )
 {
     const GUID* guid;
 	GncCustomer* pCustomer;
 
-	g_return_if_fail( be != NULL );
-	g_return_if_fail( row != NULL );
+	g_return_val_if_fail( be != NULL, NULL );
+	g_return_val_if_fail( row != NULL, NULL );
 
     guid = gnc_sql_load_guid( be, row );
     pCustomer = gncCustomerLookup( be->primary_book, guid );
@@ -93,9 +93,9 @@
         pCustomer = gncCustomerCreate( be->primary_book );
     }
     gnc_sql_load_object( be, row, GNC_ID_CUSTOMER, pCustomer, col_table );
-    gnc_sql_slots_load( be, QOF_INSTANCE(pCustomer) );
-
     qof_instance_mark_clean( QOF_INSTANCE(pCustomer) );
+
+	return pCustomer;
 }
 
 static void
@@ -113,14 +113,22 @@
     result = gnc_sql_execute_select_statement( be, stmt );
 	gnc_sql_statement_dispose( stmt );
     if( result != NULL ) {
+		GList* list = NULL;
 		GncSqlRow* row;
 
 		row = gnc_sql_result_get_first_row( result );
         while( row != NULL ) {
-            load_single_customer( be, row );
+            GncCustomer* pCustomer = load_single_customer( be, row );
+			if( pCustomer != NULL ) {
+				list = g_list_append( list, pCustomer );
+			}
 			row = gnc_sql_result_get_next_row( result );
 		}
 		gnc_sql_result_dispose( result );
+
+		if( list != NULL ) {
+			gnc_sql_slots_load_for_list( be, list );
+		}
     }
 }
 
@@ -142,31 +150,11 @@
 static void
 save_customer( GncSqlBackend* be, QofInstance* inst )
 {
-    const GUID* guid;
-	gint op;
-	gboolean is_infant;
-
 	g_return_if_fail( inst != NULL );
 	g_return_if_fail( GNC_CUSTOMER(inst) );
 	g_return_if_fail( be != NULL );
 
-	is_infant = qof_instance_get_infant( inst );
-	if( qof_instance_get_destroying( inst ) ) {
-		op = OP_DB_DELETE;
-	} else if( be->is_pristine_db || is_infant ) {
-		op = OP_DB_ADD;
-	} else {
-		op = OP_DB_ADD_OR_UPDATE;
-	}
-    (void)gnc_sql_do_db_operation( be, op, TABLE_NAME, GNC_ID_CUSTOMER, 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 );
-    }
+    gnc_sql_commit_standard_item( be, inst, TABLE_NAME, GNC_ID_CUSTOMER, col_table );
 }
 
 /* ================================================================= */

Modified: gnucash/branches/gda-dev2/src/business/business-core/sql/gnc-employee-sql.c
===================================================================
--- gnucash/branches/gda-dev2/src/business/business-core/sql/gnc-employee-sql.c	2008-07-13 00:04:16 UTC (rev 17319)
+++ gnucash/branches/gda-dev2/src/business/business-core/sql/gnc-employee-sql.c	2008-07-13 03:14:24 UTC (rev 17320)
@@ -73,14 +73,14 @@
     { NULL }
 };
 
-static void
+static GncEmployee*
 load_single_employee( GncSqlBackend* be, GncSqlRow* row )
 {
     const GUID* guid;
 	GncEmployee* pEmployee;
 
-	g_return_if_fail( be != NULL );
-	g_return_if_fail( row != NULL );
+	g_return_val_if_fail( be != NULL, NULL );
+	g_return_val_if_fail( row != NULL, NULL );
 
     guid = gnc_sql_load_guid( be, row );
     pEmployee = gncEmployeeLookup( be->primary_book, guid );
@@ -88,9 +88,9 @@
         pEmployee = gncEmployeeCreate( be->primary_book );
     }
     gnc_sql_load_object( be, row, GNC_ID_EMPLOYEE, pEmployee, col_table );
-    gnc_sql_slots_load( be, QOF_INSTANCE(pEmployee) );
+    qof_instance_mark_clean( QOF_INSTANCE(pEmployee) );
 
-    qof_instance_mark_clean( QOF_INSTANCE(pEmployee) );
+	return pEmployee;
 }
 
 static void
@@ -111,12 +111,21 @@
 	gnc_sql_statement_dispose( stmt );
     if( result != NULL ) {
         GncSqlRow* row;
+		GList* list = NULL;
 
 		row = gnc_sql_result_get_first_row( result );
         while( row != NULL ) {
-            load_single_employee( be, row );
+            GncEmployee* pEmployee = load_single_employee( be, row );
+			if( pEmployee != NULL ) {
+				list = g_list_append( list, pEmployee );
+			}
+			row = gnc_sql_result_get_next_row( result );
 		}
 		gnc_sql_result_dispose( result );
+
+		if( list != NULL ) {
+			gnc_sql_slots_load_for_list( be, list );
+		}
     }
 }
 
@@ -147,18 +156,21 @@
 	g_return_if_fail( GNC_IS_EMPLOYEE(inst) );
 	g_return_if_fail( be != NULL );
 
-    // Ensure the commodity is in the db
     emp = GNC_EMPLOYEE(inst);
-    gnc_sql_save_commodity( be, gncEmployeeGetCurrency( emp ) );
 
 	is_infant = qof_instance_get_infant( inst );
 	if( qof_instance_get_destroying( inst ) ) {
 		op = OP_DB_DELETE;
 	} else if( be->is_pristine_db || is_infant ) {
-		op = OP_DB_ADD;
+		op = OP_DB_INSERT;
 	} else {
-		op = OP_DB_ADD_OR_UPDATE;
+		op = OP_DB_UPDATE;
 	}
+	if( op != OP_DB_DELETE ) {
+    	// Ensure the commodity is in the db
+    	gnc_sql_save_commodity( be, gncEmployeeGetCurrency( emp ) );
+	}
+
     (void)gnc_sql_do_db_operation( be, op, TABLE_NAME, GNC_ID_EMPLOYEE, emp, col_table );
 
     // Now, commit or delete any slots

Modified: gnucash/branches/gda-dev2/src/business/business-core/sql/gnc-entry-sql.c
===================================================================
--- gnucash/branches/gda-dev2/src/business/business-core/sql/gnc-entry-sql.c	2008-07-13 00:04:16 UTC (rev 17319)
+++ gnucash/branches/gda-dev2/src/business/business-core/sql/gnc-entry-sql.c	2008-07-13 03:14:24 UTC (rev 17320)
@@ -97,14 +97,14 @@
 	{ NULL }
 };
 
-static void
+static GncEntry*
 load_single_entry( GncSqlBackend* be, GncSqlRow* row )
 {
     const GUID* guid;
 	GncEntry* pEntry;
 
-	g_return_if_fail( be != NULL );
-	g_return_if_fail( row != NULL );
+	g_return_val_if_fail( be != NULL, NULL );
+	g_return_val_if_fail( row != NULL, NULL );
 
     guid = gnc_sql_load_guid( be, row );
     pEntry = gncEntryLookup( be->primary_book, guid );
@@ -112,9 +112,9 @@
         pEntry = gncEntryCreate( be->primary_book );
     }
     gnc_sql_load_object( be, row, GNC_ID_ENTRY, pEntry, col_table );
-    gnc_sql_slots_load( be, QOF_INSTANCE(pEntry) );
-
     qof_instance_mark_clean( QOF_INSTANCE(pEntry) );
+
+	return pEntry;
 }
 
 static void
@@ -133,13 +133,21 @@
 	gnc_sql_statement_dispose( stmt );
     if( result != NULL ) {
         GncSqlRow* row;
+		GList* list = NULL;
 
 		row = gnc_sql_result_get_first_row( result );
         while( row != NULL ) {
-            load_single_entry( be, row );
+            GncEntry* pEntry = load_single_entry( be, row );
+			if( pEntry != NULL ) {
+				list = g_list_append( list, pEntry );
+			}
 			row = gnc_sql_result_get_next_row( result );
 		}
 		gnc_sql_result_dispose( result );
+
+		if( list != NULL ) {
+			gnc_sql_slots_load_for_list( be, list );
+		}
     }
 }
 
@@ -161,31 +169,11 @@
 static void
 save_entry( GncSqlBackend* be, QofInstance* inst )
 {
-    const GUID* guid;
-	gint op;
-	gboolean is_infant;
-
 	g_return_if_fail( inst != NULL );
 	g_return_if_fail( GNC_IS_ENTRY(inst) );
 	g_return_if_fail( be != NULL );
 
-	is_infant = qof_instance_get_infant( inst );
-	if( qof_instance_get_destroying( inst ) ) {
-		op = OP_DB_DELETE;
-	} else if( be->is_pristine_db || is_infant ) {
-		op = OP_DB_ADD;
-	} else {
-		op = OP_DB_ADD_OR_UPDATE;
-	}
-    (void)gnc_sql_do_db_operation( be, op, TABLE_NAME, GNC_ID_ENTRY, 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 );
-    }
+    gnc_sql_commit_standard_item( be, inst, TABLE_NAME, GNC_ID_ENTRY, col_table );
 }
 
 /* ================================================================= */

Modified: gnucash/branches/gda-dev2/src/business/business-core/sql/gnc-invoice-sql.c
===================================================================
--- gnucash/branches/gda-dev2/src/business/business-core/sql/gnc-invoice-sql.c	2008-07-13 00:04:16 UTC (rev 17319)
+++ gnucash/branches/gda-dev2/src/business/business-core/sql/gnc-invoice-sql.c	2008-07-13 03:14:24 UTC (rev 17320)
@@ -82,14 +82,14 @@
 	{ NULL }
 };
 
-static void
+static GncInvoice*
 load_single_invoice( GncSqlBackend* be, GncSqlRow* row )
 {
     const GUID* guid;
 	GncInvoice* pInvoice;
 
-	g_return_if_fail( be != NULL );
-	g_return_if_fail( row != NULL );
+	g_return_val_if_fail( be != NULL, NULL );
+	g_return_val_if_fail( row != NULL, NULL );
 
     guid = gnc_sql_load_guid( be, row );
     pInvoice = gncInvoiceLookup( be->primary_book, guid );
@@ -97,9 +97,9 @@
         pInvoice = gncInvoiceCreate( be->primary_book );
     }
     gnc_sql_load_object( be, row, GNC_ID_INVOICE, pInvoice, col_table );
-    gnc_sql_slots_load( be, QOF_INSTANCE(pInvoice) );
+    qof_instance_mark_clean( QOF_INSTANCE(pInvoice) );
 
-    qof_instance_mark_clean( QOF_INSTANCE(pInvoice) );
+	return pInvoice;
 }
 
 static void
@@ -118,13 +118,21 @@
 	gnc_sql_statement_dispose( stmt );
     if( result != NULL ) {
         GncSqlRow* row;
+		GList* list = NULL;
 
 		row = gnc_sql_result_get_first_row( result );
         while( row != NULL ) {
-            load_single_invoice( be, row );
+			GncInvoice* pInvoice = load_single_invoice( be, row );
+			if( pInvoice != NULL ) {
+				list = g_list_append( list, pInvoice );
+			}
 			row = gnc_sql_result_get_next_row( result );
 		}
 		gnc_sql_result_dispose( result );
+
+		if( list != NULL ) {
+			gnc_sql_slots_load_for_list( be, list );
+		}
     }
 }
 
@@ -155,18 +163,21 @@
 	g_return_if_fail( GNC_IS_INVOICE(inst) );
 	g_return_if_fail( be != NULL );
 
-    // Ensure the commodity is in the db
 	invoice = GNC_INVOICE(inst);
-    gnc_sql_save_commodity( be, gncInvoiceGetCurrency( invoice ) );
 
 	is_infant = qof_instance_get_infant( inst );
 	if( qof_instance_get_destroying( inst ) ) {
 		op = OP_DB_DELETE;
 	} else if( be->is_pristine_db || is_infant ) {
-		op = OP_DB_ADD;
+		op = OP_DB_INSERT;
 	} else {
-		op = OP_DB_ADD_OR_UPDATE;
+		op = OP_DB_UPDATE;
 	}
+	if( op != OP_DB_DELETE ) {
+    	// Ensure the commodity is in the db
+    	gnc_sql_save_commodity( be, gncInvoiceGetCurrency( invoice ) );
+	}
+
     (void)gnc_sql_do_db_operation( be, op, TABLE_NAME, GNC_ID_INVOICE, inst, col_table );
 
     // Now, commit or delete any slots

Modified: gnucash/branches/gda-dev2/src/business/business-core/sql/gnc-job-sql.c
===================================================================
--- gnucash/branches/gda-dev2/src/business/business-core/sql/gnc-job-sql.c	2008-07-13 00:04:16 UTC (rev 17319)
+++ gnucash/branches/gda-dev2/src/business/business-core/sql/gnc-job-sql.c	2008-07-13 03:14:24 UTC (rev 17320)
@@ -65,14 +65,14 @@
 	{ NULL }
 };
 
-static void
+static GncJob*
 load_single_job( GncSqlBackend* be, GncSqlRow* row )
 {
     const GUID* guid;
 	GncJob* pJob;
 
-	g_return_if_fail( be != NULL );
-	g_return_if_fail( row != NULL );
+	g_return_val_if_fail( be != NULL, NULL );
+	g_return_val_if_fail( row != NULL, NULL );
 
     guid = gnc_sql_load_guid( be, row );
     pJob = gncJobLookup( be->primary_book, guid );
@@ -80,9 +80,9 @@
         pJob = gncJobCreate( be->primary_book );
     }
     gnc_sql_load_object( be, row, GNC_ID_JOB, pJob, col_table );
-    gnc_sql_slots_load( be, QOF_INSTANCE(pJob) );
-
     qof_instance_mark_clean( QOF_INSTANCE(pJob) );
+
+	return pJob;
 }
 
 static void
@@ -101,13 +101,21 @@
 	gnc_sql_statement_dispose( stmt );
     if( result != NULL ) {
         GncSqlRow* row;
+		GList* list = NULL;
 
 		row = gnc_sql_result_get_first_row( result );
         while( row != NULL ) {
-            load_single_job( be, row );
+            GncJob* pJob = load_single_job( be, row );
+			if( pJob != NULL ) {
+				list = g_list_append( list, pJob );
+			}
 			row = gnc_sql_result_get_next_row( result );
 		}
 		gnc_sql_result_dispose( result );
+
+		if( list != NULL ) {
+			gnc_sql_slots_load_for_list( be, list );
+		}
     }
 }
 
@@ -129,31 +137,11 @@
 static void
 save_job( GncSqlBackend* be, QofInstance* inst )
 {
-    const GUID* guid;
-	gint op;
-	gboolean is_infant;
-
 	g_return_if_fail( inst != NULL );
 	g_return_if_fail( GNC_IS_JOB(inst) );
 	g_return_if_fail( be != NULL );
 
-	is_infant = qof_instance_get_infant( inst );
-	if( qof_instance_get_destroying( inst ) ) {
-		op = OP_DB_DELETE;
-	} else if( be->is_pristine_db || is_infant ) {
-		op = OP_DB_ADD;
-	} else {
-		op = OP_DB_ADD_OR_UPDATE;
-	}
-    (void)gnc_sql_do_db_operation( be, op, TABLE_NAME, GNC_ID_JOB, 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 );
-    }
+    gnc_sql_commit_standard_item( be, inst, TABLE_NAME, GNC_ID_JOB, col_table );
 }
 
 /* ================================================================= */

Modified: gnucash/branches/gda-dev2/src/business/business-core/sql/gnc-order-sql.c
===================================================================
--- gnucash/branches/gda-dev2/src/business/business-core/sql/gnc-order-sql.c	2008-07-13 00:04:16 UTC (rev 17319)
+++ gnucash/branches/gda-dev2/src/business/business-core/sql/gnc-order-sql.c	2008-07-13 03:14:24 UTC (rev 17320)
@@ -66,14 +66,14 @@
 	{ NULL },
 };
 
-static void
+static GncOrder*
 load_single_order( GncSqlBackend* be, GncSqlRow* row )
 {
     const GUID* guid;
 	GncOrder* pOrder;
 
-	g_return_if_fail( be != NULL );
-	g_return_if_fail( row != NULL );
+	g_return_val_if_fail( be != NULL, NULL );
+	g_return_val_if_fail( row != NULL, NULL );
 
     guid = gnc_sql_load_guid( be, row );
     pOrder = gncOrderLookup( be->primary_book, guid );
@@ -81,9 +81,9 @@
         pOrder = gncOrderCreate( be->primary_book );
     }
     gnc_sql_load_object( be, row, GNC_ID_ORDER, pOrder, col_table );
-    gnc_sql_slots_load( be, QOF_INSTANCE(pOrder) );
-
     qof_instance_mark_clean( QOF_INSTANCE(pOrder) );
+
+	return pOrder;
 }
 
 static void
@@ -102,13 +102,21 @@
 	gnc_sql_statement_dispose( stmt );
     if( result != NULL ) {
         GncSqlRow* row;
+		GList* list = NULL;
 
 		row = gnc_sql_result_get_first_row( result );
         while( row != NULL ) {
-            load_single_order( be, row );
+            GncOrder* pOrder = load_single_order( be, row );
+			if( pOrder != NULL ) {
+				list = g_list_append( list, pOrder );
+			}
 			row = gnc_sql_result_get_next_row( result );
 		}
 		gnc_sql_result_dispose( result );
+
+		if( list != NULL ) {
+			gnc_sql_slots_load_for_list( be, list );
+		}
     }
 }
 
@@ -130,31 +138,11 @@
 static void
 save_order( GncSqlBackend* be, QofInstance* inst )
 {
-    const GUID* guid;
-	gint op;
-	gboolean is_infant;
-
 	g_return_if_fail( inst != NULL );
 	g_return_if_fail( GNC_IS_ORDER(inst) );
 	g_return_if_fail( be != NULL );
 
-	is_infant = qof_instance_get_infant( inst );
-	if( qof_instance_get_destroying( inst ) ) {
-		op = OP_DB_DELETE;
-	} else if( be->is_pristine_db || is_infant ) {
-		op = OP_DB_ADD;
-	} else {
-		op = OP_DB_ADD_OR_UPDATE;
-	}
-    (void)gnc_sql_do_db_operation( be, op, TABLE_NAME, GNC_ID_ORDER, 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 );
-    }
+    gnc_sql_commit_standard_item( be, inst, TABLE_NAME, GNC_ID_ORDER, col_table );
 }
 
 /* ================================================================= */

Modified: gnucash/branches/gda-dev2/src/business/business-core/sql/gnc-tax-table-sql.c
===================================================================
--- gnucash/branches/gda-dev2/src/business/business-core/sql/gnc-tax-table-sql.c	2008-07-13 00:04:16 UTC (rev 17319)
+++ gnucash/branches/gda-dev2/src/business/business-core/sql/gnc-tax-table-sql.c	2008-07-13 03:14:24 UTC (rev 17320)
@@ -295,7 +295,7 @@
 	for( entry = entries; entry != NULL; entry = entry->next ) {
 		GncTaxTableEntry* e = (GncTaxTableEntry*)entry->data;
     	(void)gnc_sql_do_db_operation( be,
-                        OP_DB_ADD_OR_UPDATE,
+                        OP_DB_INSERT,
                         TTENTRIES_TABLE_NAME,
                         GNC_ID_TAXTABLE, e,
                         ttentries_col_table );
@@ -320,9 +320,9 @@
 	if( qof_instance_get_destroying( inst ) ) {
 		op = OP_DB_DELETE;
 	} else if( be->is_pristine_db || is_infant ) {
-		op = OP_DB_ADD;
+		op = OP_DB_INSERT;
 	} else {
-		op = OP_DB_ADD_OR_UPDATE;
+		op = OP_DB_UPDATE;
 	}
     (void)gnc_sql_do_db_operation( be, op, TT_TABLE_NAME, GNC_ID_TAXTABLE, tt, tt_col_table );
 

Modified: gnucash/branches/gda-dev2/src/business/business-core/sql/gnc-vendor-sql.c
===================================================================
--- gnucash/branches/gda-dev2/src/business/business-core/sql/gnc-vendor-sql.c	2008-07-13 00:04:16 UTC (rev 17319)
+++ gnucash/branches/gda-dev2/src/business/business-core/sql/gnc-vendor-sql.c	2008-07-13 03:14:24 UTC (rev 17320)
@@ -79,14 +79,14 @@
 	{ NULL }
 };
 
-static void
+static GncVendor*
 load_single_vendor( GncSqlBackend* be, GncSqlRow* row )
 {
     const GUID* guid;
 	GncVendor* pVendor;
 
-	g_return_if_fail( be != NULL );
-	g_return_if_fail( row != NULL );
+	g_return_val_if_fail( be != NULL, NULL );
+	g_return_val_if_fail( row != NULL, NULL );
 
     guid = gnc_sql_load_guid( be, row );
     pVendor = gncVendorLookup( be->primary_book, guid );
@@ -94,9 +94,9 @@
         pVendor = gncVendorCreate( be->primary_book );
     }
     gnc_sql_load_object( be, row, GNC_ID_VENDOR, pVendor, col_table );
-    gnc_sql_slots_load( be, QOF_INSTANCE(pVendor) );
+    qof_instance_mark_clean( QOF_INSTANCE(pVendor) );
 
-    qof_instance_mark_clean( QOF_INSTANCE(pVendor) );
+	return pVendor;
 }
 
 static void
@@ -115,13 +115,21 @@
 	gnc_sql_statement_dispose( stmt );
     if( result != NULL ) {
         GncSqlRow* row;
+		GList* list = NULL;
 
 		row = gnc_sql_result_get_first_row( result );
         while( row != NULL ) {
-            load_single_vendor( be, row );
+            GncVendor* pVendor = load_single_vendor( be, row );
+			if( pVendor != NULL ) {
+				list = g_list_append( list, pVendor );
+			}
 			row = gnc_sql_result_get_next_row( result );
 		}
 		gnc_sql_result_dispose( result );
+
+		if( list != NULL ) {
+			gnc_sql_slots_load_for_list( be, list );
+		}
     }
 }
 
@@ -152,18 +160,20 @@
 	g_return_if_fail( GNC_IS_VENDOR(inst) );
 	g_return_if_fail( be != NULL );
 
-    // Ensure the commodity is in the db
     v = GNC_VENDOR(inst);
-    gnc_sql_save_commodity( be, gncVendorGetCurrency( v ) );
 
 	is_infant = qof_instance_get_infant( inst );
 	if( qof_instance_get_destroying( inst ) ) {
 		op = OP_DB_DELETE;
 	} else if( be->is_pristine_db || is_infant ) {
-		op = OP_DB_ADD;
+		op = OP_DB_INSERT;
 	} else {
-		op = OP_DB_ADD_OR_UPDATE;
+		op = OP_DB_UPDATE;
 	}
+	if( op != OP_DB_DELETE ) {
+    	// Ensure the commodity is in the db
+    	gnc_sql_save_commodity( be, gncVendorGetCurrency( v ) );
+	}
     (void)gnc_sql_do_db_operation( be, op, TABLE_NAME, GNC_ID_VENDOR, v, col_table );
 
     // Now, commit or delete any slots



More information about the gnucash-changes mailing list