[libgda] Initial creation of DataSourceManager object
- From: Vivien Malerba <vivien src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgda] Initial creation of DataSourceManager object
- Date: Wed, 14 Jul 2010 15:13:13 +0000 (UTC)
commit cbfe042e86a8265582683908062c70c63fbdb658
Author: Vivien Malerba <malerba gnome-db org>
Date: Wed Jul 14 14:01:26 2010 +0200
Initial creation of DataSourceManager object
tools/browser/data-manager/Makefile.am | 4 +-
tools/browser/data-manager/data-console.c | 25 +-
tools/browser/data-manager/data-source-manager.c | 458 ++++++++++++++++++++++
tools/browser/data-manager/data-source-manager.h | 70 ++++
tools/browser/data-manager/spec-editor.c | 408 +++----------------
tools/browser/data-manager/spec-editor.h | 10 +-
6 files changed, 614 insertions(+), 361 deletions(-)
---
diff --git a/tools/browser/data-manager/Makefile.am b/tools/browser/data-manager/Makefile.am
index 054eb53..208ed9c 100644
--- a/tools/browser/data-manager/Makefile.am
+++ b/tools/browser/data-manager/Makefile.am
@@ -31,7 +31,9 @@ libperspective_la_SOURCES = \
spec-editor.c \
spec-editor.h \
data-manager-perspective.h \
- data-manager-perspective.c
+ data-manager-perspective.c \
+ data-source-manager.h \
+ data-source-manager.c
$(OBJECTS): marshal.c marshal.h
diff --git a/tools/browser/data-manager/data-console.c b/tools/browser/data-manager/data-console.c
index 78d1984..19b42a0 100644
--- a/tools/browser/data-manager/data-console.c
+++ b/tools/browser/data-manager/data-console.c
@@ -34,6 +34,7 @@
#include "../common/popup-container.h"
#include <libgda/sql-parser/gda-sql-parser.h>
#include <libgda-ui/libgda-ui.h>
+#include "data-source-manager.h"
#define PAGE_XML 0
#define PAGE_DATA 1
@@ -44,6 +45,8 @@ typedef enum {
} LayoutType;
struct _DataConsolePrivate {
+ DataSourceManager *mgr;
+
LayoutType layout_type;
BrowserConnection *bcnc;
GtkWidget *notebook;
@@ -129,6 +132,8 @@ 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)
+ g_object_unref (dconsole->priv->mgr);
g_free (dconsole->priv);
dconsole->priv = NULL;
}
@@ -173,7 +178,7 @@ 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 spec_editor_changed_cb (SpecEditor *sped, DataConsole *dconsole);
+static void data_source_mgr_changed_cb (DataSourceManager *mgr, DataConsole *dconsole);
/**
* data_console_new
@@ -190,6 +195,9 @@ data_console_new (BrowserConnection *bcnc)
dconsole = DATA_CONSOLE (g_object_new (DATA_CONSOLE_TYPE, NULL));
dconsole->priv->bcnc = g_object_ref (bcnc);
+ dconsole->priv->mgr = data_source_manager_new (bcnc);
+ g_signal_connect (dconsole->priv->mgr, "changed",
+ G_CALLBACK (data_source_mgr_changed_cb), dconsole);
/* header */
GtkWidget *label;
@@ -255,9 +263,7 @@ data_console_new (BrowserConnection *bcnc)
hbox = gtk_hbox_new (FALSE, 0);
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);
+ dconsole->priv->sped = spec_editor_new (dconsole->priv->mgr);
gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET (dconsole->priv->sped), TRUE, TRUE, 0);
#define DEFAULT_XML \
@@ -359,7 +365,8 @@ execute_clicked_cb (GtkButton *button, DataConsole *dconsole)
static void
help_clicked_cb (GtkButton *button, DataConsole *dconsole)
{
- browser_show_help ((GtkWindow*) gtk_widget_get_toplevel (dconsole), "data-manager-perspective");
+ browser_show_help ((GtkWindow*) gtk_widget_get_toplevel ((GtkWidget*) dconsole),
+ "data-manager-perspective");
}
#endif
@@ -382,7 +389,7 @@ spec_editor_toggled_cb (GtkToggleButton *button, DataConsole *dconsole)
}
static void
-spec_editor_changed_cb (SpecEditor *sped, DataConsole *dconsole)
+data_source_mgr_changed_cb (DataSourceManager *mgr, DataConsole *dconsole)
{
if (dconsole->priv->params_form) {
gtk_widget_destroy (dconsole->priv->params_form);
@@ -391,7 +398,7 @@ spec_editor_changed_cb (SpecEditor *sped, DataConsole *dconsole)
GdaSet *params;
gboolean show_variables = FALSE;
- params = spec_editor_get_params (sped);
+ params = data_source_manager_get_params (mgr);
if (params) {
dconsole->priv->params_form = gdaui_basic_form_new (params);
g_object_set ((GObject*) dconsole->priv->params_form,
@@ -462,7 +469,7 @@ compose_mode_toggled_cb (GtkToggleAction *action, DataConsole *dconsole)
/* Get Data sources */
GArray *sources_array;
GError *lerror = NULL;
- sources_array = spec_editor_get_sources_array (dconsole->priv->sped, &lerror);
+ sources_array = data_source_manager_get_sources_array (dconsole->priv->mgr, &lerror);
if (sources_array) {
if (dconsole->priv->data) {
/* destroy existing data widgets */
@@ -472,7 +479,7 @@ compose_mode_toggled_cb (GtkToggleAction *action, DataConsole *dconsole)
GtkWidget *wid;
wid = create_widget (dconsole, sources_array, &lerror);
- spec_editor_destroy_sources_array (sources_array);
+ data_source_manager_destroy_sources_array (sources_array);
if (wid) {
dconsole->priv->data = wid;
gtk_box_pack_start (GTK_BOX (dconsole->priv->data_box), wid, TRUE, TRUE, 0);
diff --git a/tools/browser/data-manager/data-source-manager.c b/tools/browser/data-manager/data-source-manager.c
new file mode 100644
index 0000000..18be2e7
--- /dev/null
+++ b/tools/browser/data-manager/data-source-manager.c
@@ -0,0 +1,458 @@
+/*
+ * Copyright (C) 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
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+#include <glib/gi18n-lib.h>
+#include "browser-connection.h"
+#include <libgda/thread-wrapper/gda-thread-wrapper.h>
+#include "support.h"
+#include "marshal.h"
+#include <sql-parser/gda-sql-parser.h>
+#include <libgda/gda-data-model-extra.h>
+#include <libgda/gda-sql-builder.h>
+
+#include "data-source-manager.h"
+
+
+/* signals */
+enum {
+ CHANGED,
+ LAST_SIGNAL
+};
+
+gint data_source_manager_signals [LAST_SIGNAL] = { 0 };
+
+/*
+ * Main static functions
+ */
+static void data_source_manager_class_init (DataSourceManagerClass *klass);
+static void data_source_manager_init (DataSourceManager *mgr);
+static void data_source_manager_dispose (GObject *object);
+
+/* get a pointer to the parents to be able to call their destructor */
+static GObjectClass *parent_class = NULL;
+
+struct _DataSourceManagerPrivate {
+ BrowserConnection *bcnc;
+ GSList *sources_list;
+ GdaSet *params; /* execution params */
+};
+
+GType
+data_source_manager_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static GStaticMutex registering = G_STATIC_MUTEX_INIT;
+ static const GTypeInfo info = {
+ sizeof (DataSourceManagerClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) data_source_manager_class_init,
+ NULL,
+ NULL,
+ sizeof (DataSourceManager),
+ 0,
+ (GInstanceInitFunc) data_source_manager_init
+ };
+
+
+ g_static_mutex_lock (®istering);
+ if (type == 0)
+ type = g_type_register_static (G_TYPE_OBJECT, "DataSourceManager", &info, 0);
+ g_static_mutex_unlock (®istering);
+ }
+ return type;
+}
+
+static void
+data_source_manager_class_init (DataSourceManagerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ parent_class = g_type_class_peek_parent (klass);
+
+ /* signals */
+ data_source_manager_signals [CHANGED] =
+ g_signal_new ("changed",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (DataSourceManagerClass, changed),
+ NULL, NULL,
+ _dm_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
+ object_class->dispose = data_source_manager_dispose;
+}
+
+static void
+data_source_manager_init (DataSourceManager *mgr)
+{
+ mgr->priv = g_new0 (DataSourceManagerPrivate, 1);
+}
+
+static void
+data_source_manager_dispose (GObject *object)
+{
+ DataSourceManager *mgr;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (IS_DATA_SOURCE_MANAGER (object));
+
+ mgr = DATA_SOURCE_MANAGER (object);
+ if (mgr->priv) {
+ if (mgr->priv->params)
+ g_object_unref (mgr->priv->params);
+
+ if (mgr->priv->sources_list) {
+ g_slist_foreach (mgr->priv->sources_list, (GFunc) g_object_unref, NULL);
+ g_slist_free (mgr->priv->sources_list);
+ mgr->priv->sources_list = NULL;
+ }
+
+ if (mgr->priv->bcnc)
+ g_object_unref (mgr->priv->bcnc);
+
+ g_free (mgr->priv);
+ mgr->priv = NULL;
+ }
+
+ /* parent class */
+ parent_class->dispose (object);
+}
+
+/**
+ * data_source_manager_new
+ * @bcnc:
+ *
+ * Creates a new #DataSourceManager object
+ *
+ * Returns: a new object
+ */
+DataSourceManager*
+data_source_manager_new (BrowserConnection *bcnc)
+{
+ DataSourceManager *mgr;
+ g_return_val_if_fail (BROWSER_IS_CONNECTION (bcnc), NULL);
+
+ mgr = DATA_SOURCE_MANAGER (g_object_new (DATA_SOURCE_MANAGER_TYPE, NULL));
+ mgr->priv->bcnc = g_object_ref (bcnc);
+
+ return mgr;
+}
+
+/*
+ * Tells if @source1 has an import which can be satisfied by an export in @source2
+ * Returns: %TRUE if there is a dependency
+ */
+static gboolean
+source_depends_on (DataSource *source1, DataSource *source2)
+{
+ GdaSet *import;
+ import = data_source_get_import (source1);
+ if (!import) {
+ g_print ("[%s] has no import\n",
+ data_source_get_title (source1));
+ return FALSE;
+ }
+
+ GSList *holders;
+ GHashTable *export_columns;
+ export_columns = data_source_get_export_columns (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) {
+ g_print ("[%s] ====> [%s]\n",
+ data_source_get_title (source1),
+ data_source_get_title (source2));
+ return TRUE;
+ }
+ }
+ g_print ("[%s] ..... [%s]\n",
+ data_source_get_title (source1),
+ data_source_get_title (source2));
+ return FALSE;
+}
+
+
+static gint
+data_source_compare_func (DataSource *s1, DataSource *s2)
+{
+ if (source_depends_on (s1, s2))
+ return 1;
+ else if (source_depends_on (s2, s1))
+ return -1;
+ else
+ return 0;
+}
+
+/**
+ * data_source_manager_add_source
+ * @mgr:
+ * @source:
+ */
+void
+data_source_manager_add_source (DataSourceManager *mgr, DataSource *source)
+{
+ g_return_if_fail (IS_DATA_SOURCE_MANAGER (mgr));
+ 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);
+ g_signal_emit (mgr, data_source_manager_signals[CHANGED], 0);
+
+ GSList *list;
+ gint i;
+ for (i = 0, list = mgr->priv->sources_list; list; list = list->next, i++) {
+ DataSource *source = DATA_SOURCE (list->data);
+ g_print ("\t %d ... %s\n", i,
+ data_source_get_title (source));
+ }
+}
+
+/**
+ * data_source_manager_remove_all
+ * @mgr:
+ */
+void
+data_source_manager_remove_all (DataSourceManager *mgr)
+{
+ g_return_if_fail (IS_DATA_SOURCE_MANAGER (mgr));
+
+ if (mgr->priv->sources_list) {
+ GSList *list;
+ list = mgr->priv->sources_list;
+ mgr->priv->sources_list = NULL;
+ g_signal_emit (mgr, data_source_manager_signals[CHANGED], 0);
+
+ g_slist_foreach (list, (GFunc) g_object_unref, NULL);
+ g_slist_free (list);
+ }
+}
+
+/**
+ * data_source_manager_remove_source
+ * @mgr:
+ * @source:
+ */
+void
+data_source_manager_remove_source (DataSourceManager *mgr, DataSource *source)
+{
+ g_return_if_fail (IS_DATA_SOURCE_MANAGER (mgr));
+ 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_remove (mgr->priv->sources_list, source);
+ g_signal_emit (mgr, data_source_manager_signals[CHANGED], 0);
+ g_object_unref (source);
+}
+
+
+static void
+compute_params (DataSourceManager *mgr)
+{
+ /* cleanning process */
+ if (mgr->priv->params) {
+ browser_connection_keep_variables (mgr->priv->bcnc, mgr->priv->params);
+ g_object_unref (mgr->priv->params);
+ }
+ mgr->priv->params = NULL;
+
+ /* compute new params */
+ if (mgr->priv->sources_list) {
+ GSList *list;
+ for (list = mgr->priv->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 = mgr->priv->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 (! mgr->priv->params)
+ mgr->priv->params = gda_set_copy (set);
+ else
+ gda_set_merge_with_set (mgr->priv->params, set);
+ }
+ }
+ }
+
+ browser_connection_load_variables (mgr->priv->bcnc, mgr->priv->params);
+}
+
+
+/**
+ * data_source_manager_get_params
+ * @mgr:
+ *
+ * Returns: a pointer to an internal #GdaSet, must not be modified
+ */
+GdaSet *
+data_source_manager_get_params (DataSourceManager *mgr)
+{
+ g_return_val_if_fail (IS_DATA_SOURCE_MANAGER (mgr), NULL);
+
+ compute_params (mgr);
+ return mgr->priv->params;
+}
+
+
+/**
+ * data_source_manager_get_sources_array
+ * @mgr:
+ *
+ * No ref is actually held by any of these pointers, all refs to DataSource are held by
+ * the @sources_list pointers
+ *
+ * Returns: an array of arrays of pointer to the #DataSource objects
+ */
+GArray *
+data_source_manager_get_sources_array (DataSourceManager *mgr, GError **error)
+{
+ g_return_val_if_fail (IS_DATA_SOURCE_MANAGER (mgr), NULL);
+
+ GSList *list;
+ GArray *array = NULL;
+ g_print ("** Creating DataSource arrays\n");
+ for (list = mgr->priv->sources_list; list; list = list->next) {
+ DataSource *source;
+ source = DATA_SOURCE (g_object_ref (G_OBJECT (list->data)));
+ g_print ("Taking into account source [%s]\n",
+ data_source_get_title (source));
+
+ GdaSet *import;
+ import = data_source_get_import (source);
+ if (!import) {
+ if (! array) {
+ array = g_array_new (FALSE, FALSE, sizeof (GArray*));
+ GArray *subarray = g_array_new (FALSE, FALSE, sizeof (DataSource*));
+ g_array_append_val (array, subarray);
+ g_array_append_val (subarray, source);
+ }
+ else {
+ GArray *subarray = g_array_index (array, GArray*, 0);
+ g_array_append_val (subarray, source);
+ }
+ continue;
+ }
+
+ if (array) {
+ gint i;
+ gboolean dep_found = FALSE;
+ for (i = array->len - 1; i >= 0 ; i--) {
+ GArray *subarray = g_array_index (array, GArray*, i);
+ 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 */
+ if (i == array->len - 1) {
+ GArray *subarray = g_array_new (FALSE, FALSE,
+ sizeof (DataSource*));
+ g_array_append_val (array, subarray);
+ g_array_append_val (subarray, source);
+ }
+ else {
+ GArray *subarray = g_array_index (array, GArray*, i+1);
+ g_array_append_val (subarray, source);
+ }
+ continue;
+ }
+ }
+
+ if (dep_found)
+ break;
+ }
+ if (! dep_found) {
+ /* add source to column 0 */
+ GArray *subarray = g_array_index (array, GArray*, 0);
+ g_array_append_val (subarray, source);
+ }
+ }
+ else {
+ /* add source to column 0 */
+ array = g_array_new (FALSE, FALSE, sizeof (GArray*));
+ GArray *subarray = g_array_new (FALSE, FALSE, sizeof (DataSource*));
+ g_array_append_val (array, subarray);
+ g_array_append_val (subarray, source);
+ }
+ }
+
+ g_print ("** DataSource arrays created\n");
+ return array;
+}
+
+/**
+ * data_source_manager_destroy_sources_array
+ */
+void
+data_source_manager_destroy_sources_array (GArray *array)
+{
+ gint i;
+ g_return_if_fail (array);
+ for (i = 0; i < array->len; i++) {
+ GArray *subarray;
+ subarray = g_array_index (array, GArray *, i);
+ gint j;
+ for (j = 0; j < subarray->len; j++) {
+ DataSource *source;
+ source = g_array_index (subarray, DataSource *, j);
+ g_object_unref (source);
+ }
+
+ g_array_free (subarray, TRUE);
+ }
+ g_array_free (array, TRUE);
+}
+
+/**
+ * data_source_manager_get_browser_cnc
+ * @mgr:
+ */
+BrowserConnection *
+data_source_manager_get_browser_cnc (DataSourceManager *mgr)
+{
+ g_return_val_if_fail (IS_DATA_SOURCE_MANAGER (mgr), NULL);
+ return mgr->priv->bcnc;
+}
diff --git a/tools/browser/data-manager/data-source-manager.h b/tools/browser/data-manager/data-source-manager.h
new file mode 100644
index 0000000..c5d320c
--- /dev/null
+++ b/tools/browser/data-manager/data-source-manager.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 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
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef __DATA_SOURCE_MANAGER_H_
+#define __DATA_SOURCE_MANAGER_H_
+
+#include "../browser-connection.h"
+#include "data-source.h"
+
+G_BEGIN_DECLS
+
+#define DATA_SOURCE_MANAGER_TYPE (data_source_manager_get_type())
+#define DATA_SOURCE_MANAGER(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, data_source_manager_get_type(), DataSourceManager)
+#define DATA_SOURCE_MANAGER_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, data_source_manager_get_type (), DataSourceManagerClass)
+#define IS_DATA_SOURCE_MANAGER(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, data_source_manager_get_type ())
+
+typedef struct _DataSourceManager DataSourceManager;
+typedef struct _DataSourceManagerClass DataSourceManagerClass;
+typedef struct _DataSourceManagerPrivate DataSourceManagerPrivate;
+
+/* struct for the object's data */
+struct _DataSourceManager
+{
+ GObject object;
+ DataSourceManagerPrivate *priv;
+};
+
+/* struct for the object's class */
+struct _DataSourceManagerClass
+{
+ GObjectClass parent_class;
+
+ /* signals */
+ void (*changed) (DataSourceManager *mgr);
+};
+
+GType data_source_manager_get_type (void) G_GNUC_CONST;
+
+DataSourceManager *data_source_manager_new (BrowserConnection *bcnc);
+void data_source_manager_add_source (DataSourceManager *mgr, DataSource *source);
+void data_source_manager_remove_source (DataSourceManager *mgr, DataSource *source);
+void data_source_manager_remove_all (DataSourceManager *mgr);
+
+GdaSet *data_source_manager_get_params (DataSourceManager *mgr);
+BrowserConnection *data_source_manager_get_browser_cnc (DataSourceManager *mgr);
+
+GArray *data_source_manager_get_sources_array (DataSourceManager *mgr, GError **error);
+void data_source_manager_destroy_sources_array (GArray *array);
+
+
+G_END_DECLS
+
+#endif
diff --git a/tools/browser/data-manager/spec-editor.c b/tools/browser/data-manager/spec-editor.c
index 1532287..d5192c6 100644
--- a/tools/browser/data-manager/spec-editor.c
+++ b/tools/browser/data-manager/spec-editor.c
@@ -26,7 +26,6 @@
#include "data-source.h"
#include <libgda/libgda.h>
#include "../support.h"
-#include "marshal.h"
#ifdef HAVE_GTKSOURCEVIEW
#ifdef GTK_DISABLE_SINGLE_INCLUDES
@@ -41,13 +40,11 @@
#endif
struct _SpecEditorPrivate {
- BrowserConnection *bcnc;
+ DataSourceManager *mgr;
SpecEditorMode mode;
GtkNotebook *notebook;
- GdaSet *params; /* execution params */
-
/* reference for all views */
xmlDocPtr doc;
@@ -66,12 +63,6 @@ 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;
/*
@@ -84,15 +75,6 @@ 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;
}
@@ -137,10 +119,8 @@ spec_editor_dispose (GObject *object)
if (sped->priv) {
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);
+ if (sped->priv->mgr)
+ g_object_unref (sped->priv->mgr);
if (sped->priv->doc)
xmlFreeDoc (sped->priv->doc);
@@ -153,9 +133,65 @@ spec_editor_dispose (GObject *object)
static gboolean
signal_editor_changed (SpecEditor *sped)
{
- /* send signal */
- g_signal_emit (sped, spec_editor_signals[CHANGED], 0);
+ /* modify the DataSourceManager */
+ data_source_manager_remove_all (sped->priv->mgr);
+
+ /* create new DataSource objects */
+ GError *lerror = NULL;
+ gchar *xml;
+ xmlDocPtr doc = NULL;
+ GtkTextIter start, end;
+ gtk_text_buffer_get_start_iter (sped->priv->buffer, &start);
+ gtk_text_buffer_get_end_iter (sped->priv->buffer, &end);
+ xml = gtk_text_buffer_get_text (sped->priv->buffer, &start, &end, FALSE);
+ if (xml) {
+ doc = xmlParseDoc (BAD_CAST xml);
+ g_free (xml);
+ }
+
+ if (!doc) {
+ TO_IMPLEMENT;
+ g_set_error (&lerror, 0, 0,
+ _("Error parsing XML specifications"));
+ goto out;
+ }
+
+ xmlNodePtr node;
+ node = xmlDocGetRootElement (doc);
+ if (!node) {
+ /* nothing to do => finished */
+ xmlFreeDoc (doc);
+ goto out;
+ }
+
+ BrowserConnection *bcnc;
+ GdaSet *params;
+
+ params = data_source_manager_get_params (sped->priv->mgr);
+ bcnc = data_source_manager_get_browser_cnc (sped->priv->mgr);
+ for (node = node->children; node; node = node->next) {
+ if (!strcmp ((gchar*) node->name, "table") ||
+ !strcmp ((gchar*) node->name, "query")) {
+ DataSource *source;
+ source = data_source_new_from_xml_node (bcnc, node, &lerror);
+ if (!source) {
+ data_source_manager_remove_all (sped->priv->mgr);
+ TO_IMPLEMENT;
+ goto out;
+ }
+
+ data_source_set_params (source, params);
+ data_source_manager_add_source (sped->priv->mgr, source);
+ g_object_unref (source);
+ }
+ }
+ xmlFreeDoc (doc);
+ out:
+ if (lerror) {
+ TO_IMPLEMENT;
+ g_clear_error (&lerror);
+ }
/* remove timeout */
sped->priv->signal_editor_changed_id = 0;
return FALSE;
@@ -175,15 +211,15 @@ editor_changed_cb (GtkTextBuffer *buffer, SpecEditor *sped)
* Returns: the newly created editor.
*/
SpecEditor *
-spec_editor_new (BrowserConnection *bcnc)
+spec_editor_new (DataSourceManager *mgr)
{
SpecEditor *sped;
- GtkWidget *sw, *nb, *exp, *vbox;
+ GtkWidget *sw, *nb, *vbox;
- g_return_val_if_fail (BROWSER_IS_CONNECTION (bcnc), NULL);
+ g_return_val_if_fail (IS_DATA_SOURCE_MANAGER (mgr), NULL);
sped = g_object_new (SPEC_EDITOR_TYPE, NULL);
- sped->priv->bcnc = g_object_ref (bcnc);
+ sped->priv->mgr = g_object_ref (mgr);
nb = gtk_notebook_new ();
gtk_box_pack_start (GTK_BOX (sped), nb, TRUE, TRUE, 0);
@@ -285,317 +321,3 @@ spec_editor_get_mode (SpecEditor *sped)
return sped->priv->mode;
}
-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
- */
-GArray *
-spec_editor_get_sources_array (SpecEditor *sped, GError **error)
-{
- g_return_val_if_fail (IS_SPEC_EDITOR (sped), NULL);
- 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);
-}
-
-/**
- * spec_editor_destroy_sources_array
- */
-void
-spec_editor_destroy_sources_array (GArray *array)
-{
- gint i;
- for (i = 0; i < array->len; i++) {
- GArray *subarray;
- subarray = g_array_index (array, GArray *, i);
- gint j;
- for (j = 0; j < subarray->len; j++) {
- DataSource *source;
- source = g_array_index (subarray, DataSource *, j);
- g_object_unref (source);
- }
-
- g_array_free (subarray, TRUE);
- }
- g_array_free (array, TRUE);
-}
-
-/*
- * Tells if @source1 has an import which can be satisfied by an export in @source2
- * Returns: %TRUE if there is a dependency
- */
-static gboolean
-source_depends_on (DataSource *source1, DataSource *source2)
-{
- GdaSet *import;
- import = data_source_get_import (source1);
- if (!import)
- return FALSE;
-
- GSList *holders;
- GHashTable *export_columns;
- export_columns = data_source_get_export_columns (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)
- return TRUE;
- }
- return FALSE;
-}
-
-/*
- * Returns: an array of arrays of pointer to the #DataSource objects
- *
- * No ref is actually held by any of these pointers, all refs to DataSource are held by
- * the @sources_list pointers
- */
-static GArray *
-create_sources_array (GSList *sources_list, GError **error)
-{
- GSList *list;
- GArray *array = NULL;
- g_print ("** Creating DataSource arrays\n");
- for (list = sources_list; list; list = list->next) {
- DataSource *source;
- source = DATA_SOURCE (g_object_ref (G_OBJECT (list->data)));
- g_print ("Taking into account source [%s]\n",
- data_source_get_title (source));
-
- GdaSet *import;
- import = data_source_get_import (source);
- if (!import) {
- if (! array) {
- array = g_array_new (FALSE, FALSE, sizeof (GArray*));
- GArray *subarray = g_array_new (FALSE, FALSE, sizeof (DataSource*));
- g_array_append_val (array, subarray);
- g_array_append_val (subarray, source);
- }
- else {
- GArray *subarray = g_array_index (array, GArray*, 0);
- g_array_append_val (subarray, source);
- }
- continue;
- }
-
- if (array) {
- gint i;
- gboolean dep_found = FALSE;
- for (i = array->len - 1; i >= 0 ; i--) {
- GArray *subarray = g_array_index (array, GArray*, i);
- 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 */
- if (i == array->len - 1) {
- GArray *subarray = g_array_new (FALSE, FALSE,
- sizeof (DataSource*));
- g_array_append_val (array, subarray);
- g_array_append_val (subarray, source);
- }
- else {
- GArray *subarray = g_array_index (array, GArray*, i+1);
- g_array_append_val (subarray, source);
- }
- continue;
- }
- }
-
- if (dep_found)
- break;
- }
- if (! dep_found) {
- /* add source to column 0 */
- GArray *subarray = g_array_index (array, GArray*, 0);
- g_array_append_val (subarray, source);
- }
- }
- else {
- /* add source to column 0 */
- array = g_array_new (FALSE, FALSE, sizeof (GArray*));
- GArray *subarray = g_array_new (FALSE, FALSE, sizeof (DataSource*));
- g_array_append_val (array, subarray);
- g_array_append_val (subarray, source);
- }
- }
-
- g_print ("** DataSource arrays created\n");
- return array;
-}
-
-static gint
-data_source_compare_func (DataSource *s1, DataSource *s2)
-{
- if (source_depends_on (s1, s2))
- return 1;
- else if (source_depends_on (s2, s1))
- return -1;
- else
- return 0;
-}
-
-static GSList *
-compute_sources_list (SpecEditor *sped, GError **error)
-{
- gchar *xml;
- xmlDocPtr doc = NULL;
- GSList *sources_list = NULL;
-
- /* create sources_list from XML */
- GtkTextIter start, end;
- gtk_text_buffer_get_start_iter (sped->priv->buffer, &start);
- gtk_text_buffer_get_end_iter (sped->priv->buffer, &end);
- xml = gtk_text_buffer_get_text (sped->priv->buffer, &start, &end, FALSE);
- if (xml) {
- doc = xmlParseDoc (BAD_CAST xml);
- g_free (xml);
- }
-
- if (!doc) {
- g_set_error (error, 0, 0,
- _("Error parsing XML specifications"));
- goto onerror;
- }
-
- xmlNodePtr node;
- node = xmlDocGetRootElement (doc);
- if (!node) {
- /* nothing to do => finished */
- xmlFreeDoc (doc);
- return NULL;
- }
-
- for (node = node->children; node; node = node->next) {
- if (!strcmp ((gchar*) node->name, "table") ||
- !strcmp ((gchar*) node->name, "query")) {
- DataSource *source;
- source = data_source_new_from_xml_node (sped->priv->bcnc, node, error);
- if (!source)
- goto onerror;
-
- sources_list = g_slist_prepend (sources_list, source);
- data_source_set_params (source, sped->priv->params);
- }
- }
- xmlFreeDoc (doc);
- doc = NULL;
- return g_slist_sort (sources_list, (GCompareFunc) data_source_compare_func);
-
- onerror:
- if (doc)
- xmlFreeDoc (doc);
- if (sources_list) {
- g_slist_foreach (sources_list, (GFunc) g_object_unref, NULL);
- g_slist_free (sources_list);
- }
-
- return NULL;
-}
-
-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);
-
- 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 sources_array;
-}
diff --git a/tools/browser/data-manager/spec-editor.h b/tools/browser/data-manager/spec-editor.h
index 40485e9..da4fa8f 100644
--- a/tools/browser/data-manager/spec-editor.h
+++ b/tools/browser/data-manager/spec-editor.h
@@ -25,6 +25,7 @@
#include <gtk/gtk.h>
#include "../browser-connection.h"
+#include "data-source-manager.h"
G_BEGIN_DECLS
@@ -46,9 +47,6 @@ struct _SpecEditor {
struct _SpecEditorClass {
GtkVBoxClass parent_class;
-
- /* signals */
- void (*changed) (SpecEditor *editor);
};
typedef enum {
@@ -58,17 +56,13 @@ typedef enum {
GType spec_editor_get_type (void) G_GNUC_CONST;
-SpecEditor *spec_editor_new (BrowserConnection *bcnc);
+SpecEditor *spec_editor_new (DataSourceManager *mgr);
void spec_editor_set_xml_text (SpecEditor *sped, const gchar *xml);
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);
-
G_END_DECLS
#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]