[libgda] Execution time corrections



commit e12313bcd841256ffa4746eb2381ce1ed80b7c30
Author: Vivien Malerba <malerba gnome-db org>
Date:   Tue Oct 13 21:15:33 2009 +0200

    Execution time corrections
    
    - avoid using g_object_get_data() when not necessary
    - avoid using g_slist_nth_data() when not necessary
    - added an optimized gda_set_get_nth_holder()
    - avoid testing type in static functions

 doc/C/libgda-sections.txt                   |    1 +
 doc/C/tmpl/gda-set.sgml                     |   10 +++
 libgda-ui/gdaui-data-widget-info.c          |   37 +++++++++---
 libgda-ui/gdaui-raw-grid.c                  |   80 +++++++++++++++------------
 libgda/gda-data-model-iter.c                |    2 +-
 libgda/gda-data-select.c                    |   19 +-----
 libgda/gda-set.c                            |   42 ++++++++++++++
 libgda/gda-set.h                            |    2 +
 libgda/libgda.symbols                       |    1 +
 libgda/thread-wrapper/gda-thread-provider.c |    8 ++-
 tools/browser/browser-connection.c          |    9 ++-
 11 files changed, 147 insertions(+), 64 deletions(-)
---
diff --git a/doc/C/libgda-sections.txt b/doc/C/libgda-sections.txt
index 3e591e7..114997a 100644
--- a/doc/C/libgda-sections.txt
+++ b/doc/C/libgda-sections.txt
@@ -1038,6 +1038,7 @@ gda_set_get_holder_value
 gda_set_set_holder_value
 <SUBSECTION>
 gda_set_get_holder
+gda_set_get_nth_holder
 gda_set_add_holder
 gda_set_remove_holder
 gda_set_merge_with_set
diff --git a/doc/C/tmpl/gda-set.sgml b/doc/C/tmpl/gda-set.sgml
index 8e34d45..9265bbb 100644
--- a/doc/C/tmpl/gda-set.sgml
+++ b/doc/C/tmpl/gda-set.sgml
@@ -187,6 +187,16 @@ Container for several values
 @Returns: 
 
 
+<!-- ##### FUNCTION gda_set_get_nth_holder ##### -->
+<para>
+
+</para>
+
+ set: 
+ pos: 
+ Returns: 
+
+
 <!-- ##### FUNCTION gda_set_add_holder ##### -->
 <para>
 
diff --git a/libgda-ui/gdaui-data-widget-info.c b/libgda-ui/gdaui-data-widget-info.c
index b2ffa9b..2c7a730 100644
--- a/libgda-ui/gdaui-data-widget-info.c
+++ b/libgda-ui/gdaui-data-widget-info.c
@@ -62,6 +62,8 @@ struct _GdauiDataWidgetInfoPriv
 	GtkWidget         *buttons_bar;
 	GtkWidget         *current_sample;
 	GtkWidget         *row_spin;
+
+	guint              idle_id;
 };
 
 /* get a pointer to the parents to be able to call their destructor */
@@ -207,6 +209,8 @@ gdaui_data_widget_info_dispose (GObject *object)
 	info = GDAUI_DATA_WIDGET_INFO (object);
 
 	if (info->priv) {
+		if (info->priv->idle_id)
+			g_source_remove (info->priv->idle_id);
 		if (info->priv->proxy)
 			release_proxy (info);
 		if (info->priv->iter)
@@ -225,9 +229,9 @@ gdaui_data_widget_info_dispose (GObject *object)
 
 static void
 gdaui_data_widget_info_set_property (GObject *object,
-					guint param_id,
-					const GValue *value,
-					GParamSpec *pspec)
+				     guint param_id,
+				     const GValue *value,
+				     GParamSpec *pspec)
 {
 	GdauiDataWidgetInfo *info;
 
@@ -310,9 +314,9 @@ gdaui_data_widget_info_set_property (GObject *object,
 
 static void
 gdaui_data_widget_info_get_property (GObject *object,
-					guint param_id,
-					GValue *value,
-					GParamSpec *pspec)
+				     guint param_id,
+				     GValue *value,
+				     GParamSpec *pspec)
 {
 	GdauiDataWidgetInfo *info;
 
@@ -497,12 +501,23 @@ row_spin_changed_cb (GtkSpinButton *spin, GdauiDataWidgetInfo *info)
 	gda_data_model_iter_move_to_row (gdaui_data_widget_get_current_data (info->priv->data_widget), row);
 }
 
+static gboolean idle_modif_buttons_update (GdauiDataWidgetInfo *info);
+static void
+modif_buttons_update (GdauiDataWidgetInfo *info)
+{
+	if (info->priv->idle_id == 0)
+		info->priv->idle_id = g_idle_add_full (G_PRIORITY_HIGH_IDLE,
+						       (GSourceFunc) idle_modif_buttons_update,
+						       g_object_ref (info), g_object_unref);
+}
+
+
 #define BLOCK_SPIN (g_signal_handlers_block_by_func (G_OBJECT (info->priv->row_spin), \
 						     G_CALLBACK (row_spin_changed_cb), info))
 #define UNBLOCK_SPIN (g_signal_handlers_unblock_by_func (G_OBJECT (info->priv->row_spin), \
 							 G_CALLBACK (row_spin_changed_cb), info))
-static void
-modif_buttons_update (GdauiDataWidgetInfo *info)
+static gboolean
+idle_modif_buttons_update (GdauiDataWidgetInfo *info)
 {
 	GdaDataModelIter *model_iter;
 	gboolean wrows, filtered_proxy = FALSE;
@@ -724,5 +739,9 @@ modif_buttons_update (GdauiDataWidgetInfo *info)
 	}
 	
 	if (info->priv->uimanager)
-		gtk_ui_manager_ensure_update (info->priv->uimanager); 
+		gtk_ui_manager_ensure_update (info->priv->uimanager);
+
+	/* remove IDLE */
+	info->priv->idle_id = 0;
+	return FALSE;
 }
diff --git a/libgda-ui/gdaui-raw-grid.c b/libgda-ui/gdaui-raw-grid.c
index 6ba8fdf..bec6fcf 100644
--- a/libgda-ui/gdaui-raw-grid.c
+++ b/libgda-ui/gdaui-raw-grid.c
@@ -92,6 +92,7 @@ struct _GdauiRawGridPriv
 	GdaDataProxy               *proxy;       /* proxy data model, proxying @data_model */
 
 	GSList                     *columns_data; /* list of ColumnData */
+	GHashTable                 *columns_hash; /* key = a GtkCellRenderer, value = a #ColumnData (no ref held) */
 
 	GSList                     *reordered_indexes;  /* Indexes of the reordered columns. */
 
@@ -288,6 +289,7 @@ gdaui_raw_grid_init (GdauiRawGrid *grid)
 	grid->priv->default_show_info_cell = FALSE;
 	grid->priv->default_show_global_actions = TRUE;
 	grid->priv->columns_data = NULL;
+	grid->priv->columns_hash = g_hash_table_new (NULL, NULL);
 	grid->priv->export_type = 2;
 	grid->priv->write_mode = GDAUI_DATA_WIDGET_WRITE_ON_DEMAND;
 	
@@ -652,11 +654,11 @@ load_xml_data_layouts (GdauiRawGrid  *grid,
 
 static gboolean
 gdaui_raw_grid_query_tooltip (GtkWidget   *widget,
-				 gint         x,
-				 gint         y,
-				 gboolean     keyboard_tip,
-				 GtkTooltip  *tooltip,
-				 gpointer     data)
+			      gint         x,
+			      gint         y,
+			      gboolean     keyboard_tip,
+			      GtkTooltip  *tooltip,
+			      gpointer     data)
 {
 	GtkTreeView *tree_view = GTK_TREE_VIEW(widget);
 
@@ -667,22 +669,20 @@ gdaui_raw_grid_query_tooltip (GtkWidget   *widget,
 
 	gint position = 0;
 	guint col_x = 0;
-	GList *columns = gtk_tree_view_get_columns (tree_view), *list = columns;
-	while (list != NULL) {
+	GList *list, *columns = gtk_tree_view_get_columns (tree_view);
+	for (list = columns; list; list = list->next) {
 		GtkTreeViewColumn *column = list->data;
 		if (x >= col_x && x < (col_x + column->width)) {
 			break;
 		} else
 			col_x += column->width;
 		++position;
-		list = g_list_next (list);
 	}
 	if (list == NULL)
 		return FALSE;
 
 	GdauiRawGrid *grid = GDAUI_RAW_GRID(tree_view);
-	ColumnData *column_data = (ColumnData *)
-		(g_slist_nth (grid->priv->columns_data, position)->data);
+	ColumnData *column_data = (ColumnData *) (g_slist_nth (grid->priv->columns_data, position)->data);
 	g_return_val_if_fail (column_data, FALSE);
 
 	g_list_free (columns);
@@ -873,6 +873,7 @@ gdaui_raw_grid_set_property (GObject *object,
 				g_list_free (columns);
 
 				g_slist_free (grid->priv->columns_data);
+				g_hash_table_remove_all (grid->priv->columns_hash);
 				grid->priv->columns_data = columns_data;
 
 				// Remove unnecessary columns according layout
@@ -900,15 +901,14 @@ gdaui_raw_grid_set_property (GObject *object,
 			break;
 				
 		case PROP_INFO_CELL_VISIBLE: {
-			GSList *list = grid->priv->columns_data;
+			GSList *list;
 			gboolean show = g_value_get_boolean (value);
 			grid->priv->default_show_info_cell = show;
 	
-			while (list) {
+			for (list = grid->priv->columns_data; list; list = list->next) {
 				COLUMN_DATA (list->data)->info_shown = show;
 				g_object_set (G_OBJECT (COLUMN_DATA (list->data)->info_cell), "visible", 
 					      show, NULL);
-				list = g_slist_next (list);
 			}
 		}
 			break;
@@ -1097,6 +1097,7 @@ init_tree_view (GdauiRawGrid *grid)
 
 			renderer = gdaui_data_cell_renderer_combo_new (grid->priv->iter_info, group->source);
 			column_data->data_cell = renderer;
+			g_hash_table_insert (grid->priv->columns_hash, renderer, column_data);
 			gtk_tree_view_insert_column_with_data_func (tree_view, i, title, renderer,
 								    (GtkTreeCellDataFunc) cell_renderer_value_set_attributes, 
 								    grid, NULL);
@@ -1137,6 +1138,7 @@ init_tree_view (GdauiRawGrid *grid)
 			}
 			renderer = _gdaui_new_cell_renderer (g_type, plugin);
 			column_data->data_cell = renderer;
+			g_hash_table_insert (grid->priv->columns_hash, renderer, column_data);
 			gtk_tree_view_insert_column_with_data_func (tree_view, i, title, renderer,
 								    (GtkTreeCellDataFunc) cell_renderer_value_set_attributes, 
 								    grid, NULL);
@@ -1157,12 +1159,12 @@ init_tree_view (GdauiRawGrid *grid)
 		g_object_set (G_OBJECT (renderer), "editable", !column_data->data_locked, NULL);
 		if (g_object_class_find_property (G_OBJECT_GET_CLASS (renderer), "set_default_if_invalid"))
 			g_object_set (G_OBJECT (renderer), "set_default_if_invalid", TRUE, NULL);
-		g_object_set_data (G_OBJECT (renderer), "__gdaui_group", group);
 		g_object_set_data (G_OBJECT (column), "__gdaui_group", group);
 
 		/* Adding the GValue's information cell as another GtkCellRenderer */
 		renderer = gdaui_data_cell_renderer_info_new (grid->priv->store, grid->priv->iter, group);
 		column_data->info_cell = renderer;
+		g_hash_table_insert (grid->priv->columns_hash, renderer, column_data);
 		gtk_tree_view_column_pack_end (column, renderer, FALSE);
 		gtk_tree_view_column_set_cell_data_func (column, renderer, 
 							 (GtkTreeCellDataFunc) cell_renderer_info_set_attributes, 
@@ -1170,7 +1172,6 @@ init_tree_view (GdauiRawGrid *grid)
 		g_signal_connect (G_OBJECT (renderer), "status_changed",
 				  G_CALLBACK (data_cell_status_changed), grid);
 		g_object_set (G_OBJECT (renderer), "visible", column_data->info_shown, NULL);
-		g_object_set_data (G_OBJECT (renderer), "__gdaui_group", group);
 
 		/* Sorting data */
 		gtk_tree_view_column_set_clickable (column, TRUE);
@@ -1194,8 +1195,9 @@ cell_renderer_value_set_attributes (GtkTreeViewColumn *tree_column,
 	gboolean to_be_deleted = FALSE;
 	ColumnData *column_data;
 
-	group = g_object_get_data (G_OBJECT (tree_column), "__gdaui_group");
-	column_data = get_column_data (grid, group);
+	column_data = g_hash_table_lookup (grid->priv->columns_hash, cell);
+	g_assert (column_data);
+	group = column_data->group;
 	
 	if (group->group->nodes_source) {
 		/* parameters depending on a GdaDataModel */
@@ -1295,8 +1297,9 @@ cell_renderer_info_set_attributes (GtkTreeViewColumn *tree_column,
 	gboolean to_be_deleted = FALSE;
 	ColumnData *column_data;
 
-	group = g_object_get_data (G_OBJECT (tree_column), "__gdaui_group");
-	column_data = get_column_data (grid, group);
+	column_data = g_hash_table_lookup (grid->priv->columns_hash, cell);
+	g_assert (column_data);
+	group = column_data->group;
 	
 	if (group->group->nodes_source) {
 		/* parameters depending on a GdaDataModel */
@@ -1353,8 +1356,11 @@ data_cell_value_changed (GtkCellRenderer *renderer, const gchar *path, const GVa
 {
 	GtkTreeIter iter;
 	GdauiSetGroup *group;
+	ColumnData *column_data;
 	
-	group = g_object_get_data (G_OBJECT (renderer), "__gdaui_group");
+	column_data = g_hash_table_lookup (grid->priv->columns_hash, renderer);
+	g_assert (column_data);
+	group = column_data->group;
 	g_assert (g_slist_length (group->group->nodes) == 1);
 
 	if (set_iter_from_path (grid, path, &iter)) {
@@ -1377,8 +1383,11 @@ data_cell_values_changed (GtkCellRenderer *renderer, const gchar *path,
 {
 	GtkTreeIter iter;
 	GdauiSetGroup *group;
-	
-	group = g_object_get_data (G_OBJECT (renderer), "__gdaui_group");
+	ColumnData *column_data;
+
+	column_data = g_hash_table_lookup (grid->priv->columns_hash, renderer);
+	g_assert (column_data);
+	group = column_data->group;
 	g_assert (group->group->nodes_source);
 
 	if (new_values)
@@ -1472,10 +1481,14 @@ data_cell_status_changed (GtkCellRenderer *renderer, const gchar *path, GdaValue
 	gint col;
 	gint offset;
 	GValue *attribute;
+	ColumnData *column_data;
+
+	column_data = g_hash_table_lookup (grid->priv->columns_hash, renderer);
+	g_assert (column_data);
+	group = column_data->group;
 
 	offset = gda_data_model_get_n_columns (gda_data_proxy_get_proxied_model (grid->priv->proxy));
 
-	group = g_object_get_data (G_OBJECT (renderer), "__gdaui_group");
 	tree_model = GTK_TREE_MODEL (grid->priv->store);
 
 	treepath = gtk_tree_path_new_from_string (path);
@@ -2178,8 +2191,7 @@ save_as_response_cb (GtkDialog *dialog, guint response_id, GdauiRawGrid *grid)
 		columns = gtk_tree_view_get_columns (GTK_TREE_VIEW (grid));
 		cols = g_new (gint, gda_data_model_get_n_columns (GDA_DATA_MODEL (grid->priv->data_model)));
 		nb_cols = 0;
-		list = columns;
-		while (list) {
+		for (list = columns; list; list = list->next) {
 			if (gtk_tree_view_column_get_visible (GTK_TREE_VIEW_COLUMN (list->data))) {
 				GdauiSetGroup *group;
 				GSList *params;
@@ -2189,7 +2201,6 @@ save_as_response_cb (GtkDialog *dialog, guint response_id, GdauiRawGrid *grid)
 					cols [nb_cols] = g_slist_index (((GdaSet *)grid->priv->iter)->holders,
 									GDA_SET_NODE (params->data)->holder);
 			}
-			list = g_list_next (list);
 		}
 		g_list_free (columns);
 
@@ -2633,24 +2644,21 @@ paramlist_public_data_changed_cb (GdauiSet *info, GdauiRawGrid *grid)
 
 	/* info cells */
 	if (grid->priv->columns_data) {
-		GSList *list = grid->priv->columns_data;
-		while (list) {
+		GSList *list;
+		for (list = grid->priv->columns_data; list; list = list->next) {
                         g_free (((ColumnData *) (list->data))->tooltip_text);
 			g_free (list->data);
-			list = g_slist_next (list);
 		}
 		g_slist_free (grid->priv->columns_data);
 		grid->priv->columns_data = NULL;
+		g_hash_table_remove_all (grid->priv->columns_hash);
 	}
 
 	columns = gtk_tree_view_get_columns (GTK_TREE_VIEW (grid));
 	if (columns) {
-		list = columns;
-		while (list) {
+		for (list = columns; list; list = list->next)
 			gtk_tree_view_remove_column (GTK_TREE_VIEW (grid),
 						     (GtkTreeViewColumn*) (list->data));
-			list = g_list_next (list);
-		}
 		g_list_free (columns);
 	}
 
@@ -2844,14 +2852,14 @@ gdaui_raw_grid_soft_clean (GdauiRawGrid *grid)
 
 	/* info cells */
 	if (grid->priv->columns_data) {
-		GSList *list = grid->priv->columns_data;
-		while (list) {
+		GSList *list;
+		for (list = grid->priv->columns_data; list; list = list->next) {
                         g_free (((ColumnData *) (list->data))->tooltip_text);
 			g_free (list->data);
-			list = g_slist_next (list);
 		}
 		g_slist_free (grid->priv->columns_data);
 		grid->priv->columns_data = NULL;
+		g_hash_table_remove_all (grid->priv->columns_hash);
 	}
 
 	/* store */
diff --git a/libgda/gda-data-model-iter.c b/libgda/gda-data-model-iter.c
index c340b30..a50725a 100644
--- a/libgda/gda-data-model-iter.c
+++ b/libgda/gda-data-model-iter.c
@@ -903,7 +903,7 @@ gda_data_model_iter_get_holder_for_field (GdaDataModelIter *iter, gint col)
 	g_return_val_if_fail (GDA_IS_DATA_MODEL_ITER (iter), NULL);
 	g_return_val_if_fail (iter->priv, NULL);
 
-	return g_slist_nth_data (((GdaSet *) iter)->holders, col);
+	return gda_set_get_nth_holder ((GdaSet *) iter, col);
 }
 
 /**
diff --git a/libgda/gda-data-select.c b/libgda/gda-data-select.c
index c839c9e..2eaba95 100644
--- a/libgda/gda-data-select.c
+++ b/libgda/gda-data-select.c
@@ -312,7 +312,7 @@ static void
 gda_data_select_init (GdaDataSelect *model, GdaDataSelectClass *klass)
 {
 	ModType i;
-	g_return_if_fail (GDA_IS_DATA_SELECT (model));
+
 	model->priv = g_new0 (GdaDataSelectPrivate, 1);
 	model->priv->cnc = NULL;
 	model->priv->sh = g_new0 (PrivateShareable, 1);
@@ -425,8 +425,6 @@ gda_data_select_dispose (GObject *object)
 {
 	GdaDataSelect *model = (GdaDataSelect *) object;
 
-	g_return_if_fail (GDA_IS_DATA_SELECT (model));
-
 	/* free memory */
 	if (model->priv) {
 		if (model->priv->cnc) {
@@ -525,8 +523,6 @@ gda_data_select_finalize (GObject *object)
 {
 	GdaDataSelect *model = (GdaDataSelect *) object;
 
-	g_return_if_fail (GDA_IS_DATA_SELECT (model));
-
 	/* free memory */
 	if (model->priv) {
 		g_free (model->priv);
@@ -1466,7 +1462,7 @@ gda_data_select_get_n_rows (GdaDataModel *model)
 {
 	GdaDataSelect *imodel;
 	gint retval;
-	g_return_val_if_fail (GDA_IS_DATA_SELECT (model), 0);
+
 	imodel = GDA_DATA_SELECT (model);
 	g_return_val_if_fail (imodel->priv, 0);
 
@@ -1485,7 +1481,7 @@ static gint
 gda_data_select_get_n_columns (GdaDataModel *model)
 {
 	GdaDataSelect *imodel;
-	g_return_val_if_fail (GDA_IS_DATA_SELECT (model), 0);
+
 	imodel = GDA_DATA_SELECT (model);
 	g_return_val_if_fail (imodel->priv, 0);
 	
@@ -1499,7 +1495,7 @@ static GdaColumn *
 gda_data_select_describe_column (GdaDataModel *model, gint col)
 {
 	GdaDataSelect *imodel;
-	g_return_val_if_fail (GDA_IS_DATA_SELECT (model), NULL);
+
 	imodel = GDA_DATA_SELECT (model);
 	g_return_val_if_fail (imodel->priv, NULL);
 
@@ -1512,7 +1508,6 @@ gda_data_select_get_access_flags (GdaDataModel *model)
 	GdaDataSelect *imodel;
 	GdaDataModelAccessFlags flags = 0;
 
-	g_return_val_if_fail (GDA_IS_DATA_SELECT (model), 0);
 	imodel = GDA_DATA_SELECT (model);
 	g_return_val_if_fail (imodel->priv, 0);
 
@@ -1598,7 +1593,6 @@ gda_data_select_get_value_at (GdaDataModel *model, gint col, gint row, GError **
 	gint int_row, irow;
 	GdaDataSelect *imodel;
 
-	g_return_val_if_fail (GDA_IS_DATA_SELECT (model), NULL);
 	imodel = (GdaDataSelect *) model;
 	g_return_val_if_fail (imodel->priv, NULL);
 
@@ -1738,7 +1732,6 @@ gda_data_select_get_attributes_at (GdaDataModel *model, gint col, gint row)
 	GdaValueAttribute flags = GDA_VALUE_ATTR_IS_UNCHANGED;
 	GdaDataSelect *imodel;
 
-	g_return_val_if_fail (GDA_IS_DATA_SELECT (model), 0);
 	imodel = (GdaDataSelect *) model;
 	g_return_val_if_fail (imodel->priv, 0);
 	
@@ -1759,7 +1752,6 @@ gda_data_select_create_iter (GdaDataModel *model)
 {
 	GdaDataSelect *imodel;
 
-	g_return_val_if_fail (GDA_IS_DATA_SELECT (model), 0);
 	imodel = (GdaDataSelect *) model;
 	g_return_val_if_fail (imodel->priv, 0);
 
@@ -1787,7 +1779,6 @@ gda_data_select_iter_next (GdaDataModel *model, GdaDataModelIter *iter)
 	gint target_iter_row;
 	gint irow, int_row;
 
-	g_return_val_if_fail (GDA_IS_DATA_SELECT (model), FALSE);
 	imodel = (GdaDataSelect *) model;
 	g_return_val_if_fail (imodel->priv, FALSE);
 
@@ -1837,7 +1828,6 @@ gda_data_select_iter_prev (GdaDataModel *model, GdaDataModelIter *iter)
 	gint target_iter_row;
 	gint irow, int_row;
 
-	g_return_val_if_fail (GDA_IS_DATA_SELECT (model), FALSE);
 	imodel = (GdaDataSelect *) model;
 	g_return_val_if_fail (imodel->priv, FALSE);
 
@@ -1888,7 +1878,6 @@ gda_data_select_iter_at_row (GdaDataModel *model, GdaDataModelIter *iter, gint r
 	GdaRow *prow = NULL;
 	gint irow, int_row;
 
-	g_return_val_if_fail (GDA_IS_DATA_SELECT (model), FALSE);
 	imodel = (GdaDataSelect *) model;
 	g_return_val_if_fail (imodel->priv, FALSE);
 
diff --git a/libgda/gda-set.c b/libgda/gda-set.c
index 29a03d0..6eaa480 100644
--- a/libgda/gda-set.c
+++ b/libgda/gda-set.c
@@ -52,6 +52,7 @@ static void gda_set_finalize (GObject *object);
 static void set_remove_node (GdaSet *set, GdaSetNode *node);
 static void set_remove_source (GdaSet *set, GdaSetSource *source);
 
+
 static void changed_holder_cb (GdaHolder *holder, GdaSet *dataset);
 static GError *validate_change_holder_cb (GdaHolder *holder, const GValue *value, GdaSet *dataset);
 static void source_changed_holder_cb (GdaHolder *holder, GdaSet *dataset);
@@ -95,6 +96,7 @@ struct _GdaSetPrivate
 	gchar           *name;
 	gchar           *descr;
 	GHashTable      *holders_hash; /* key = GdaHoler ID, value = GdaHolder */
+	GArray          *holders_array;
 };
 
 static void 
@@ -345,6 +347,7 @@ gda_set_init (GdaSet *set)
 	set->sources_list = NULL;
 	set->groups_list = NULL;
 	set->priv->holders_hash = g_hash_table_new (g_str_hash, g_str_equal);
+	set->priv->holders_array = NULL;
 }
 
 
@@ -920,6 +923,10 @@ gda_set_remove_holder (GdaSet *set, GdaHolder *holder)
 
 	set->holders = g_slist_remove (set->holders, holder);
 	g_hash_table_remove (set->priv->holders_hash, gda_holder_get_id (holder));
+	if (set->priv->holders_array) {
+		g_array_free (set->priv->holders_array, TRUE);
+		set->priv->holders_array = NULL;
+	}
 	g_object_unref (G_OBJECT (holder));
 }
 
@@ -1005,6 +1012,10 @@ gda_set_dispose (GObject *object)
 		g_hash_table_destroy (set->priv->holders_hash);
 		set->priv->holders_hash = NULL;
 	}
+	if (set->priv->holders_array) {
+		g_array_free (set->priv->holders_array, TRUE);
+		set->priv->holders_array = NULL;
+	}
 
 	/* free the nodes if there are some */
 	while (set->nodes_list)
@@ -1181,6 +1192,10 @@ gda_set_real_add_holder (GdaSet *set, GdaHolder *holder)
 		/* really add @holder to the set */
 		set->holders = g_slist_append (set->holders, holder);
 		g_hash_table_insert (set->priv->holders_hash, (gchar*) hid, holder);
+		if (set->priv->holders_array) {
+			g_array_free (set->priv->holders_array, TRUE);
+			set->priv->holders_array = NULL;
+		}
 		g_object_ref (holder);
 		g_signal_connect (G_OBJECT (holder), "changed",
 				  G_CALLBACK (changed_holder_cb), set);
@@ -1309,6 +1324,33 @@ gda_set_get_holder (GdaSet *set, const gchar *holder_id)
 	return (GdaHolder *) g_hash_table_lookup (set->priv->holders_hash, holder_id);
 }
 
+/**
+ * gda_set_get_nth_holder
+ * @set: a #GdaSet object
+ * @pos: the position of the requested #GdaHolder, starting at %0
+ *
+ * Finds a #GdaHolder using its position
+ *
+ * Returns: a #GdaHolder or %NULL
+ *
+ * Since: 4.2
+ */
+GdaHolder *
+gda_set_get_nth_holder (GdaSet *set, gint pos)
+{
+	g_return_val_if_fail (GDA_IS_SET (set), NULL);
+	if (! set->priv->holders_array) {
+		GSList *list;
+		set->priv->holders_array = g_array_sized_new (FALSE, FALSE, sizeof (GdaHolder*),
+							      g_slist_length (set->holders));
+		for (list = set->holders; list; list = list->next)
+			g_array_append_val (set->priv->holders_array, list->data);
+	}
+	if ((pos < 0) || (pos > set->priv->holders_array->len))
+		return NULL;
+	else
+		return g_array_index (set->priv->holders_array, GdaHolder*, pos);
+}
 
 /**
  * gda_set_get_node
diff --git a/libgda/gda-set.h b/libgda/gda-set.h
index 65ef392..bb159c5 100644
--- a/libgda/gda-set.h
+++ b/libgda/gda-set.h
@@ -103,6 +103,7 @@ struct _GdaSetClass
 							const gchar *attr_name, const GValue *attr_value);
 	void                  (*public_data_changed)   (GdaSet *set);
 
+	/*< private >*/
 	/* Padding for future expansion */
 	void (*_gda_reserved1) (void);
 	void (*_gda_reserved2) (void);
@@ -121,6 +122,7 @@ GdaSet       *gda_set_new_from_spec_node       (xmlNodePtr xml_spec, GError **er
 gboolean      gda_set_set_holder_value         (GdaSet *set, GError **error, const gchar *holder_id, ...);
 const GValue *gda_set_get_holder_value         (GdaSet *set, const gchar *holder_id);
 GdaHolder    *gda_set_get_holder               (GdaSet *set, const gchar *holder_id);
+GdaHolder    *gda_set_get_nth_holder           (GdaSet *set, gint pos);
 gboolean      gda_set_add_holder               (GdaSet *set, GdaHolder *holder);
 void          gda_set_remove_holder            (GdaSet *set, GdaHolder *holder);
 void          gda_set_merge_with_set           (GdaSet *set, GdaSet *set_to_merge);
diff --git a/libgda/libgda.symbols b/libgda/libgda.symbols
index dbb7c2a..2a77133 100644
--- a/libgda/libgda.symbols
+++ b/libgda/libgda.symbols
@@ -548,6 +548,7 @@
 	gda_set_get_holder
 	gda_set_get_holder_value
 	gda_set_get_node
+	gda_set_get_nth_holder
 	gda_set_get_source
 	gda_set_get_source_for_model
 	gda_set_get_type
diff --git a/libgda/thread-wrapper/gda-thread-provider.c b/libgda/thread-wrapper/gda-thread-provider.c
index 2bb15c6..51e65d1 100644
--- a/libgda/thread-wrapper/gda-thread-provider.c
+++ b/libgda/thread-wrapper/gda-thread-provider.c
@@ -469,7 +469,6 @@ _gda_thread_provider_handle_virtual_connection (GdaThreadProvider *provider, Gda
 	ThreadConnectionData *cdata;
 	GdaServerProvider *sub_prov;
 	GdaThreadWrapper *wr;
-	gboolean wr_created = FALSE;
 	GdaConnection *cnc;
 
 	g_return_val_if_fail (GDA_IS_THREAD_PROVIDER (provider), NULL);
@@ -1510,6 +1509,13 @@ sub_thread_execute_statement (ExecuteStatementData *data, GError **error)
 {
 	/* WARNING: function executed in sub thread! */
 	GObject *retval;
+	
+#ifdef GDA_DEBUG_NO
+	g_print ("%p Starting sleep in %s()...\n", g_thread_self (), __FUNCTION__);
+	sleep (10);
+	g_print ("%p finished sleeping in %s().\n", g_thread_self (), __FUNCTION__);
+#endif
+
 	retval = PROV_CLASS (data->prov)->statement_execute (data->prov,
 							     data->cnc,
 							     data->stmt,
diff --git a/tools/browser/browser-connection.c b/tools/browser/browser-connection.c
index 90d2f1d..6819f16 100644
--- a/tools/browser/browser-connection.c
+++ b/tools/browser/browser-connection.c
@@ -977,8 +977,13 @@ wrapper_statement_execute (StmtExecData *data, GError **error)
 						data->params, data->model_usage,
 						data->need_last_insert_row ? &last_insert_row : NULL,
 						error);
-	if (obj && last_insert_row)
-		g_object_set_data (obj, "__bcnc_last_inserted_row", last_insert_row);
+	if (obj) {
+		if (GDA_IS_DATA_MODEL (obj))
+			/* force loading of rows if necessary */
+			gda_data_model_get_n_rows ((GdaDataModel*) obj);
+		else if (last_insert_row)
+			g_object_set_data (obj, "__bcnc_last_inserted_row", last_insert_row);
+	}
 	return obj ? obj : (gpointer) 0x01;
 }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]