[libgda] GdaBrowser's data manager: corrected data sources sorting



commit 986a34730a28ea4324daedf4715fa789356ce81c
Author: Vivien Malerba <malerba gnome-db org>
Date:   Sun Aug 1 10:46:24 2010 +0200

    GdaBrowser's data manager: corrected data sources sorting

 tools/browser/browser-connection-priv.h          |    2 +-
 tools/browser/data-manager/data-console.c        |   63 ++++++++-------
 tools/browser/data-manager/data-source-manager.c |   91 +++++++++++++++++++---
 tools/browser/data-manager/data-source.c         |   61 ++++++++++++--
 tools/browser/data-manager/data-source.h         |    2 +
 tools/browser/data-manager/data-widget.c         |   10 ++-
 tools/browser/data-manager/xml-spec-editor.c     |    4 +
 tools/browser/doc/tmpl/browser-connection.sgml   |    1 +
 8 files changed, 184 insertions(+), 50 deletions(-)
---
diff --git a/tools/browser/browser-connection-priv.h b/tools/browser/browser-connection-priv.h
index 283596e..ce1e38f 100644
--- a/tools/browser/browser-connection-priv.h
+++ b/tools/browser/browser-connection-priv.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 Vivien Malerba
+ * Copyright (C) 2009 - 2010 Vivien Malerba
  *
  * This Library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public License as
diff --git a/tools/browser/data-manager/data-console.c b/tools/browser/data-manager/data-console.c
index 5ba0ac1..5a2f5fe 100644
--- a/tools/browser/data-manager/data-console.c
+++ b/tools/browser/data-manager/data-console.c
@@ -78,6 +78,8 @@ static void data_console_init       (DataConsole *dconsole, DataConsoleClass *kl
 static void data_console_dispose    (GObject *object);
 static void data_console_show_all   (GtkWidget *widget);
 
+static void data_source_mgr_changed_cb (DataSourceManager *mgr, DataConsole *dconsole);
+
 /* BrowserPage interface */
 static void                 data_console_page_init (BrowserPageIface *iface);
 static GtkActionGroup      *data_console_page_get_actions_group (BrowserPage *page);
@@ -143,8 +145,12 @@ data_console_dispose (GObject *object)
 			g_object_unref (dconsole->priv->bcnc);
 		if (dconsole->priv->agroup)
 			g_object_unref (dconsole->priv->agroup);
-		if (dconsole->priv->mgr)
+		if (dconsole->priv->mgr) {
+			g_signal_handlers_disconnect_by_func (dconsole->priv->mgr,
+							      G_CALLBACK (data_source_mgr_changed_cb),
+							      dconsole);
 			g_object_unref (dconsole->priv->mgr);
+		}
 		g_free (dconsole->priv);
 		dconsole->priv = NULL;
 	}
@@ -189,7 +195,6 @@ static void execute_clicked_cb (GtkButton *button, DataConsole *dconsole);
 static void help_clicked_cb (GtkButton *button, DataConsole *dconsole);
 #endif
 static void spec_editor_toggled_cb (GtkToggleButton *button, DataConsole *dconsole);
-static void data_source_mgr_changed_cb (DataSourceManager *mgr, DataConsole *dconsole);
 
 /**
  * data_console_new
@@ -277,32 +282,6 @@ data_console_new (BrowserConnection *bcnc)
 	gtk_notebook_append_page (GTK_NOTEBOOK (dconsole->priv->editors_notebook),
 				  dconsole->priv->xml_sped, NULL);
 
-#define DEFAULT_XML \
-"<data>\n" \
-"    <!-- This is an example of XML code, this editor will be replaced by a UI editing,\n" \
-"         but will still be visible and useable for quick access\n" \
-"    -->\n" \
-"\n    <!-- specifies that we want the contents of the 'customers' table -->\n" \
-"    <table name=\"customers\"/>\n" \
-"\n    <!-- specifies that we want the contents of the 'orders' table, where the order ID \n" \
-"         depends on the selected customer's ID -->\n"						\
-"    <table name=\"orders\">\n" \
-"        <depend foreign_key_table=\"customers\"/>\n" \
-"    </table>\n" \
-"\n    <!-- specifies that we want the result of the execution of a SELECT query, notice the WHERE clause\n" \
-"          which enables to filter on the previously selected order ID-->\n" \
-"    <query title=\"Order's products\" id=\"products\">\n" \
-"        SELECT p.ref, p.name FROM products p INNER JOIN order_contents o ON (o.product_ref=p.ref) WHERE o order_id=##orders id::int\n" \
-"    </query>\n" \
-"\n    <!-- a more complicated query this time giving all the orders (for any customer) containing the \n" \
-"         selected product from the previous SELECT query-->\n" \
-"    <query title=\"All orders with this product\" id=\"aorders\">\n" \
-"        SELECT distinct c.name, o.creation_date, o.delivery_date FROM customers c INNER JOIN orders o ON (o.customer=c.id) INNER JOIN order_contents oc ON (oc.order_id=o.id) INNER JOIN products p ON (oc product_ref=##products ref::string)\n" \
-"    </query>\n" \
-"</data>"
-
-	xml_spec_editor_set_xml_text (XML_SPEC_EDITOR (dconsole->priv->xml_sped), DEFAULT_XML);
-
 	dconsole->priv->ui_sped = ui_spec_editor_new (dconsole->priv->mgr);
 	gtk_notebook_append_page (GTK_NOTEBOOK (dconsole->priv->editors_notebook),
 				  dconsole->priv->ui_sped, NULL);
@@ -365,6 +344,34 @@ data_console_new (BrowserConnection *bcnc)
         gtk_widget_show_all (hpaned);
 	gtk_widget_hide (dconsole->priv->params_top);
 
+	/* initial contents for tests */
+#define DEFAULT_XML \
+"<data>\n" \
+"    <!-- This is an example of XML code, this editor will be replaced by a UI editing,\n" \
+"         but will still be visible and useable for quick access\n" \
+"    -->\n" \
+"\n    <!-- specifies that we want the contents of the 'customers' table -->\n" \
+"    <table name=\"customers\"/>\n" \
+"\n    <!-- specifies that we want the contents of the 'orders' table, where the order ID \n" \
+"         depends on the selected customer's ID -->\n"						\
+"    <table name=\"orders\">\n" \
+"        <depend foreign_key_table=\"customers\"/>\n" \
+"    </table>\n" \
+"\n    <!-- specifies that we want the result of the execution of a SELECT query, notice the WHERE clause\n" \
+"          which enables to filter on the previously selected order ID-->\n" \
+"    <query title=\"Order's products\" id=\"products\">\n" \
+"        SELECT p.ref, p.name FROM products p INNER JOIN order_contents o ON (o.product_ref=p.ref) WHERE o order_id=##orders id::int\n" \
+"    </query>\n" \
+"\n    <!-- a more complicated query this time giving all the orders (for any customer) containing the \n" \
+"         selected product from the previous SELECT query-->\n" \
+"    <query title=\"All orders with this product\" id=\"aorders\">\n" \
+"        SELECT distinct c.name, o.creation_date, o.delivery_date FROM customers c INNER JOIN orders o ON (o.customer=c.id) INNER JOIN order_contents oc ON (oc.order_id=o.id) INNER JOIN products p ON (oc product_ref=##products ref::string)\n" \
+"    </query>\n" \
+"</data>"
+
+	//xml_spec_editor_set_xml_text (XML_SPEC_EDITOR (dconsole->priv->xml_sped), DEFAULT_XML);
+
+
 	return (GtkWidget*) dconsole;
 }
 
diff --git a/tools/browser/data-manager/data-source-manager.c b/tools/browser/data-manager/data-source-manager.c
index 18be2e7..27245ff 100644
--- a/tools/browser/data-manager/data-source-manager.c
+++ b/tools/browser/data-manager/data-source-manager.c
@@ -166,8 +166,10 @@ source_depends_on (DataSource *source1, DataSource *source2)
 	GdaSet *import;
 	import = data_source_get_import (source1);
 	if (!import) {
+#ifdef DEBUG_SOURCES_SORT
 		g_print ("[%s] has no import\n",
 			 data_source_get_title (source1));
+#endif
 		return FALSE;
 	}
 
@@ -177,15 +179,19 @@ source_depends_on (DataSource *source1, DataSource *source2)
 	for (holders = import->holders; holders; holders = holders->next) {
 		GdaHolder *holder = (GdaHolder*) holders->data;
 		if (GPOINTER_TO_INT (g_hash_table_lookup (export_columns, gda_holder_get_id (holder))) >= 1) {
+#ifdef DEBUG_SOURCES_SORT
 			g_print ("[%s] ====> [%s]\n",
 				 data_source_get_title (source1),
 				 data_source_get_title (source2));
+#endif
 			return TRUE;
 		}
 	}
+#ifdef DEBUG_SOURCES_SORT
 	g_print ("[%s] ..... [%s]\n",
 		 data_source_get_title (source1),
 		 data_source_get_title (source2));
+#endif
 	return FALSE;
 }
 
@@ -198,7 +204,7 @@ data_source_compare_func (DataSource *s1, DataSource *s2)
 	else if (source_depends_on (s2, s1))
 		return -1;
 	else
-		return 0;
+		return 1;
 }
 
 /**
@@ -213,18 +219,80 @@ data_source_manager_add_source (DataSourceManager *mgr, DataSource *source)
 	g_return_if_fail (IS_DATA_SOURCE (source));
 
 	g_return_if_fail (! g_slist_find (mgr->priv->sources_list, source));
-	mgr->priv->sources_list = g_slist_insert_sorted (mgr->priv->sources_list,
-							 g_object_ref (source),
-							 (GCompareFunc) data_source_compare_func);
+
+#ifdef DEBUG_SOURCES_SORT
+	g_print ("Adding source [%s]\n", data_source_get_title (source));
+#endif
+	if (! mgr->priv->sources_list)
+		mgr->priv->sources_list = g_slist_append (NULL, g_object_ref (source));
+	else {
+		GSList *list;
+		gint lefti, righti, curi;
+		gboolean deperror = FALSE;
+		lefti = -1;
+		righti = g_slist_length (mgr->priv->sources_list);
+		for (curi = 0, list = mgr->priv->sources_list;
+		     list;
+		     curi++, list = list->next) {
+			if (source_depends_on (source, (DataSource*) list->data))
+				lefti = MAX (lefti, curi);
+			else if (source_depends_on ((DataSource*) list->data, source))
+				righti = MIN (righti, curi);
+		}
+		if (lefti < righti) {
+			/*g_print ("\tleft=%d right=%d\n", lefti, righti);*/
+			list = g_slist_nth (mgr->priv->sources_list, righti);
+			if (list)
+				mgr->priv->sources_list = g_slist_insert_before (mgr->priv->sources_list, list,
+										 g_object_ref (source));
+			else
+				mgr->priv->sources_list = g_slist_append (mgr->priv->sources_list,
+									  g_object_ref (source));
+		}
+		else {
+			if (lefti == righti) {
+				DataSource *sourcei;
+				sourcei = (DataSource*) g_slist_nth_data (mgr->priv->sources_list,
+									  lefti);
+				if (source_depends_on (source, sourcei) &&
+				    source_depends_on (sourcei, source)) {
+					/* there is an error */
+					deperror = TRUE;
+					TO_IMPLEMENT;
+				}
+			}
+			if (!deperror) {
+				GSList *olist;
+#ifdef DEBUG_SOURCES_SORT
+				g_print ("Reorganizing sources order\n");
+#endif
+				olist = g_slist_reverse (mgr->priv->sources_list);
+				mgr->priv->sources_list = NULL;
+				for (list = olist; list; list = list->next) {
+					data_source_manager_add_source (mgr, (DataSource*) list->data);
+					g_object_unref ((GObject*) list->data);
+				}
+				data_source_manager_add_source (mgr, source);
+			}
+		}
+	}
 	g_signal_emit (mgr, data_source_manager_signals[CHANGED], 0);
 
+#ifdef DEBUG_SOURCES_SORT
+	g_print ("Sources in manager:\n");
+#endif
 	GSList *list;
 	gint i;
 	for (i = 0, list = mgr->priv->sources_list; list; list = list->next, i++) {
 		DataSource *source = DATA_SOURCE (list->data);
+#ifdef DEBUG_SOURCES_SORT
 		g_print ("\t %d ... %s\n", i, 
-		 data_source_get_title (source));
+			 data_source_get_title (source));
+#endif
 	}
+#ifdef DEBUG_SOURCES_SORT
+	g_print ("\n");
+#endif
 }
 
 /**
@@ -348,12 +416,18 @@ data_source_manager_get_sources_array (DataSourceManager *mgr, GError **error)
 
 	GSList *list;
 	GArray *array = NULL;
+#ifdef DEBUG_SOURCES_SORT
 	g_print ("** Creating DataSource arrays\n");
+#endif
 	for (list = mgr->priv->sources_list; list; list = list->next) {
 		DataSource *source;
 		source = DATA_SOURCE (g_object_ref (G_OBJECT (list->data)));
+#ifdef DEBUG_SOURCES_SORT
 		g_print ("Taking into account source [%s]\n",
 			 data_source_get_title (source));
+#endif
+
+		data_source_should_rerun (source);
 
 		GdaSet *import;
 		import = data_source_get_import (source);
@@ -379,11 +453,6 @@ data_source_manager_get_sources_array (DataSourceManager *mgr, GError **error)
 				gint j;
 				for (j = 0; j < subarray->len; j++) {
 					DataSource *source2 = g_array_index (subarray, DataSource*, j);
-					g_print ("Source [%s] %s on source [%s]\n",
-						 data_source_get_title (source),
-						 source_depends_on (source, source2) ?
-						 "depends" : "does not depend",
-						 data_source_get_title (source2));
 					if (source_depends_on (source, source2)) {
 						dep_found = TRUE;
 						/* add source to column i+1 */
@@ -419,7 +488,9 @@ data_source_manager_get_sources_array (DataSourceManager *mgr, GError **error)
 		}
 	}
 
+#ifdef DEBUG_SOURCES_SORT
 	g_print ("** DataSource arrays created\n");
+#endif
 	return array;
 }
 
diff --git a/tools/browser/data-manager/data-source.c b/tools/browser/data-manager/data-source.c
index 652e097..e15a471 100644
--- a/tools/browser/data-manager/data-source.c
+++ b/tools/browser/data-manager/data-source.c
@@ -262,6 +262,9 @@ init_from_query (DataSource *source, xmlNodePtr node)
 	const gchar *remain;
 	xmlChar *contents;
 
+#ifdef DEBUG_SOURCE
+	g_print ("%s(%s [%s])\n", __FUNCTION__, source->priv->id, source->priv->title);
+#endif
 	contents = xmlNodeGetContent (node);
 
 	g_clear_error (& source->priv->init_error);
@@ -305,7 +308,9 @@ init_from_query (DataSource *source, xmlNodePtr node)
 					g_array_append_val (source->priv->export_names, tmp);
 					g_hash_table_insert (source->priv->export_columns, tmp,
 							     GINT_TO_POINTER (i + 1));
-					/* g_print ("EXPORT [%s]\n", tmp); */
+#ifdef DEBUG_SOURCE
+					g_print ("\tEXPORT [%s]\n", tmp);
+#endif
 
 					GdaSqlSelectField *sf = (GdaSqlSelectField *) list->data;
 					if (sf->validity_meta_table_column) {
@@ -314,7 +319,9 @@ init_from_query (DataSource *source, xmlNodePtr node)
 						g_array_append_val (source->priv->export_names, tmp);
 						g_hash_table_insert (source->priv->export_columns, tmp,
 								     GINT_TO_POINTER (i + 1));
-						/* g_print ("EXPORT [%s]\n", tmp); */
+#ifdef DEBUG_SOURCE
+						g_print ("\tEXPORT [%s]\n", tmp);
+#endif
 					}
 				}
 			}
@@ -327,13 +334,21 @@ init_from_query (DataSource *source, xmlNodePtr node)
 					      &source->priv->init_error);
 		if (source->priv->params) {
 			GSList *list;
-			for (list = source->priv->params->holders; list; list = list->next)
+			for (list = source->priv->params->holders; list; list = list->next) {
 				gda_holder_set_not_null (GDA_HOLDER (list->data), FALSE);
+#ifdef DEBUG_SOURCE
+				g_print ("\tIMPORT [%s]\n", gda_holder_get_id (GDA_HOLDER (list->data)));
+#endif
+			}
 
 			g_signal_connect (source->priv->params, "holder-changed",
 					  G_CALLBACK (params_changed_cb), source);
 		}
 	}
+
+#ifdef DEBUG_SOURCE
+	g_print ("\n");
+#endif
 }
 
 static GdaMetaTable *
@@ -387,6 +402,10 @@ static gboolean
 init_from_table_node (DataSource *source, xmlNodePtr node, GError **error)
 {
 	xmlChar *tname;
+
+#ifdef DEBUG_SOURCE
+	g_print ("%s(%s [%s])\n", __FUNCTION__, source->priv->id, source->priv->title);
+#endif
 	tname = xmlGetProp (node, BAD_CAST "name");
 	if (!tname) {
 		g_set_error (error, 0, 0,
@@ -452,7 +471,9 @@ init_from_table_node (DataSource *source, xmlNodePtr node, GError **error)
 		g_array_append_val (source->priv->export_names, tmp);
 		g_hash_table_insert (source->priv->export_columns, tmp,
 				     GINT_TO_POINTER (i + 1));
-		/*g_print ("EXPORT [%s]\n", tmp);*/
+#ifdef DEBUG_SOURCE
+		g_print ("\tEXPORT [%s]\n", tmp);
+#endif
 
 		if (source->priv->id)
 			tmp = g_strdup_printf ("%s %d", source->priv->id, i + 1);
@@ -461,7 +482,9 @@ init_from_table_node (DataSource *source, xmlNodePtr node, GError **error)
 		g_array_append_val (source->priv->export_names, tmp);
 		g_hash_table_insert (source->priv->export_columns, tmp,
 				     GINT_TO_POINTER (i + 1));
-		/*g_print ("EXPORT [%s]\n", tmp);*/
+#ifdef DEBUG_SOURCE
+		g_print ("\tEXPORT [%s]\n", tmp);
+#endif
 	}
 	xmlFree (tname);
 
@@ -560,16 +583,23 @@ init_from_table_node (DataSource *source, xmlNodePtr node, GError **error)
 				      &source->priv->init_error);
 	if (source->priv->params) {
 		GSList *list;
-		for (list = source->priv->params->holders; list; list = list->next)
+		for (list = source->priv->params->holders; list; list = list->next) {
 			gda_holder_set_not_null (GDA_HOLDER (list->data), FALSE);
+#ifdef DEBUG_SOURCE
+			g_print ("\tIMPORT [%s]\n", gda_holder_get_id (GDA_HOLDER (list->data)));
+#endif
+		}
 
 		g_signal_connect (source->priv->params, "holder-changed",
 				  G_CALLBACK (params_changed_cb), source);
 	}
 
-	g_print ("SQL [%s]\n", gda_statement_to_sql (source->priv->stmt, NULL, NULL));
+	/*g_print ("SQL [%s]\n", gda_statement_to_sql (source->priv->stmt, NULL, NULL));*/
 	g_object_unref (b);
 
+#ifdef DEBUG_SOURCE
+	g_print ("\n");
+#endif
 	return source->priv->stmt ? TRUE : FALSE;
 }
 
@@ -670,7 +700,7 @@ data_source_get_import (DataSource *source)
 }
 
 /**
- * data_source_set_external_import
+ * data_source_set_params
  */
 void
 data_source_set_params (DataSource *source, GdaSet *params)
@@ -706,7 +736,7 @@ data_source_set_params (DataSource *source, GdaSet *params)
 }
 
 /**
- * data_source_get_export_template
+ * data_source_get_export_names
  *
  * Returns: an array of strings, or %NULL
  */
@@ -881,3 +911,16 @@ data_source_get_title (DataSource *source)
 	else
 		return _("No name");
 }
+
+/**
+ * data_source_should_rerun
+ *
+ * The SELECT statement will be re-executed the next time
+ * data_source_execute() is called 
+ */
+void
+data_source_should_rerun (DataSource *source)
+{
+	g_return_if_fail (IS_DATA_SOURCE (source));
+	source->priv->need_rerun = TRUE;
+}
diff --git a/tools/browser/data-manager/data-source.h b/tools/browser/data-manager/data-source.h
index 10088ca..b7dd4c9 100644
--- a/tools/browser/data-manager/data-source.h
+++ b/tools/browser/data-manager/data-source.h
@@ -75,6 +75,8 @@ DataSource         *data_source_new_from_table      (BrowserConnection *bcnc,
 DataSource         *data_source_new_from_select     (BrowserConnection *bcnc, const gchar *select_sql);
 */
 
+void                data_source_should_rerun        (DataSource *source);
+
 G_END_DECLS
 
 #endif
diff --git a/tools/browser/data-manager/data-widget.c b/tools/browser/data-manager/data-widget.c
index ca24fd7..ca26c25 100644
--- a/tools/browser/data-manager/data-widget.c
+++ b/tools/browser/data-manager/data-widget.c
@@ -307,8 +307,14 @@ data_widget_new (GArray *sources_array)
 static void
 data_part_free (DataPart *part)
 {
-	if (part->source)
+	if (part->source) {
+		g_signal_handlers_disconnect_by_func (part->source,
+						      G_CALLBACK (source_exec_started_cb), part);
+		g_signal_handlers_disconnect_by_func (part->source,
+						      G_CALLBACK (source_exec_finished_cb), part);
 		g_object_unref (part->source);
+	}
+
 	if (part->export_data)
 		g_object_unref (part->export_data);
 	if (part->dep_parts)
@@ -342,7 +348,7 @@ source_exec_finished_cb (DataSource *source, GError *error, DataPart *part)
 	GtkWidget *wid;
 	browser_spinner_stop (part->spinner);
 	
-	/*g_print ("Execution of source [%s] finished\n", data_source_get_title (part->source));*/
+	g_print ("==== Execution of source [%s] finished\n", data_source_get_title (part->source));
 	if (error) {
 		gchar *tmp;
 		tmp = g_markup_printf_escaped ("\n<b>Error:\n</b>%s",
diff --git a/tools/browser/data-manager/xml-spec-editor.c b/tools/browser/data-manager/xml-spec-editor.c
index 0bb15e4..c3e3d99 100644
--- a/tools/browser/data-manager/xml-spec-editor.c
+++ b/tools/browser/data-manager/xml-spec-editor.c
@@ -277,8 +277,12 @@ xml_spec_editor_set_xml_text (XmlSpecEditor *sped, const gchar *xml)
 {
 	g_return_if_fail (IS_XML_SPEC_EDITOR (sped));
 
+	g_signal_handlers_block_by_func (sped->priv->buffer,
+					 G_CALLBACK (editor_changed_cb), sped);
 	gtk_text_buffer_set_text (sped->priv->buffer, xml, -1);
 	signal_editor_changed (sped);
+	g_signal_handlers_unblock_by_func (sped->priv->buffer,
+					   G_CALLBACK (editor_changed_cb), sped);
 }
 
 /**
diff --git a/tools/browser/doc/tmpl/browser-connection.sgml b/tools/browser/doc/tmpl/browser-connection.sgml
index a187793..2c9a52f 100644
--- a/tools/browser/doc/tmpl/browser-connection.sgml
+++ b/tools/browser/doc/tmpl/browser-connection.sgml
@@ -33,6 +33,7 @@ An opened connection
 @nb_no_job_waits: 
 @executed_statements: 
 @meta_store_signal: 
+ transaction_status_signal: 
 @name: 
 @cnc: 
 @dict_file_name: 



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