[libgda] Support variables in GdaBrowser's data manager
- From: Vivien Malerba <vivien src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgda] Support variables in GdaBrowser's data manager
- Date: Wed, 24 Mar 2010 20:48:17 +0000 (UTC)
commit 975e6912a4dc351e1a45ca68d0cb8cd0d2db3b57
Author: Vivien Malerba <malerba gnome-db org>
Date: Wed Mar 24 21:44:26 2010 +0100
Support variables in GdaBrowser's data manager
tools/browser/browser-connection-priv.h | 3 +-
tools/browser/browser-connection.c | 100 +++++++++++++-
tools/browser/browser-connection.h | 7 +
tools/browser/data-manager/data-console.c | 46 ++++++-
tools/browser/data-manager/data-source.c | 113 +++++++++++++--
tools/browser/data-manager/data-source.h | 1 +
tools/browser/data-manager/spec-editor.c | 174 +++++++++++++++++++-----
tools/browser/data-manager/spec-editor.h | 4 +
tools/browser/doc/gda-browser-sections.txt | 3 +
tools/browser/doc/tmpl/browser-connection.sgml | 20 +++-
tools/browser/query-exec/query-console.c | 47 +------
11 files changed, 417 insertions(+), 101 deletions(-)
---
diff --git a/tools/browser/browser-connection-priv.h b/tools/browser/browser-connection-priv.h
index 4371893..0cce524 100644
--- a/tools/browser/browser-connection-priv.h
+++ b/tools/browser/browser-connection-priv.h
@@ -32,7 +32,6 @@ struct _BrowserConnectionPrivate {
GdaConnection *cnc;
gchar *dict_file_name;
GdaSqlParser *parser;
- GSList *variables; /* list of BrowserVariable pointer, owned here */
GdaDsnInfo dsn_info;
GMutex *p_mstruct_mutex;
@@ -45,6 +44,8 @@ struct _BrowserConnectionPrivate {
gchar *busy_reason;
GdaConnection *store_cnc;
+
+ GdaSet *variables;
};
void browser_connection_set_busy_state (BrowserConnection *bcnc, gboolean busy, const gchar *busy_reason);
diff --git a/tools/browser/browser-connection.c b/tools/browser/browser-connection.c
index 0afa9cb..bbe5ff3 100644
--- a/tools/browser/browser-connection.c
+++ b/tools/browser/browser-connection.c
@@ -255,6 +255,8 @@ browser_connection_init (BrowserConnection *bcnc)
bcnc->priv->bfav = NULL;
bcnc->priv->store_cnc = NULL;
+
+ bcnc->priv->variables = NULL;
}
static void
@@ -425,6 +427,9 @@ browser_connection_dispose (GObject *object)
bcnc = BROWSER_CONNECTION (object);
if (bcnc->priv) {
+ if (bcnc->priv->variables)
+ g_object_unref (bcnc->priv->variables);
+
if (bcnc->priv->store_cnc)
g_object_unref (bcnc->priv->store_cnc);
@@ -459,10 +464,6 @@ browser_connection_dispose (GObject *object)
}
if (bcnc->priv->parser)
g_object_unref (bcnc->priv->parser);
- if (bcnc->priv->variables) {
- g_slist_foreach (bcnc->priv->variables, (GFunc) g_object_unref, NULL);
- g_slist_free (bcnc->priv->variables);
- }
if (bcnc->priv->bfav) {
g_signal_handlers_disconnect_by_func (bcnc->priv->bfav,
G_CALLBACK (fav_changed_cb), bcnc);
@@ -1399,3 +1400,94 @@ browser_connection_get_table_column_attribute (BrowserConnection *bcnc,
return retval;
}
+
+/**
+ * browser_connection_keep_variables
+ * @bcnc: a #BrowserConnection object
+ * @set: a #GdaSet containing variables for which a copy has to be done
+ *
+ * Makes a copy of the variables in @set and keep them in @bcnc. Retreive them
+ * using browser_connection_load_variables()
+ */
+void
+browser_connection_keep_variables (BrowserConnection *bcnc, GdaSet *set)
+{
+ g_return_if_fail (BROWSER_IS_CONNECTION (bcnc));
+ if (!set)
+ return;
+ g_return_if_fail (GDA_IS_SET (set));
+
+ if (! bcnc->priv->variables) {
+ bcnc->priv->variables = gda_set_copy (set);
+ return;
+ }
+
+ GSList *list;
+ for (list = set->holders; list; list = list->next) {
+ GdaHolder *nh, *eh;
+ nh = GDA_HOLDER (list->data);
+ eh = gda_set_get_holder (bcnc->priv->variables, gda_holder_get_id (nh));
+ if (eh) {
+ if (gda_holder_get_g_type (nh) == gda_holder_get_g_type (eh)) {
+ const GValue *cvalue;
+ cvalue = gda_holder_get_value (nh);
+ gda_holder_set_value (eh, cvalue, NULL);
+ }
+ else {
+ gda_set_remove_holder (bcnc->priv->variables, eh);
+ eh = gda_holder_copy (nh);
+ gda_set_add_holder (bcnc->priv->variables, eh);
+ g_object_unref (eh);
+ }
+ }
+ else {
+ eh = gda_holder_copy (nh);
+ gda_set_add_holder (bcnc->priv->variables, eh);
+ g_object_unref (eh);
+ }
+ }
+}
+
+/**
+ * browser_connection_load_variables
+ * @bcnc: a #BrowserConnection object
+ * @set: a #GdaSet which will in the end contain (if any) variables stored in @bcnc
+ *
+ * For each #GdaHolder in @set, set the value if one is available in @bcnc.
+ */
+void
+browser_connection_load_variables (BrowserConnection *bcnc, GdaSet *set)
+{
+ g_return_if_fail (BROWSER_IS_CONNECTION (bcnc));
+ if (!set)
+ return;
+ g_return_if_fail (GDA_IS_SET (set));
+
+ if (! bcnc->priv->variables)
+ return;
+
+ GSList *list;
+ for (list = set->holders; list; list = list->next) {
+ GdaHolder *nh, *eh;
+ nh = GDA_HOLDER (list->data);
+ eh = gda_set_get_holder (bcnc->priv->variables, gda_holder_get_id (nh));
+ if (eh) {
+ if (gda_holder_get_g_type (nh) == gda_holder_get_g_type (eh)) {
+ const GValue *cvalue;
+ cvalue = gda_holder_get_value (eh);
+ gda_holder_set_value (nh, cvalue, NULL);
+ }
+ else if (g_value_type_transformable (gda_holder_get_g_type (eh),
+ gda_holder_get_g_type (nh))) {
+ const GValue *evalue;
+ GValue *nvalue;
+ evalue = gda_holder_get_value (eh);
+ nvalue = gda_value_new (gda_holder_get_g_type (nh));
+ if (g_value_transform (evalue, nvalue))
+ gda_holder_take_value (nh, nvalue, NULL);
+ else
+ gda_value_free (nvalue);
+ }
+ }
+ }
+}
diff --git a/tools/browser/browser-connection.h b/tools/browser/browser-connection.h
index 3c89947..327239f 100644
--- a/tools/browser/browser-connection.h
+++ b/tools/browser/browser-connection.h
@@ -118,6 +118,13 @@ gchar *browser_connection_get_table_column_attribute (BrowserConne
const gchar *attr_name,
GError **error);
+/*
+ * Variables used at various places and for which a copy of the last recent value
+ * is stored in the BrowserConnection object
+ */
+void browser_connection_keep_variables (BrowserConnection *bcnc, GdaSet *set);
+void browser_connection_load_variables (BrowserConnection *bcnc, GdaSet *set);
+
G_END_DECLS
#endif
diff --git a/tools/browser/data-manager/data-console.c b/tools/browser/data-manager/data-console.c
index 79cb246..b8c22a4 100644
--- a/tools/browser/data-manager/data-console.c
+++ b/tools/browser/data-manager/data-console.c
@@ -52,6 +52,7 @@ struct _DataConsolePrivate {
GtkWidget *data;
GtkActionGroup *agroup;
+ gboolean toggling;
GtkToggleButton *params_toggle;
GtkWidget *params_top;
GtkWidget *params_form_box;
@@ -168,6 +169,7 @@ static void editor_clear_clicked_cb (GtkButton *button, DataConsole *dconsole);
static void variables_clicked_cb (GtkToggleButton *button, DataConsole *dconsole);
static void execute_clicked_cb (GtkButton *button, DataConsole *dconsole);
static void spec_editor_toggled_cb (GtkToggleButton *button, DataConsole *dconsole);
+static void spec_editor_changed_cb (SpecEditor *sped, DataConsole *dconsole);
/**
* data_console_new
@@ -250,6 +252,8 @@ data_console_new (BrowserConnection *bcnc)
gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
dconsole->priv->sped = spec_editor_new (dconsole->priv->bcnc);
+ g_signal_connect (dconsole->priv->sped, "changed",
+ G_CALLBACK (spec_editor_changed_cb), dconsole);
gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET (dconsole->priv->sped), TRUE, TRUE, 0);
#define DEFAULT_XML \
@@ -276,7 +280,7 @@ data_console_new (BrowserConnection *bcnc)
" </query>\n" \
"</data>"
- spec_editor_set_xml_text (dconsole->priv->sped, DEFAULT_XML);
+ //spec_editor_set_xml_text (dconsole->priv->sped, DEFAULT_XML);
/* buttons */
GtkWidget *bbox, *button;
@@ -363,6 +367,35 @@ spec_editor_toggled_cb (GtkToggleButton *button, DataConsole *dconsole)
}
static void
+spec_editor_changed_cb (SpecEditor *sped, DataConsole *dconsole)
+{
+ if (dconsole->priv->params_form) {
+ gtk_widget_destroy (dconsole->priv->params_form);
+ dconsole->priv->params_form = NULL;
+ }
+
+ GdaSet *params;
+ gboolean show_variables = FALSE;
+ params = spec_editor_get_params (sped);
+ if (params) {
+ dconsole->priv->params_form = gdaui_basic_form_new (params);
+ g_object_set ((GObject*) dconsole->priv->params_form,
+ "show-actions", TRUE, NULL);
+ show_variables = TRUE;
+ }
+ else {
+ dconsole->priv->params_form = gtk_label_new ("");
+ gtk_label_set_markup (GTK_LABEL (dconsole->priv->params_form), VARIABLES_HELP);
+ }
+ gtk_container_add (GTK_CONTAINER (dconsole->priv->params_form_box),
+ dconsole->priv->params_form);
+ gtk_widget_show (dconsole->priv->params_form);
+
+ /* force showing variables */
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dconsole->priv->params_toggle), show_variables);
+}
+
+static void
editor_clear_clicked_cb (GtkButton *button, DataConsole *dconsole)
{
spec_editor_set_xml_text (dconsole->priv->sped, "");
@@ -405,9 +438,14 @@ compose_mode_toggled_cb (GtkToggleAction *action, DataConsole *dconsole)
{
gint pagenb;
+ if (dconsole->priv->toggling) {
+ dconsole->priv->toggling = FALSE;
+ return;
+ }
+
pagenb = gtk_notebook_get_current_page (GTK_NOTEBOOK (dconsole->priv->notebook));
if (pagenb == PAGE_XML) {
- /* parse XML and create the data */
+ /* Get Data sources */
GArray *sources_array;
GError *lerror = NULL;
sources_array = spec_editor_get_sources_array (dconsole->priv->sped, &lerror);
@@ -434,6 +472,10 @@ compose_mode_toggled_cb (GtkToggleAction *action, DataConsole *dconsole)
_("Error parsing XML specifications"));
g_clear_error (&lerror);
}
+ if (pagenb == PAGE_XML) {
+ dconsole->priv->toggling = TRUE;
+ gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
+ }
}
else {
/* simply change the current page */
diff --git a/tools/browser/data-manager/data-source.c b/tools/browser/data-manager/data-source.c
index 9c3521b..af6c07b 100644
--- a/tools/browser/data-manager/data-source.c
+++ b/tools/browser/data-manager/data-source.c
@@ -59,9 +59,12 @@ struct _DataSourcePrivate {
gchar *select_sql;
guint exec_id;
+ gboolean executing;
+ gboolean exec_again;
GdaStatement *stmt;
- GdaSet *params;
+ GdaSet *ext_params; /* "free" parameters */
+ GdaSet *params; /* all the params used when executing @stmt */
gboolean need_rerun; /* set to %TRUE if @params has changed since the last exec */
GError *exec_error;
@@ -130,6 +133,9 @@ data_source_init (DataSource *source)
source->priv = g_new0 (DataSourcePrivate, 1);
source->priv->bcnc = NULL;
source->priv->need_rerun = FALSE;
+ source->priv->exec_id = 0;
+ source->priv->executing = FALSE;
+ source->priv->exec_again = FALSE;
}
static void
@@ -139,6 +145,13 @@ params_changed_cb (GdaSet *params, GdaHolder *holder, DataSource *source)
}
static void
+ext_params_changed_cb (GdaSet *params, GdaHolder *holder, DataSource *source)
+{
+ source->priv->need_rerun = TRUE;
+ data_source_execute (source, NULL);
+}
+
+static void
data_source_dispose (GObject *object)
{
DataSource *source;
@@ -158,6 +171,12 @@ data_source_dispose (GObject *object)
G_CALLBACK (params_changed_cb), source);
g_object_unref (source->priv->params);
}
+ if (source->priv->ext_params) {
+ g_signal_handlers_disconnect_by_func (source->priv->ext_params,
+ G_CALLBACK (ext_params_changed_cb),
+ source);
+ g_object_unref (source->priv->ext_params);
+ }
g_free (source->priv->id);
g_free (source->priv->title);
@@ -401,7 +420,7 @@ 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);
+ /*g_print ("EXPORT [%s]\n", tmp);*/
if (source->priv->id)
tmp = g_strdup_printf ("%s %d", source->priv->id, i + 1);
@@ -410,7 +429,7 @@ 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);
+ /*g_print ("EXPORT [%s]\n", tmp);*/
}
xmlFree (tname);
@@ -515,9 +534,12 @@ exec_end_timeout_cb (DataSource *source)
{
GObject *obj;
+ g_return_val_if_fail (source->priv->exec_id > 0, FALSE);
+
g_clear_error (&source->priv->exec_error);
obj = browser_connection_execution_get_result (source->priv->bcnc,
- source->priv->exec_id, NULL,
+ source->priv->exec_id,
+ NULL,
&source->priv->exec_error);
if (obj) {
if (GDA_IS_DATA_MODEL (obj)) {
@@ -531,19 +553,29 @@ exec_end_timeout_cb (DataSource *source)
gda_data_model_thaw (source->priv->model);
gda_data_model_reset (source->priv->model);
}
+ /*gda_data_model_dump (source->priv->model, NULL);*/
}
else {
g_object_unref (obj);
g_set_error (&source->priv->exec_error, 0, 0,
_("Statement to execute is not a selection statement"));
}
+
source->priv->exec_id = 0;
g_signal_emit (source, data_source_signals [EXEC_FINISHED], 0, source->priv->exec_error);
+ if (source->priv->exec_again) {
+ source->priv->exec_again = FALSE;
+ data_source_execute (source, NULL);
+ }
return FALSE;
}
else if (source->priv->exec_error) {
source->priv->exec_id = 0;
g_signal_emit (source, data_source_signals [EXEC_FINISHED], 0, source->priv->exec_error);
+ if (source->priv->exec_again) {
+ source->priv->exec_again = FALSE;
+ data_source_execute (source, NULL);
+ }
return FALSE;
}
else
@@ -557,7 +589,7 @@ gboolean
data_source_execution_going_on (DataSource *source)
{
g_return_val_if_fail (IS_DATA_SOURCE (source), FALSE);
- return source->priv->exec_id == 0 ? FALSE : TRUE;
+ return source->priv->executing || (source->priv->exec_id > 0);
}
/**
@@ -573,6 +605,42 @@ data_source_get_import (DataSource *source)
}
/**
+ * data_source_set_external_import
+ */
+void
+data_source_set_params (DataSource *source, GdaSet *params)
+{
+ gboolean bound = FALSE;
+ g_return_if_fail (IS_DATA_SOURCE (source));
+ g_return_if_fail (!params || GDA_IS_SET (params));
+
+ if (source->priv->ext_params) {
+ g_signal_handlers_disconnect_by_func (source->priv->ext_params,
+ G_CALLBACK (ext_params_changed_cb), source);
+ g_object_unref (source->priv->ext_params);
+ source->priv->ext_params = NULL;
+ }
+
+ if (source->priv->params) {
+ GSList *list;
+ for (list = source->priv->params->holders; list; list = list->next) {
+ GdaHolder *holder = GDA_HOLDER (list->data);
+ GdaHolder *bind = NULL;
+ if (params)
+ bind = gda_set_get_holder (params, gda_holder_get_id (holder));
+ if (gda_holder_set_bind (holder, bind, NULL))
+ bound = TRUE;
+ }
+ }
+
+ if (params && bound) {
+ source->priv->ext_params = g_object_ref (params);
+ g_signal_connect (params, "holder-changed",
+ G_CALLBACK (ext_params_changed_cb), source);
+ }
+}
+
+/**
* data_source_get_export_template
*
* Returns: an array of strings, or %NULL
@@ -597,15 +665,24 @@ data_source_get_export_columns (DataSource *source)
}
/**
- * data_source_start_execution
+ * data_source_execute
*/
void
data_source_execute (DataSource *source, GError **error)
{
GError *lerror = NULL;
gboolean has_exec = TRUE;
+ guint exec_id = 0;
g_return_if_fail (IS_DATA_SOURCE (source));
-
+
+ if (source->priv->exec_again)
+ return;
+ if (source->priv->executing || (source->priv->exec_id > 0)) {
+ source->priv->exec_again = TRUE;
+ return;
+ }
+
+ source->priv->executing = TRUE;
if (! source->priv->stmt) {
if (source->priv->init_error)
g_propagate_error (error, source->priv->init_error);
@@ -620,29 +697,35 @@ data_source_execute (DataSource *source, GError **error)
* wrong thread */
source->priv->need_rerun = FALSE;
gda_data_model_freeze (source->priv->model);
- source->priv->exec_id = browser_connection_rerun_select (source->priv->bcnc,
- source->priv->model, &lerror);
+ exec_id = browser_connection_rerun_select (source->priv->bcnc,
+ source->priv->model, &lerror);
}
else
has_exec = FALSE;
}
else
- source->priv->exec_id = browser_connection_execute_statement (source->priv->bcnc,
- source->priv->stmt,
- source->priv->params,
- GDA_STATEMENT_MODEL_RANDOM_ACCESS | GDA_STATEMENT_MODEL_ALLOW_NOPARAM,
- FALSE, &lerror);
+ exec_id = browser_connection_execute_statement (source->priv->bcnc,
+ source->priv->stmt,
+ source->priv->params,
+ GDA_STATEMENT_MODEL_RANDOM_ACCESS |
+ GDA_STATEMENT_MODEL_ALLOW_NOPARAM,
+ FALSE, &lerror);
+
if (has_exec) {
g_signal_emit (source, data_source_signals [EXEC_STARTED], 0);
- if (! source->priv->exec_id) {
+ if (! exec_id) {
+ gda_data_model_thaw (source->priv->model);
+ gda_data_model_reset (source->priv->model);
g_signal_emit (source, data_source_signals [EXEC_FINISHED], 0, lerror);
g_propagate_error (error, lerror);
}
else {
/* monitor the end of execution */
+ source->priv->exec_id = exec_id;
g_timeout_add (50, (GSourceFunc) exec_end_timeout_cb, source);
}
}
+ source->priv->executing = FALSE;
}
/*
diff --git a/tools/browser/data-manager/data-source.h b/tools/browser/data-manager/data-source.h
index 391eca6..720c719 100644
--- a/tools/browser/data-manager/data-source.h
+++ b/tools/browser/data-manager/data-source.h
@@ -56,6 +56,7 @@ struct _DataSourceClass
GType data_source_get_type (void) G_GNUC_CONST;
DataSource *data_source_new_from_xml_node (BrowserConnection *bcnc, xmlNodePtr node, GError **error);
+void data_source_set_params (DataSource *source, GdaSet *params);
xmlNodePtr data_source_to_xml_node (DataSource *source);
GdaSet *data_source_get_import (DataSource *source);
diff --git a/tools/browser/data-manager/spec-editor.c b/tools/browser/data-manager/spec-editor.c
index dabc74b..9d7972c 100644
--- a/tools/browser/data-manager/spec-editor.c
+++ b/tools/browser/data-manager/spec-editor.c
@@ -26,6 +26,7 @@
#include "data-source.h"
#include <libgda/libgda.h>
#include "../support.h"
+#include "marshal.h"
#ifdef HAVE_GTKSOURCEVIEW
#ifdef GTK_DISABLE_SINGLE_INCLUDES
@@ -45,13 +46,14 @@ struct _SpecEditorPrivate {
SpecEditorMode mode;
GtkNotebook *notebook;
- guint params_compute_id; /* timout ID to compute params */
+ GdaSet *params; /* execution params */
/* reference for all views */
xmlDocPtr doc;
/* XML view */
gboolean xml_view_up_to_date;
+ guint signal_editor_changed_id; /* timout ID to signal editor changed */
GtkWidget *text;
GtkTextBuffer *buffer;
@@ -63,6 +65,12 @@ static void spec_editor_class_init (SpecEditorClass *klass);
static void spec_editor_init (SpecEditor *sped, SpecEditorClass *klass);
static void spec_editor_dispose (GObject *object);
+enum {
+ CHANGED,
+ LAST_SIGNAL
+};
+
+static guint spec_editor_signals[LAST_SIGNAL] = { 0 };
static GObjectClass *parent_class = NULL;
/*
@@ -75,6 +83,15 @@ spec_editor_class_init (SpecEditorClass *klass)
parent_class = g_type_class_peek_parent (klass);
+ /* signals */
+ spec_editor_signals [CHANGED] =
+ g_signal_new ("changed",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (SpecEditorClass, changed),
+ NULL, NULL,
+ _dm_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
object_class->dispose = spec_editor_dispose;
}
@@ -86,7 +103,7 @@ spec_editor_init (SpecEditor *sped, SpecEditorClass *klass)
/* allocate private structure */
sped->priv = g_new0 (SpecEditorPrivate, 1);
- sped->priv->params_compute_id = 0;
+ sped->priv->signal_editor_changed_id = 0;
sped->priv->mode = SPEC_EDITOR_XML;
}
@@ -117,9 +134,10 @@ spec_editor_dispose (GObject *object)
{
SpecEditor *sped = (SpecEditor*) object;
if (sped->priv) {
- if (sped->priv->params_compute_id)
- g_source_remove (sped->priv->params_compute_id);
-
+ if (sped->priv->signal_editor_changed_id)
+ g_source_remove (sped->priv->signal_editor_changed_id);
+ if (sped->priv->params)
+ g_object_unref (sped->priv->params);
if (sped->priv->bcnc)
g_object_unref (sped->priv->bcnc);
@@ -132,12 +150,13 @@ spec_editor_dispose (GObject *object)
}
static gboolean
-compute_params (SpecEditor *sped)
+signal_editor_changed (SpecEditor *sped)
{
- TO_IMPLEMENT;
-
+ /* send signal */
+ g_signal_emit (sped, spec_editor_signals[CHANGED], 0);
+
/* remove timeout */
- sped->priv->params_compute_id = 0;
+ sped->priv->signal_editor_changed_id = 0;
return FALSE;
}
@@ -145,9 +164,9 @@ compute_params (SpecEditor *sped)
static void
editor_changed_cb (GtkTextBuffer *buffer, SpecEditor *sped)
{
- if (sped->priv->params_compute_id)
- g_source_remove (sped->priv->params_compute_id);
- sped->priv->params_compute_id = g_timeout_add_seconds (1, (GSourceFunc) compute_params, sped);
+ if (sped->priv->signal_editor_changed_id)
+ g_source_remove (sped->priv->signal_editor_changed_id);
+ sped->priv->signal_editor_changed_id = g_timeout_add_seconds (1, (GSourceFunc) signal_editor_changed, sped);
}
/**
@@ -216,8 +235,12 @@ spec_editor_set_xml_text (SpecEditor *sped, const gchar *xml)
g_return_if_fail (IS_SPEC_EDITOR (sped));
gtk_text_buffer_set_text (sped->priv->buffer, xml, -1);
+ signal_editor_changed (sped);
}
+/**
+ * spec_editor_get_xml_text
+ */
gchar *
spec_editor_get_xml_text (SpecEditor *sped)
{
@@ -260,7 +283,78 @@ spec_editor_get_mode (SpecEditor *sped)
}
static GArray *compute_sources (SpecEditor *sped, GError **error);
+static GSList *compute_sources_list (SpecEditor *sped, GError **error);
+
+static void
+compute_params (SpecEditor *sped)
+{
+ /* cleanning process */
+ if (sped->priv->params) {
+ browser_connection_keep_variables (sped->priv->bcnc, sped->priv->params);
+ g_object_unref (sped->priv->params);
+ }
+ sped->priv->params = NULL;
+
+ /* compute new params */
+ GSList *sources_list;
+ sources_list = compute_sources_list (sped, NULL);
+ if (sources_list) {
+ GSList *list;
+ for (list = sources_list; list; list = list->next) {
+ DataSource *source;
+ GdaSet *set;
+
+ source = DATA_SOURCE (list->data);
+ set = data_source_get_import (source);
+ if (!set)
+ continue;
+
+ GSList *holders;
+ gboolean found;
+ for (found = FALSE, holders = set->holders; holders; holders = holders->next) {
+ GSList *list2;
+ for (list2 = sources_list; list2; list2 = list2->next) {
+ if (list2 == list)
+ continue;
+ GHashTable *export_h;
+ export_h = data_source_get_export_columns (DATA_SOURCE (list2->data));
+ if (g_hash_table_lookup (export_h,
+ gda_holder_get_id (GDA_HOLDER (holders->data)))) {
+ found = TRUE;
+ break;
+ }
+ }
+ }
+ if (! found) {
+ if (! sped->priv->params)
+ sped->priv->params = gda_set_copy (set);
+ else
+ gda_set_merge_with_set (sped->priv->params, set);
+ }
+ }
+
+ /* cleanups */
+ g_slist_foreach (sources_list, (GFunc) g_object_unref, NULL);
+ g_slist_free (sources_list);
+ sources_list = NULL;
+ }
+
+ browser_connection_load_variables (sped->priv->bcnc, sped->priv->params);
+}
+
+/**
+ * spec_editor_get_params
+ *
+ * Returns: a pointer to an internal #GdaSet, must not be modified
+ */
+GdaSet *
+spec_editor_get_params (SpecEditor *sped)
+{
+ g_return_val_if_fail (IS_SPEC_EDITOR (sped), NULL);
+ compute_params (sped);
+ return sped->priv->params;
+}
/**
* spec_editor_get_sources_array
@@ -269,10 +363,10 @@ GArray *
spec_editor_get_sources_array (SpecEditor *sped, GError **error)
{
g_return_val_if_fail (IS_SPEC_EDITOR (sped), NULL);
- if (sped->priv->params_compute_id > 0) {
- g_source_remove (sped->priv->params_compute_id);
- sped->priv->params_compute_id = 0;
- //compute_params (tconsole);
+ if (sped->priv->signal_editor_changed_id > 0) {
+ g_source_remove (sped->priv->signal_editor_changed_id);
+ sped->priv->signal_editor_changed_id = 0;
+ compute_params (sped);
}
return compute_sources (sped, error);
}
@@ -408,12 +502,11 @@ create_sources_array (GSList *sources_list, GError **error)
return array;
}
-static GArray *
-compute_sources (SpecEditor *sped, GError **error)
+static GSList *
+compute_sources_list (SpecEditor *sped, GError **error)
{
gchar *xml;
xmlDocPtr doc = NULL;
- GError *lerror = NULL;
GSList *sources_list = NULL;
/* create sources_list from XML */
@@ -427,7 +520,7 @@ compute_sources (SpecEditor *sped, GError **error)
}
if (!doc) {
- g_set_error (&lerror, 0, 0,
+ g_set_error (error, 0, 0,
_("Error parsing XML specifications"));
goto onerror;
}
@@ -444,42 +537,51 @@ compute_sources (SpecEditor *sped, GError **error)
if (!strcmp ((gchar*) node->name, "table") ||
!strcmp ((gchar*) node->name, "query")) {
DataSource *source;
- source = data_source_new_from_xml_node (sped->priv->bcnc, node, &lerror);
+ source = data_source_new_from_xml_node (sped->priv->bcnc, node, error);
if (!source)
goto onerror;
- else
- sources_list = g_slist_prepend (sources_list, source);
+
+ sources_list = g_slist_prepend (sources_list, source);
+ data_source_set_params (source, sped->priv->params);
}
}
xmlFreeDoc (doc);
doc = NULL;
- sources_list = g_slist_reverse (sources_list);
+ return g_slist_reverse (sources_list);
- /* reorder sources_list */
- GArray *sources_array;
- sources_array = create_sources_array (sources_list, &lerror);
+ onerror:
+ if (doc)
+ xmlFreeDoc (doc);
if (sources_list) {
g_slist_foreach (sources_list, (GFunc) g_object_unref, NULL);
g_slist_free (sources_list);
- sources_list = NULL;
}
- if (! sources_array)
- goto onerror;
+
+ return NULL;
+}
- return sources_array;
+static GArray *
+compute_sources (SpecEditor *sped, GError **error)
+{
+ GArray *sources_array = NULL;
+ GSList *sources_list;
+ GError *lerror = NULL;
+
+ sources_list = compute_sources_list (sped, &lerror);
+ if (!lerror)
+ sources_array = create_sources_array (sources_list, &lerror);
- onerror:
- if (doc)
- xmlFreeDoc (doc);
if (sources_list) {
g_slist_foreach (sources_list, (GFunc) g_object_unref, NULL);
g_slist_free (sources_list);
+ sources_list = NULL;
}
+
if (lerror) {
browser_show_error ((GtkWindow*) gtk_widget_get_toplevel ((GtkWidget*) sped),
lerror && lerror->message ? lerror->message :_("Error parsing XML specifications"));
g_clear_error (&lerror);
}
-
- return NULL;
+
+ return sources_array;
}
diff --git a/tools/browser/data-manager/spec-editor.h b/tools/browser/data-manager/spec-editor.h
index 624975b..40485e9 100644
--- a/tools/browser/data-manager/spec-editor.h
+++ b/tools/browser/data-manager/spec-editor.h
@@ -46,6 +46,9 @@ struct _SpecEditor {
struct _SpecEditorClass {
GtkVBoxClass parent_class;
+
+ /* signals */
+ void (*changed) (SpecEditor *editor);
};
typedef enum {
@@ -62,6 +65,7 @@ gchar *spec_editor_get_xml_text (SpecEditor *sped);
void spec_editor_set_mode (SpecEditor *sped, SpecEditorMode mode);
SpecEditorMode spec_editor_get_mode (SpecEditor *sped);
+GdaSet *spec_editor_get_params (SpecEditor *sped);
GArray *spec_editor_get_sources_array (SpecEditor *sped, GError **error);
void spec_editor_destroy_sources_array (GArray *array);
diff --git a/tools/browser/doc/gda-browser-sections.txt b/tools/browser/doc/gda-browser-sections.txt
index 1424209..4cb6751 100644
--- a/tools/browser/doc/gda-browser-sections.txt
+++ b/tools/browser/doc/gda-browser-sections.txt
@@ -92,6 +92,9 @@ browser_connection_get_transaction_status
<SUBSECTION>
browser_connection_set_table_column_attribute
browser_connection_get_table_column_attribute
+<SUBSECTION>
+browser_connection_keep_variables
+browser_connection_load_variables
<SUBSECTION Standard>
BROWSER_CONNECTION
BROWSER_IS_CONNECTION
diff --git a/tools/browser/doc/tmpl/browser-connection.sgml b/tools/browser/doc/tmpl/browser-connection.sgml
index 1c12eea..781266a 100644
--- a/tools/browser/doc/tmpl/browser-connection.sgml
+++ b/tools/browser/doc/tmpl/browser-connection.sgml
@@ -31,7 +31,6 @@ An opened connection
@cnc:
@dict_file_name:
@parser:
- variables:
@dsn_info:
@p_mstruct_mutex:
@p_mstruct:
@@ -40,6 +39,7 @@ An opened connection
@busy:
@busy_reason:
@store_cnc:
+ variables:
<!-- ##### STRUCT BrowserConnection ##### -->
<para>
@@ -309,3 +309,21 @@ An opened connection
@Returns:
+<!-- ##### FUNCTION browser_connection_keep_variables ##### -->
+<para>
+
+</para>
+
+ bcnc:
+ set:
+
+
+<!-- ##### FUNCTION browser_connection_load_variables ##### -->
+<para>
+
+</para>
+
+ bcnc:
+ set:
+
+
diff --git a/tools/browser/query-exec/query-console.c b/tools/browser/query-exec/query-console.c
index 91e774e..7ad14c7 100644
--- a/tools/browser/query-exec/query-console.c
+++ b/tools/browser/query-exec/query-console.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The GNOME Foundation
+ * Copyright (C) 2009 - 2010 The GNOME Foundation
*
* AUTHORS:
* Vivien Malerba <malerba gnome-db org>
@@ -106,7 +106,6 @@ struct _QueryConsolePrivate {
GtkWidget *exec_button;
GtkWidget *indent_button;
guint params_compute_id; /* timout ID to compute params */
- GdaSet *past_params; /* keeps values given to old params */
GdaSet *params; /* execution params */
GtkWidget *params_popup; /* popup shown when invalid params are required */
@@ -186,7 +185,6 @@ query_console_init (QueryConsole *tconsole, QueryConsoleClass *klass)
tconsole->priv = g_new0 (QueryConsolePrivate, 1);
tconsole->priv->parser = NULL;
tconsole->priv->params_compute_id = 0;
- tconsole->priv->past_params = NULL;
tconsole->priv->params = NULL;
tconsole->priv->params_popup = NULL;
tconsole->priv->agroup = NULL;
@@ -211,8 +209,6 @@ query_console_dispose (GObject *object)
}
if (tconsole->priv->parser)
g_object_unref (tconsole->priv->parser);
- if (tconsole->priv->past_params)
- g_object_unref (tconsole->priv->past_params);
if (tconsole->priv->params)
g_object_unref (tconsole->priv->params);
if (tconsole->priv->params_compute_id)
@@ -544,16 +540,11 @@ compute_params (QueryConsole *tconsole)
GdaBatch *batch;
if (tconsole->priv->params) {
- if (tconsole->priv->past_params) {
- gda_set_merge_with_set (tconsole->priv->params, tconsole->priv->past_params);
- g_object_unref (tconsole->priv->past_params);
- tconsole->priv->past_params = tconsole->priv->params;
- }
- else
- tconsole->priv->past_params = tconsole->priv->params;
+ browser_connection_keep_variables (tconsole->priv->bcnc, tconsole->priv->params);
+ g_object_unref (tconsole->priv->params);
}
-
tconsole->priv->params = NULL;
+
if (tconsole->priv->params_form) {
gtk_widget_destroy (tconsole->priv->params_form);
tconsole->priv->params_form = NULL;
@@ -590,35 +581,7 @@ compute_params (QueryConsole *tconsole)
gtk_widget_show (tconsole->priv->params_form);
g_object_unref (batch);
- if (tconsole->priv->past_params && tconsole->priv->params) {
- /* copy the values from tconsole->priv->past_params to tconsole->priv->params */
- GSList *list;
- for (list = tconsole->priv->params->holders; list; list = list->next) {
- GdaHolder *oldh, *newh;
- newh = GDA_HOLDER (list->data);
- oldh = gda_set_get_holder (tconsole->priv->past_params, gda_holder_get_id (newh));
- if (oldh) {
- GType otype, ntype;
- otype = gda_holder_get_g_type (oldh);
- ntype = gda_holder_get_g_type (newh);
- if (otype == ntype) {
- const GValue *ovalue;
- ovalue = gda_holder_get_value (oldh);
- gda_holder_set_value (newh, ovalue, NULL);
- }
- else if (g_value_type_transformable (otype, ntype)) {
- const GValue *ovalue;
- GValue *nvalue;
- ovalue = gda_holder_get_value (oldh);
- nvalue = gda_value_new (ntype);
- if (g_value_transform (ovalue, nvalue))
- gda_holder_take_value (newh, nvalue, NULL);
- else
- gda_value_free (nvalue);
- }
- }
- }
- }
+ browser_connection_load_variables (tconsole->priv->bcnc, tconsole->priv->params);
if (tconsole->priv->params && show_variables &&
gda_set_is_valid (tconsole->priv->params, NULL))
show_variables = FALSE;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]