diff --git a/src/backend/dbi/gnc-backend-dbi.c b/src/backend/dbi/gnc-backend-dbi.c index aee2899de8..a61c5170d4 100644 --- a/src/backend/dbi/gnc-backend-dbi.c +++ b/src/backend/dbi/gnc-backend-dbi.c @@ -626,6 +626,10 @@ gnc_dbi_session_end( QofBackend *be_start ) dbi_conn_close( be->conn ); be->conn = NULL; } + if( be->sql_be.conn != NULL ) { + gnc_sql_connection_dispose( be->sql_be.conn ); + be->sql_be.conn = NULL; + } gnc_sql_finalize_version_info( &be->sql_be ); LEAVE (" "); @@ -636,6 +640,8 @@ gnc_dbi_destroy_backend( /*@ only @*/ QofBackend *be ) { g_return_if_fail( be != NULL ); + qof_backend_destroy( be ); + g_free( be ); } diff --git a/src/backend/sql/gnc-backend-sql.c b/src/backend/sql/gnc-backend-sql.c index b8da18efe7..edce1c7869 100644 --- a/src/backend/sql/gnc-backend-sql.c +++ b/src/backend/sql/gnc-backend-sql.c @@ -1082,11 +1082,14 @@ add_gvalue_string_to_slist( const GncSqlBackend* be, QofIdTypeConst obj_name, getter = gnc_sql_get_getter( obj_name, table_row ); if( getter != NULL ) { s = (gchar*)(*getter)( pObject, NULL ); + if( s != NULL ) { + s = g_strdup( s ); + } } } (void)g_value_init( value, G_TYPE_STRING ); if( s ) { - g_value_set_string( value, s ); + g_value_take_string( value, s ); } (*pList) = g_slist_append( (*pList), value ); @@ -2350,6 +2353,21 @@ gnc_sql_get_sql_value( const GncSqlConnection* conn, const GValue* value ) } } +static void +free_gvalue_list( GSList* list ) +{ + GSList* node; + GValue* value; + + for( node = list; node != NULL; node = node->next ) { + value = (GValue*)node->data; + + g_value_unset( value ); + g_free( value ); + } + g_slist_free( list ); +} + /*@ null @*/ static GncSqlStatement* build_insert_statement( GncSqlBackend* be, const gchar* table_name, @@ -2409,9 +2427,8 @@ build_insert_statement( GncSqlBackend* be, (void)g_string_append( sql, value_str ); g_free( value_str ); (void)g_value_reset( value ); - g_free( value ); } - g_slist_free( values ); + free_gvalue_list( values ); (void)g_string_append( sql, ")" ); stmt = gnc_sql_connection_create_statement_from_sql( be->conn, sql->str ); @@ -2470,13 +2487,15 @@ build_update_statement( GncSqlBackend* be, (void)g_string_append( sql, "," ); } (void)g_string_append( sql, (gchar*)colname->data ); - g_free( colname->data ); (void)g_string_append( sql, "=" ); value_str = gnc_sql_get_sql_value( be->conn, (GValue*)(value->data) ); (void)g_string_append( sql, value_str ); g_free( value_str ); firstCol = FALSE; } + for( colname = colnames; colname != NULL; colname = colname->next ) { + g_free( colname->data ); + } g_list_free( colnames ); if( value != NULL || colname != NULL ) { PERR( "Mismatch in number of column names and values" ); @@ -2484,10 +2503,7 @@ build_update_statement( GncSqlBackend* be, stmt = gnc_sql_connection_create_statement_from_sql( be->conn, sql->str ); gnc_sql_statement_add_where_cond( stmt, obj_name, pObject, &table[0], (GValue*)(values->data) ); - for( value = values; value != NULL; value = value->next ) { - g_free( value->data ); - } - g_slist_free( values ); + free_gvalue_list( values ); (void)g_string_free( sql, TRUE ); return stmt; @@ -2520,6 +2536,7 @@ build_delete_statement( GncSqlBackend* be, pHandler->add_gvalue_to_slist_fn( be, obj_name, pObject, table, &list ); g_assert( list != NULL ); gnc_sql_statement_add_where_cond( stmt, obj_name, pObject, &table[0], (GValue*)(list->data) ); + free_gvalue_list( list ); return stmt; } @@ -2770,7 +2787,10 @@ gnc_sql_finalize_version_info( GncSqlBackend* be ) { g_return_if_fail( be != NULL ); - g_hash_table_destroy( be->versions ); + if( be->versions != NULL ) { + g_hash_table_destroy( be->versions ); + be->versions = NULL; + } } /** diff --git a/src/backend/sql/gnc-slots-sql.c b/src/backend/sql/gnc-slots-sql.c index cddc5e38d2..98501d5a43 100644 --- a/src/backend/sql/gnc-slots-sql.c +++ b/src/backend/sql/gnc-slots-sql.c @@ -435,7 +435,6 @@ gnc_sql_slots_load( GncSqlBackend* be, QofInstance* inst ) GncSqlResult* result; gchar guid_buf[GUID_ENCODING_LENGTH+1]; GncSqlStatement* stmt; - GValue value; const GUID* guid; KvpFrame* pFrame; @@ -445,9 +444,6 @@ gnc_sql_slots_load( GncSqlBackend* be, QofInstance* inst ) guid = qof_instance_get_guid( inst ); pFrame = qof_instance_get_slots( inst ); (void)guid_to_string_buff( guid, guid_buf ); - memset( &value, 0, sizeof( value ) ); - (void)g_value_init( &value, G_TYPE_STRING ); - g_value_set_string( &value, guid_buf ); buf = g_strdup_printf( "SELECT * FROM %s WHERE obj_guid='%s'", TABLE_NAME, guid_buf ); stmt = gnc_sql_create_statement_from_sql( be, buf ); diff --git a/src/engine/SX-book.c b/src/engine/SX-book.c index d530424434..9cf51afa25 100644 --- a/src/engine/SX-book.c +++ b/src/engine/SX-book.c @@ -253,8 +253,20 @@ book_sxes_setup(QofBook *book) sxes->sx_list = NULL; sxes->sx_notsaved = TRUE; qof_collection_set_data(col, sxes); +} - /* XXX: FIXME: MEMORY LEAK. This object is never freed. */ +static void +book_sxes_end(QofBook* book) +{ + QofCollection *col; + SchedXactions *sxes; + + col = qof_book_get_collection(book, GNC_ID_SCHEDXACTION); + sxes = qof_collection_get_data(col); + if (sxes != NULL) { + g_object_unref(sxes); + qof_collection_set_data(col, NULL); + } } static void @@ -300,7 +312,7 @@ static QofObject sxes_object_def = .type_label = "Scheduled Transactions List", .create = NULL, .book_begin = book_sxes_setup, - .book_end = NULL, + .book_end = book_sxes_end, .is_dirty = book_sxlist_notsaved, .mark_clean = book_sxns_mark_saved, .foreach = NULL, diff --git a/src/libqof/backend/file/qsf-xml-map.c b/src/libqof/backend/file/qsf-xml-map.c index 9900a1b754..584faaa624 100644 --- a/src/libqof/backend/file/qsf-xml-map.c +++ b/src/libqof/backend/file/qsf-xml-map.c @@ -311,6 +311,7 @@ gboolean is_qsf_map(const gchar *path) doc = xmlParseFile(path); if(doc == NULL) { return FALSE; } if(TRUE != qsf_is_valid(QSF_SCHEMA_DIR, QSF_MAP_SCHEMA, doc)) { + xmlFreeDoc(doc); return FALSE; } map_root = xmlDocGetRootElement(doc); diff --git a/src/libqof/backend/file/qsf-xml.c b/src/libqof/backend/file/qsf-xml.c index e506b580e1..f3c3a8a641 100644 --- a/src/libqof/backend/file/qsf-xml.c +++ b/src/libqof/backend/file/qsf-xml.c @@ -83,6 +83,7 @@ qsf_is_valid(const gchar *schema_dir, const gchar* schema_filename, xmlDocPtr do xmlSchemaFreeParserCtxt(qsf_schema_file); xmlSchemaFreeValidCtxt(qsf_context); xmlSchemaFree(qsf_schema); + g_free(schema_path); if(result == 0) { return TRUE; } return FALSE; } @@ -155,6 +156,7 @@ gboolean is_our_qsf_object(const gchar *path) if(TRUE != qsf_is_valid(QSF_SCHEMA_DIR, QSF_OBJECT_SCHEMA, doc)) { PINFO (" validation failed %s %s %s", QSF_SCHEMA_DIR, QSF_OBJECT_SCHEMA, path); + xmlFreeDoc(doc); return FALSE; } object_root = xmlDocGetRootElement(doc); @@ -178,7 +180,11 @@ gboolean is_qsf_object(const gchar *path) if(path == NULL) { return FALSE; } doc = xmlParseFile(path); if(doc == NULL) { return FALSE; } - if(TRUE != qsf_is_valid(QSF_SCHEMA_DIR, QSF_OBJECT_SCHEMA, doc)) { return FALSE; } + if(TRUE != qsf_is_valid(QSF_SCHEMA_DIR, QSF_OBJECT_SCHEMA, doc)) { + xmlFreeDoc(doc); + return FALSE; + } + xmlFreeDoc(doc); /* Note cannot test against a map here, so if the file is valid QSF, accept it and work out the details later. */ return TRUE; diff --git a/src/libqof/qof/qofbook.c b/src/libqof/qof/qofbook.c index 9621e86453..f65cba0cb8 100644 --- a/src/libqof/qof/qofbook.c +++ b/src/libqof/qof/qofbook.c @@ -146,7 +146,7 @@ qof_book_destroy (QofBook *book) cols = book->hash_of_collections; g_object_unref (book); g_hash_table_destroy (cols); - book->hash_of_collections = NULL; + /*book->hash_of_collections = NULL;*/ LEAVE ("book=%p", book); }