[libgda] GdaBrowser's data manager: corrected data sources sorting
- From: Vivien Malerba <vivien src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgda] GdaBrowser's data manager: corrected data sources sorting
- Date: Sun, 1 Aug 2010 15:53:02 +0000 (UTC)
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]