[libgda] Virtual connection corrections and doc. improvements



commit b462bcf9af43c23467b434bce3f0e5a42894c9bc
Author: Vivien Malerba <malerba gnome-db org>
Date:   Sat Apr 9 15:05:58 2011 +0200

    Virtual connection corrections and doc. improvements

 doc/C/libgda-sections.txt                          |    1 +
 .../virtual/gda-vconnection-data-model-private.h   |    2 +-
 libgda/sqlite/virtual/gda-vconnection-data-model.c |  139 ++++++++++----------
 libgda/sqlite/virtual/gda-vconnection-data-model.h |  109 +++++++++++----
 libgda/sqlite/virtual/gda-vconnection-hub.c        |  109 ++++------------
 libgda/sqlite/virtual/gda-vprovider-data-model.c   |   60 +++++----
 6 files changed, 207 insertions(+), 213 deletions(-)
---
diff --git a/doc/C/libgda-sections.txt b/doc/C/libgda-sections.txt
index 837d53f..9a528c1 100644
--- a/doc/C/libgda-sections.txt
+++ b/doc/C/libgda-sections.txt
@@ -613,6 +613,7 @@ gda_vconnection_data_model_add_model
 gda_vconnection_data_model_remove
 gda_vconnection_data_model_get_table_name
 gda_vconnection_data_model_get_model
+gda_vconnection_data_model_get
 gda_vconnection_data_model_foreach
 <SUBSECTION Standard>
 GDA_IS_VCONNECTION_DATA_MODEL
diff --git a/libgda/sqlite/virtual/gda-vconnection-data-model-private.h b/libgda/sqlite/virtual/gda-vconnection-data-model-private.h
index 85b0d2d..e087052 100644
--- a/libgda/sqlite/virtual/gda-vconnection-data-model-private.h
+++ b/libgda/sqlite/virtual/gda-vconnection-data-model-private.h
@@ -1,4 +1,4 @@
-/* GDA
+/*
  * Copyright (C) 2007 The GNOME Foundation.
  *
  * AUTHORS:
diff --git a/libgda/sqlite/virtual/gda-vconnection-data-model.c b/libgda/sqlite/virtual/gda-vconnection-data-model.c
index f3b5417..9fedd75 100644
--- a/libgda/sqlite/virtual/gda-vconnection-data-model.c
+++ b/libgda/sqlite/virtual/gda-vconnection-data-model.c
@@ -1,6 +1,5 @@
 /* 
- * GDA common library
- * Copyright (C) 2007 - 2010 The GNOME Foundation.
+ * Copyright (C) 2007 - 2011 The GNOME Foundation.
  *
  * AUTHORS:
  *      Vivien Malerba <malerba gnome-db org>
@@ -33,23 +32,9 @@ struct _GdaVconnectionDataModelPrivate {
 	GSList *table_data_list; /* list of GdaVConnectionTableData structures */
 };
 
-/* properties */
-enum
-{
-        PROP_0,
-};
-
 static void gda_vconnection_data_model_class_init (GdaVconnectionDataModelClass *klass);
 static void gda_vconnection_data_model_init       (GdaVconnectionDataModel *cnc, GdaVconnectionDataModelClass *klass);
 static void gda_vconnection_data_model_dispose   (GObject *object);
-static void gda_vconnection_data_model_set_property (GObject *object,
-						     guint param_id,
-						     const GValue *value,
-						     GParamSpec *pspec);
-static void gda_vconnection_data_model_get_property (GObject *object,
-						     guint param_id,
-						     GValue *value,
-						     GParamSpec *pspec);
 static GObjectClass  *parent_class = NULL;
 
 /*
@@ -63,10 +48,6 @@ gda_vconnection_data_model_class_init (GdaVconnectionDataModelClass *klass)
 	parent_class = g_type_class_peek_parent (klass);
 
 	object_class->dispose = gda_vconnection_data_model_dispose;
-
-	/* Properties */
-        object_class->set_property = gda_vconnection_data_model_set_property;
-        object_class->get_property = gda_vconnection_data_model_get_property;
 }
 
 static void
@@ -98,6 +79,11 @@ gda_vconnection_data_model_dispose (GObject *object)
 	parent_class->dispose (object);
 }
 
+/**
+ * gda_vconnection_data_model_get_type:
+ *
+ * Returns: a new #GType
+ */
 GType
 gda_vconnection_data_model_get_type (void)
 {
@@ -129,42 +115,6 @@ gda_vconnection_data_model_get_type (void)
 }
 
 static void
-gda_vconnection_data_model_set_property (GObject *object,
-					 guint param_id,
-					 G_GNUC_UNUSED const GValue *value,
-					 GParamSpec *pspec)
-{
-        GdaVconnectionDataModel *cnc;
-
-        cnc = GDA_VCONNECTION_DATA_MODEL (object);
-        if (cnc->priv) {
-                switch (param_id) {
-		default:
-			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
-			break;
-                }
-        }
-}
-
-static void
-gda_vconnection_data_model_get_property (GObject *object,
-					 guint param_id,
-					 G_GNUC_UNUSED GValue *value,
-					 GParamSpec *pspec)
-{
-        GdaVconnectionDataModel *cnc;
-
-        cnc = GDA_VCONNECTION_DATA_MODEL (object);
-        if (cnc->priv) {
-		switch (param_id) {
-		default:
-			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
-			break;
-		}
-        }
-}
-
-static void
 spec_destroy_func (GdaVconnectionDataModelSpec *spec)
 {
 	g_object_unref (spec->data_model);
@@ -172,7 +122,7 @@ spec_destroy_func (GdaVconnectionDataModelSpec *spec)
 }
 
 static GList *
-create_columns (GdaVconnectionDataModelSpec *spec)
+create_columns (GdaVconnectionDataModelSpec *spec, GError **error)
 {
 	g_return_val_if_fail (spec->data_model, NULL);
 
@@ -188,7 +138,7 @@ create_columns (GdaVconnectionDataModelSpec *spec)
 }
 
 /**
- * gda_vconnection_data_model_add_model
+ * gda_vconnection_data_model_add_model:
  * @cnc: a #GdaVconnectionDataModel connection
  * @model: a #GdaDataModel
  * @table_name: the name of the table
@@ -200,7 +150,7 @@ create_columns (GdaVconnectionDataModelSpec *spec)
  *
  * For a more general approach, see the gda_vconnection_data_model_add() method.
  *
- * Returns: TRUE if no error occurred
+ * Returns: %TRUE if no error occurred
  */
 gboolean
 gda_vconnection_data_model_add_model (GdaVconnectionDataModel *cnc, 
@@ -219,9 +169,9 @@ gda_vconnection_data_model_add_model (GdaVconnectionDataModel *cnc,
 }
 
 /**
- * gda_vconnection_data_model_add
+ * gda_vconnection_data_model_add:
  * @cnc: a #GdaVconnectionDataModel connection
- * @spec: a #GdaVconnectionDataModelSpec structure
+ * @spec: a #GdaVconnectionDataModelSpec structure, used AS IS (not copied) and can be modified
  * @spec_free_func: function to call when freeing @spec, or %NULL
  * @table_name: the name of the table
  * @error: a place to store errors, or %NULL
@@ -232,7 +182,12 @@ gda_vconnection_data_model_add_model (GdaVconnectionDataModel *cnc,
  * If there is just one #GdaDataModel to make appear as a table
  * then the gda_vconnection_data_model_add_model() method is easier to use.
  *
- * Returns: TRUE if no error occurred
+ * The @spec_free_func can (depending on your code) be used to clean memory allocated for @spec or
+ * @spec->data_model.
+ *
+ * If an error occurs, then the @spec_free_func function is called using @spec as argument.
+ *
+ * Returns: %TRUE if no error occurred
  */
 gboolean
 gda_vconnection_data_model_add (GdaVconnectionDataModel *cnc, GdaVconnectionDataModelSpec *spec, 
@@ -251,8 +206,21 @@ gda_vconnection_data_model_add (GdaVconnectionDataModel *cnc, GdaVconnectionData
 	g_return_val_if_fail (table_name && *table_name, FALSE);
 	g_return_val_if_fail (spec, FALSE);
 	g_return_val_if_fail (spec->data_model || (spec->create_columns_func && (spec->create_model_func || spec->create_filtered_model_func)), FALSE);
-	if (spec->data_model)
+
+	/* cleaning functions */
+	if (spec->data_model) {
 		g_return_val_if_fail (GDA_IS_DATA_MODEL (spec->data_model), FALSE);
+		spec->create_columns_func = create_columns;
+		spec->create_model_func = NULL;
+		spec->create_filter_func = NULL;
+		spec->create_filtered_model_func = NULL;
+	}
+	else if (spec->create_filter_func)
+		spec->create_model_func = NULL;
+	else {
+		spec->create_filter_func = NULL;
+		spec->create_filtered_model_func = NULL;
+	}
 
 	scnc = (SqliteConnectionData*) gda_connection_internal_get_provider_data ((GdaConnection *) cnc);
 	if (!scnc) 
@@ -284,13 +252,12 @@ gda_vconnection_data_model_add (GdaVconnectionDataModel *cnc, GdaVconnectionData
 		g_print ("Virtual connection: added table %s (model = %p)\n", td->table_name, td->spec->data_model);
 	*/
 
-
 	return retval;
 }
 
 
 /**
- * gda_vconnection_data_model_remove
+ * gda_vconnection_data_model_remove:
  * @cnc: a #GdaVconnectionDataModel connection
  * @table_name: the name of the table to remove from @cnc
  * @error: a place to store errors, or %NULL
@@ -298,7 +265,7 @@ gda_vconnection_data_model_add (GdaVconnectionDataModel *cnc, GdaVconnectionData
  * Remove the table named @table_name in the @cnc connection (as if a "DROP TABLE..."
  * statement was executed, except that no data gets destroyed as the associated data model remains the same).
  *
- * Returns: TRUE if no error occurred
+ * Returns: %TRUE if no error occurred
  */
 gboolean
 gda_vconnection_data_model_remove (GdaVconnectionDataModel *cnc, const gchar *table_name, GError **error)
@@ -348,13 +315,41 @@ gda_vconnection_data_model_remove (GdaVconnectionDataModel *cnc, const gchar *ta
 }
 
 /**
- * gda_vconnection_data_model_get_model
+ * gda_vconnection_data_model_get:
+ * @cnc: a #GdaVconnectionDataModel connection
+ * @table_name: a table name within @cnc
+ *
+ * Find the #GdaVconnectionDataModelSpec specifying how the table named @table_name is represented
+ * in @cnc.
+ *
+ * Returns: (transfer none) (allow-none): a #GdaVconnectionDataModelSpec pointer, of %NULL if there is no table named @table_name
+ *
+ * Since: 5.0
+ */
+GdaVconnectionDataModelSpec *
+gda_vconnection_data_model_get (GdaVconnectionDataModel *cnc, const gchar *table_name)
+{
+	GdaVConnectionTableData *td;
+	g_return_val_if_fail (GDA_IS_VCONNECTION_DATA_MODEL (cnc), NULL);
+	if (!table_name || !(*table_name))
+		return NULL;
+	td = gda_vconnection_get_table_data_by_name (cnc, table_name);
+	if (td)
+		return td->spec;
+	else
+		return NULL;
+}
+
+/**
+ * gda_vconnection_data_model_get_model:
  * @cnc: a #GdaVconnectionDataModel connection
  * @table_name: a table name within @cnc
  *
- * Find the #GdaDataModel object representing the @table_name table in @cnc
+ * Find the #GdaDataModel object representing the @table_name table in @cnc. it can return %NULL
+ * either if no table named @table_name exists, or if that table actually exists but no #GdaDataModel
+ * has yet been created. For a more general approach, use the gda_vconnection_data_model_get().
  *
- * Returns: the #GdaDataModel, or %NULL if no table named @table_name exists
+ * Returns: (transfer none) (allow-none): the #GdaDataModel, or %NULL
  */
 GdaDataModel *
 gda_vconnection_data_model_get_model (GdaVconnectionDataModel *cnc, const gchar *table_name)
@@ -373,13 +368,13 @@ gda_vconnection_data_model_get_model (GdaVconnectionDataModel *cnc, const gchar
 }
 
 /**
- * gda_vconnection_data_model_get_table_name
+ * gda_vconnection_data_model_get_table_name:
  * @cnc: a #GdaVconnectionDataModel connection
  * @model: a #GdaDataModel representing a table within @cnc
  *
  * Find the name of the table associated to @model in @cnc
  *
- * Returns: the table name, or %NULL if not found
+ * Returns: (transfer none) (allow-none): the table name, or %NULL if not found
  */
 const gchar *
 gda_vconnection_data_model_get_table_name (GdaVconnectionDataModel *cnc, GdaDataModel *model)
@@ -399,7 +394,7 @@ gda_vconnection_data_model_get_table_name (GdaVconnectionDataModel *cnc, GdaData
 }
 
 /**
- * gda_vconnection_data_model_foreach
+ * gda_vconnection_data_model_foreach:
  * @cnc: a #GdaVconnectionDataModel connection
  * @func: a #GdaVconnectionDataModelFunc function pointer
  * @data: data to pass to @func calls
diff --git a/libgda/sqlite/virtual/gda-vconnection-data-model.h b/libgda/sqlite/virtual/gda-vconnection-data-model.h
index 90f8153..a617c39 100644
--- a/libgda/sqlite/virtual/gda-vconnection-data-model.h
+++ b/libgda/sqlite/virtual/gda-vconnection-data-model.h
@@ -42,39 +42,47 @@ typedef struct _GdaVconnectionDataModelFilter GdaVconnectionDataModelFilter;
 
 /**
  * GdaVconnectionDataModelCreateColumnsFunc:
- * @Param1: 
- * @Param2: 
- * @Returns: 
+ * @Param1: a pointer to a #GdaVconnectionDataModelSpec structure
+ * @Param2: a place to store errors, or %NULL
+ * @Returns: (element-type GdaColumn) (transfer full): a new list of #GdaColumn objects
+ *
+ * Function called to create the virtual table's columns, as #GdaColumn objects.
  */
-typedef GList        *(*GdaVconnectionDataModelCreateColumnsFunc) (GdaVconnectionDataModelSpec *, GError **);
+typedef GList *(*GdaVconnectionDataModelCreateColumnsFunc) (GdaVconnectionDataModelSpec *, GError **);
 
 /**
  * GdaVconnectionDataModelCreateModelFunc:
- * @Param1: 
- * @Returns: 
+ * @Param1: a pointer to a #GdaVconnectionDataModelSpec structure
+ * @Returns: (transfer full): a new #GdaDataModel
+ *
+ * Function called to create a #GdaDataModel object, called when a virtual table's data need to
+ * be accessed, and when optimization is not handled.
  */
-typedef GdaDataModel *(*GdaVconnectionDataModelCreateModelFunc)   (GdaVconnectionDataModelSpec *);
+typedef GdaDataModel *(*GdaVconnectionDataModelCreateModelFunc) (GdaVconnectionDataModelSpec *);
 
 /**
  * GdaVconnectionDataModelFunc:
- * @Param1: 
- * @Param2: 
- * @Param3: 
+ * @Param1: a pointer to a #GdaDataModel
+ * @Param2: the name of the table represented by @Param1
+ * @Param3: a data pointer, passed as last ergument to gda_vconnection_data_model_foreach()
+ *
+ * This function is called for every #GdaDataModel representing a table in a #GdaVconnectionDataModel
+ * connection, when using the gda_vconnection_data_model_foreach() method.
  */
-
 typedef void (*GdaVconnectionDataModelFunc) (GdaDataModel *, const gchar *, gpointer );
 
 /**
  * GdaVconnectionDataModelFilter:
  *
- * Enabling pre-filtering when creating a data model to be used as a table,
- * (structure closely mapped with SQLite's sqlite3_index_info type), to enable
- * the data model to perform some filter tasks itself.
+ * This structure contains data which should be analysed to produce a data model (used as data 
+ * for a virtual table) when a #GdaVconnectionDataModelCreateFModelFunc is called. The structure
+ * contains an input part (which should not be modified) and and output part (it is
+ * closely mapped with SQLite's sqlite3_index_info type).
  *
- * A pointer to this structure is passed to the GdaVconnectionDataModelParseFilterFunc function
- * and the function has to modify the variables in the *Outputs* section (and nowhere else)
+ * A pointer to this structure is passed to the #GdaVconnectionDataModelParseFilterFunc function
+ * and the function has to modify the variables in the output part (marked as *Outputs*).
  *
- * The @idxNum and @idxPointer are passed to the GdaVconnectionDataModelCreateFModelFunc function call
+ * The @idxNum and @idxPointer are passed to the #GdaVconnectionDataModelCreateFModelFunc function call
  * and they represent nothing specific except that the GdaVconnectionDataModelParseFilterFunc and
  * GdaVconnectionDataModelCreateFModelFunc functions need to agree on their meaning.
  *
@@ -106,26 +114,57 @@ struct _GdaVconnectionDataModelFilter {
 
 /**
  * GdaVconnectionDataModelParseFilterFunc:
- * @Param1:
- * @Param2:
+ * @Param1: a pointer to a #GdaVconnectionDataModelSpec structure
+ * @Param2: a pointer to a #GdaVconnectionDataModelFilter structure
+ *
+ * This function actually analyses the proposed optimization and modified @Param2 to tell the database
+ * engine how (if applicable) it implements the optimization.
  */
-typedef void          (*GdaVconnectionDataModelParseFilterFunc)   (GdaVconnectionDataModelSpec *, GdaVconnectionDataModelFilter *); 
+typedef void (*GdaVconnectionDataModelParseFilterFunc) (GdaVconnectionDataModelSpec *, GdaVconnectionDataModelFilter *); 
 
 /**
  * GdaVconnectionDataModelCreateFModelFunc:
- * @Param1: 
- * @Returns: 
+ * @Param1: a pointer to a #GdaVconnectionDataModelSpec structure
+ * @Param2: the index number chosen to actually execute the optimization (from #GdaVconnectionDataModelFilter's #idxNum attribute)
+ * @Param3: corresponds to the #GdaVconnectionDataModelFilter's #idxPointer attribute
+ * @Param4: size of @Param5
+ * @Param5: an array of #GValue, as specified by the #GdaVconnectionDataModelFilter's #aConstraintUsage's #argvIndex value
+ * @Returns: (transfer full): a new #GdaDataModel
+ *
+ * Function called to create a #GdaDataModel object, called when a virtual table's data need to
+ * be accessed, and when optimization is handled.
  */
-typedef GdaDataModel *(*GdaVconnectionDataModelCreateFModelFunc)  (GdaVconnectionDataModelSpec *,
-								   int, const char *, int, GValue **);
+typedef GdaDataModel *(*GdaVconnectionDataModelCreateFModelFunc) (GdaVconnectionDataModelSpec *, int, const char *, int, GValue **);
+
 /**
  * GdaVconnectionDataModelSpec:
- * @data_model: 
- * @create_columns_func: 
- * @create_model_func: 
- * @create_filter_func: 
- * @create_filtered_model_func:
+ * @data_model: a #GdaDataModel, or %NULL
+ * @create_columns_func: a pointer to a #GdaVconnectionDataModelCreateColumnsFunc function, or %NULL
+ * @create_model_func: a pointer to a #GdaVconnectionDataModelCreateModelFunc function, or %NULL
+ * @create_filter_func: a pointer to a #GdaVconnectionDataModelParseFilterFunc function, or %NULL
+ * @create_filtered_model_func: a pointer to a #GdaVconnectionDataModelCreateFModelFunc function, or %NULL
  *
+ * This structure holds all the information supplied to declare a virtual table using
+ * gda_vconnection_data_model_add(). You don't need to provider pointers for all the functions and
+ * for @data_model, but the following rules have to be respected:
+ * <itemizedlist>
+ *  <listitem><para>@data_model is not %NULL and all the function pointers are %NULL: this is the situation
+ *   when the virtual table's contents is defined once by @data_model</para></listitem>
+ *  <listitem><para>@data_model is %NULL and @create_columns_func is not %NULL:
+ *     <itemizedlist>
+ *        <listitem><para>@create_filtered_model_func is not %NULL: this is the situation where the
+ *                        virtual table's associated data model handles filter optimizations.
+ *                        @create_model_func is ignored in this case.
+ *        </para></listitem>
+ *        <listitem><para>@create_model_func is not %NULL: this is the situation where the
+ *                        virtual table's associated data model does not handle filter optimizations
+ *        </para></listitem>
+ *     </itemizedlist>
+ *  </para></listitem>
+ * </itemizedlist>
+ *
+ * Note that if specifying a @create_filtered_model_func, you should also specifiy a @create_filter_func
+ * function which is actually responsible for analysing the optimization.
  */
 struct _GdaVconnectionDataModelSpec {
 	GdaDataModel                             *data_model;
@@ -159,7 +198,16 @@ struct _GdaVconnectionDataModelClass {
  * @see_also: The #GdaVproviderDataModel provider to use to create such connection objects.
  *
  * The #GdaVconnectionDataModel is a virtual connection in which #GdaDataModel data models can be added
- * or removed, each representing a table in the connection.
+ * or removed, each representing a table in the connection, the gda_vconnection_data_model_add_model()
+ * and gda_vconnection_data_model_remove() methods.
+ *
+ * Furthermore it is possible to declare tables without any associated data model yet,
+ * the real data model being automatically created when the
+ * table's data is needed. This allows more dynamic table's contents and filtering optimizations.
+ * See the gda_vconnection_data_model_add() and gda_vconnection_data_model_remove() methods. The
+ * filtering optimizations are based on SQLite's virtual table optimisations see
+ * <ulink url="http://www.sqlite.org/cvstrac/wiki?p=VirtualTableBestIndexMethod";>SQLite's documentation</ulink>
+ * for some background information.
  */
 
 GType               gda_vconnection_data_model_get_type  (void) G_GNUC_CONST;
@@ -171,6 +219,7 @@ gboolean            gda_vconnection_data_model_add_model (GdaVconnectionDataMode
 							  GdaDataModel *model, const gchar *table_name, GError **error);
 gboolean            gda_vconnection_data_model_remove    (GdaVconnectionDataModel *cnc, const gchar *table_name, GError **error);
 
+GdaVconnectionDataModelSpec *gda_vconnection_data_model_get (GdaVconnectionDataModel *cnc, const gchar *table_name);
 const gchar        *gda_vconnection_data_model_get_table_name (GdaVconnectionDataModel *cnc, GdaDataModel *model);
 GdaDataModel       *gda_vconnection_data_model_get_model (GdaVconnectionDataModel *cnc, const gchar *table_name);
 
diff --git a/libgda/sqlite/virtual/gda-vconnection-hub.c b/libgda/sqlite/virtual/gda-vconnection-hub.c
index c36e179..efda161 100644
--- a/libgda/sqlite/virtual/gda-vconnection-hub.c
+++ b/libgda/sqlite/virtual/gda-vconnection-hub.c
@@ -1,6 +1,5 @@
 /* 
- * GDA common library
- * Copyright (C) 2007 - 2010 The GNOME Foundation.
+ * Copyright (C) 2007 - 2011 The GNOME Foundation.
  *
  * AUTHORS:
  *      Vivien Malerba <malerba gnome-db org>
@@ -47,23 +46,9 @@ struct _GdaVconnectionHubPrivate {
 	GSList *hub_connections; /* list of HubConnection structures */
 };
 
-/* properties */
-enum
-{
-        PROP_0,
-};
-
 static void gda_vconnection_hub_class_init (GdaVconnectionHubClass *klass);
 static void gda_vconnection_hub_init       (GdaVconnectionHub *cnc, GdaVconnectionHubClass *klass);
 static void gda_vconnection_hub_dispose   (GObject *object);
-static void gda_vconnection_hub_set_property (GObject *object,
-					      guint param_id,
-					      const GValue *value,
-					      GParamSpec *pspec);
-static void gda_vconnection_hub_get_property (GObject *object,
-					      guint param_id,
-					      GValue *value,
-					      GParamSpec *pspec);
 static GObjectClass  *parent_class = NULL;
 
 static HubConnection *get_hub_cnc_by_ns (GdaVconnectionHub *hub, const gchar *ns);
@@ -81,10 +66,6 @@ gda_vconnection_hub_class_init (GdaVconnectionHubClass *klass)
 
 	object_class->dispose = gda_vconnection_hub_dispose;
 
-	/* Properties */
-        object_class->set_property = gda_vconnection_hub_set_property;
-        object_class->get_property = gda_vconnection_hub_get_property;
-
 	/* static objects */
 	internal_parser = gda_sql_parser_new ();
 }
@@ -146,44 +127,8 @@ gda_vconnection_hub_get_type (void)
 	return type;
 }
 
-static void
-gda_vconnection_hub_set_property (GObject *object,
-					 guint param_id,
-					 G_GNUC_UNUSED const GValue *value,
-					 GParamSpec *pspec)
-{
-        GdaVconnectionHub *cnc;
-
-        cnc = GDA_VCONNECTION_HUB (object);
-        if (cnc->priv) {
-                switch (param_id) {
-		default:
-			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
-			break;
-                }
-        }
-}
-
-static void
-gda_vconnection_hub_get_property (GObject *object,
-					 guint param_id,
-					 G_GNUC_UNUSED GValue *value,
-					 GParamSpec *pspec)
-{
-        GdaVconnectionHub *cnc;
-
-        cnc = GDA_VCONNECTION_HUB (object);
-        if (cnc->priv) {
-		switch (param_id) {
-		default:
-			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
-			break;
-		}
-        }
-}
-
 /**
- * gda_vconnection_hub_add
+ * gda_vconnection_hub_add:
  * @hub: a #GdaVconnectionHub connection
  * @cnc: a #GdaConnection
  * @ns: a namespace, or %NULL
@@ -239,7 +184,7 @@ gda_vconnection_hub_add (GdaVconnectionHub *hub,
 }
 
 /**
- * gda_vconnection_hub_remove
+ * gda_vconnection_hub_remove:
  * @hub: a #GdaVconnectionHub connection
  * @cnc: a #GdaConnection
  * @error: a place to store errors, or %NULL
@@ -293,7 +238,7 @@ get_hub_cnc_by_cnc (GdaVconnectionHub *hub, GdaConnection *cnc)
 }
 
 /**
- * gda_vconnection_hub_get_connection
+ * gda_vconnection_hub_get_connection:
  * @hub: a #GdaVconnectionHub connection
  * @ns: a name space, or %NULL
  *
@@ -316,7 +261,7 @@ gda_vconnection_hub_get_connection (GdaVconnectionHub *hub, const gchar *ns)
 }
 
 /**
- * gda_vconnection_hub_foreach
+ * gda_vconnection_hub_foreach:
  * @hub: a #GdaVconnectionHub connection
  * @func: a #GdaVconnectionDataModelFunc function pointer
  * @data: data to pass to @func calls
@@ -455,22 +400,20 @@ dict_table_create_columns_func (GdaVconnectionDataModelSpec *spec, GError **erro
 }
 
 static gchar *
-make_string_for_sqlite3_index_info (sqlite3_index_info *info)
+make_string_for_filter (GdaVconnectionDataModelFilter *info)
 {
 	GString *string;
 	gint i;
 
 	string = g_string_new ("");
 	for (i = 0; i < info->nConstraint; i++) {
-		const struct sqlite3_index_constraint *cons;
+		const struct GdaVirtualConstraint *cons;
 		cons = &(info->aConstraint [i]);
-		if (! cons->usable)
-			continue;
 		g_string_append_printf (string, "|%d,%d", cons->iColumn, cons->op);
 	}
 	g_string_append_c (string, '/');
 	for (i = 0; i < info->nOrderBy; i++) {
-		struct sqlite3_index_orderby *order;
+		struct GdaVirtualOrderby *order;
 		order = &(info->aOrderBy[i]);
 		g_string_append_printf (string, "|%d,%d", order->iColumn, order->desc ? 1 : 0);
 	}
@@ -480,7 +423,7 @@ make_string_for_sqlite3_index_info (sqlite3_index_info *info)
 typedef struct {
 	GdaStatement *stmt;
 	int orderByConsumed;
-	struct sqlite3_index_constraint_usage *out_const;
+	struct GdaVirtualConstraintUsage *out_const;
 } ComputedFilter;
 
 static void
@@ -492,7 +435,7 @@ computed_filter_free (ComputedFilter *filter)
 }
 
 static void
-dict_table_create_filter (GdaVconnectionDataModelSpec *spec, sqlite3_index_info *info)
+dict_table_create_filter (GdaVconnectionDataModelSpec *spec, GdaVconnectionDataModelFilter *info)
 {
 	LocalSpec *lspec = (LocalSpec *) spec;
 	GdaSqlBuilder *b;
@@ -503,17 +446,16 @@ dict_table_create_filter (GdaVconnectionDataModelSpec *spec, sqlite3_index_info
 	if (lspec->cols_error)
 		return;
 
-	hash = make_string_for_sqlite3_index_info (info);
+	hash = make_string_for_filter (info);
 	if (lspec->filters_hash) {
 		ComputedFilter *filter;
 		filter = g_hash_table_lookup (lspec->filters_hash, hash);
 		if (filter) {
-			info->idxStr = (char*) filter->stmt;
-			info->needToFreeIdxStr = FALSE;
+			info->idxPointer = filter->stmt;
 			info->orderByConsumed = filter->orderByConsumed;
 			memcpy (info->aConstraintUsage,
 				filter->out_const,
-				sizeof (struct sqlite3_index_constraint_usage) * info->nConstraint);
+				sizeof (struct GdaVirtualConstraintUsage) * info->nConstraint);
 			/*g_print ("Reusing filter %p, hash=[%s]\n", filter, hash);*/
 			g_free (hash);
 			return;
@@ -533,10 +475,8 @@ dict_table_create_filter (GdaVconnectionDataModelSpec *spec, sqlite3_index_info
 	GdaSqlBuilderId *op_ids;
 	op_ids = g_new (GdaSqlBuilderId, info->nConstraint);
 	for (i = 0, argpos = 0; i < info->nConstraint; i++) {
-		const struct sqlite3_index_constraint *cons;
+		const struct GdaVirtualConstraint *cons;
 		cons = &(info->aConstraint [i]);
-		if (! cons->usable)
-			continue;
 		if (cons->iColumn >= lspec->ncols) {
 			g_warning ("Internal error: column known by SQLite's virtual table %d is not known for "
 				   "table '%s', which has %d column(s)", cons->iColumn,
@@ -570,10 +510,11 @@ dict_table_create_filter (GdaVconnectionDataModelSpec *spec, sqlite3_index_info
 	g_free (op_ids);
 	
 	/* ORDER BY part */
-	info->orderByConsumed = TRUE;
+	info->orderByConsumed = FALSE;
 	for (i = 0; i < info->nOrderBy; i++) {
-		struct sqlite3_index_orderby *ao;
+		struct GdaVirtualOrderby *ao;
 		GdaSqlBuilderId fid;
+		info->orderByConsumed = TRUE;
 		ao = &(info->aOrderBy [i]);
 		if (ao->iColumn >= lspec->ncols) {
 			g_warning ("Internal error: column known by SQLite's virtual table %d is not known for "
@@ -595,10 +536,10 @@ dict_table_create_filter (GdaVconnectionDataModelSpec *spec, sqlite3_index_info
 		filter = g_new0 (ComputedFilter, 1);
 		filter->stmt = stmt;
 		filter->orderByConsumed = info->orderByConsumed;
-		filter->out_const = g_new (struct sqlite3_index_constraint_usage,  info->nConstraint);
+		filter->out_const = g_new (struct GdaVirtualConstraintUsage,  info->nConstraint);
 		memcpy (filter->out_const,
 			info->aConstraintUsage,
-			sizeof (struct sqlite3_index_constraint_usage) * info->nConstraint);
+			sizeof (struct GdaVirtualConstraintUsage) * info->nConstraint);
 
 		gchar *sql;
 		sql = gda_statement_to_sql (stmt, NULL, NULL);
@@ -611,16 +552,16 @@ dict_table_create_filter (GdaVconnectionDataModelSpec *spec, sqlite3_index_info
 								     (GDestroyNotify) computed_filter_free);
 		
 		g_hash_table_insert (lspec->filters_hash, hash, filter);
-		info->idxStr = (char*) filter->stmt;
+		info->idxPointer = filter->stmt;
 		/*g_print ("There are now %d statements in store...\n", g_hash_table_size (lspec->filters_hash));*/
 	}
 	else {
 		for (i = 0, argpos = 0; i < info->nConstraint; i++) {
 			info->aConstraintUsage[i].argvIndex = 0;
-			info->aConstraintUsage[i].omit = 0;
+			info->aConstraintUsage[i].omit = FALSE;
 		}
-		info->idxStr = NULL;
-		info->orderByConsumed = 0;
+		info->idxPointer = NULL;
+		info->orderByConsumed = FALSE;
 		g_free (hash);
 	}
 }
@@ -977,8 +918,8 @@ table_add (HubConnection *hc, const GValue *table_name, GError **error)
 	GDA_VCONNECTION_DATA_MODEL_SPEC (lspec)->data_model = NULL;
 	GDA_VCONNECTION_DATA_MODEL_SPEC (lspec)->create_columns_func = (GdaVconnectionDataModelCreateColumnsFunc) dict_table_create_columns_func;
 	GDA_VCONNECTION_DATA_MODEL_SPEC (lspec)->create_model_func = NULL;
-	GDA_VCONNECTION_DATA_MODEL_SPEC (lspec)->create_filter_func = (GdaVconnectionDataModelParseFilterFunc) dict_table_create_filter;
-	GDA_VCONNECTION_DATA_MODEL_SPEC (lspec)->create_filtered_model_func = (GdaVconnectionDataModelCreateFModelFunc) dict_table_create_model_func;
+	GDA_VCONNECTION_DATA_MODEL_SPEC (lspec)->create_filter_func = dict_table_create_filter;
+	GDA_VCONNECTION_DATA_MODEL_SPEC (lspec)->create_filtered_model_func = dict_table_create_model_func;
 	lspec->table_name = gda_value_copy (table_name);
 	lspec->hc = hc;
 	tmp = get_complete_table_name (hc, lspec->table_name);
diff --git a/libgda/sqlite/virtual/gda-vprovider-data-model.c b/libgda/sqlite/virtual/gda-vprovider-data-model.c
index 5135449..3b6190f 100644
--- a/libgda/sqlite/virtual/gda-vprovider-data-model.c
+++ b/libgda/sqlite/virtual/gda-vprovider-data-model.c
@@ -1,5 +1,4 @@
 /* 
- * GDA common library
  * Copyright (C) 2007 - 2011 The GNOME Foundation.
  *
  * AUTHORS:
@@ -191,6 +190,7 @@ typedef struct {
 
 typedef struct {
 	sqlite3_vtab_cursor      base; /* base.pVtab is a pointer to the sqlite3_vtab virtual table */
+	GdaDataModel            *model; /* in which @iter iterates */
 	GdaDataModelIter        *iter;
 } VirtualCursor;
 
@@ -357,7 +357,7 @@ virtualCreate (sqlite3 *db, void *pAux, int argc, const char *const *argv, sqlit
 	GError *error = NULL;
 	if (!td->columns && td->spec->create_columns_func)
 		td->columns = td->spec->create_columns_func (td->spec, &error);
-	if (! td->columns) {
+	if (!td->columns) {
 		if (error && error->message) {
 			int len = strlen (error->message) + 1;
 			*pzErr = SQLITE3_CALL (sqlite3_malloc) (sizeof (gchar) * len);
@@ -384,10 +384,7 @@ virtualCreate (sqlite3 *db, void *pAux, int argc, const char *const *argv, sqlit
 
 		if (i != 0)
 			g_string_append (sql, ", ");
-		if (td->columns)
-			column = g_list_nth_data (td->columns, i);
-		else
-			column = gda_data_model_describe_column (td->spec->data_model, i);
+		column = g_list_nth_data (td->columns, i);
 		if (!column) {
 			*pzErr = SQLITE3_CALL (sqlite3_mprintf) (_("Can't get data model description for column %d"), i);
 			g_string_free (sql, TRUE);
@@ -497,11 +494,10 @@ virtualOpen (sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor)
 {
 	VirtualCursor *cursor;
 
-	TRACE (pVTab, NULL);
-
 	/* create empty cursor */
 	cursor = g_new0 (VirtualCursor, 1);
 	*ppCursor = (sqlite3_vtab_cursor*) cursor;
+	TRACE (pVTab, cursor);
 
 	return SQLITE_OK;
 }
@@ -515,8 +511,11 @@ virtualClose (sqlite3_vtab_cursor *cur)
 
 	if (cursor->iter)
 		g_object_unref (cursor->iter);
+	if (cursor->model)
+		g_object_unref (cursor->model);
 
 	g_free (cur);
+
 	return SQLITE_OK;
 }
 
@@ -779,6 +778,7 @@ virtualFilter (sqlite3_vtab_cursor *pVtabCursor, int idxNum, const char *idxStr,
 	else
 		cursor->iter = gda_data_model_create_iter (vtable->td->real_model);
 
+	cursor->model = g_object_ref (vtable->td->real_model);
 	gda_data_model_iter_move_next (cursor->iter);
 	return SQLITE_OK;
 }
@@ -827,43 +827,48 @@ index_info_dump (sqlite3_index_info *pIdxInfo, gboolean dump_out)
 static void
 map_sqlite3_info_to_gda_filter (sqlite3_index_info *info, GdaVconnectionDataModelFilter *filter)
 {
-	gint i;
 	memset (filter, 0, sizeof (GdaVconnectionDataModelFilter));
-	filter->nConstraint = info->nConstraint;
 	if (info->nConstraint > 0) {
-		filter->aConstraint = g_new (struct GdaVirtualConstraint, filter->nConstraint);
-		filter->aConstraintUsage = g_new (struct GdaVirtualConstraintUsage, filter->nConstraint);
-		for (i = 0; i < info->nConstraint; i++) {
-			filter->aConstraint[i].iColumn = info->aConstraint[i].iColumn;
+		gint i, j;
+		filter->aConstraint = g_new (struct GdaVirtualConstraint, info->nConstraint);
+		filter->aConstraintUsage = g_new (struct GdaVirtualConstraintUsage, info->nConstraint);
+		for (i = 0, j = 0; i < info->nConstraint; i++) {
+			if (! info->aConstraint[i].usable)
+				continue;
+
+			filter->aConstraint[j].iColumn = info->aConstraint[i].iColumn;
 			switch (info->aConstraint[i].op) {
 			case SQLITE_INDEX_CONSTRAINT_EQ:
-				filter->aConstraint[i].op = GDA_SQL_OPERATOR_TYPE_EQ;
+				filter->aConstraint[j].op = GDA_SQL_OPERATOR_TYPE_EQ;
 				break;
 			case SQLITE_INDEX_CONSTRAINT_GT:
-				filter->aConstraint[i].op = GDA_SQL_OPERATOR_TYPE_GT;
+				filter->aConstraint[j].op = GDA_SQL_OPERATOR_TYPE_GT;
 				break;
 			case SQLITE_INDEX_CONSTRAINT_LE:
-				filter->aConstraint[i].op = GDA_SQL_OPERATOR_TYPE_LEQ;
+				filter->aConstraint[j].op = GDA_SQL_OPERATOR_TYPE_LEQ;
 				break;
 			case SQLITE_INDEX_CONSTRAINT_LT:
-				filter->aConstraint[i].op = GDA_SQL_OPERATOR_TYPE_LT;
+				filter->aConstraint[j].op = GDA_SQL_OPERATOR_TYPE_LT;
 				break;
 			case SQLITE_INDEX_CONSTRAINT_GE:
-				filter->aConstraint[i].op = GDA_SQL_OPERATOR_TYPE_GEQ;
+				filter->aConstraint[j].op = GDA_SQL_OPERATOR_TYPE_GEQ;
 				break;
 			case SQLITE_INDEX_CONSTRAINT_MATCH:
-				filter->aConstraint[i].op = GDA_SQL_OPERATOR_TYPE_REGEXP;
+				filter->aConstraint[j].op = GDA_SQL_OPERATOR_TYPE_REGEXP;
 				break;
 			default:
 				g_assert_not_reached ();
 			}
 
-			filter->aConstraintUsage[i].argvIndex = 0;
-			filter->aConstraintUsage[i].omit = FALSE;
+			filter->aConstraintUsage[j].argvIndex = 0;
+			filter->aConstraintUsage[j].omit = FALSE;
+			j++;
 		}
+		filter->nConstraint = j;
 	}
 	filter->nOrderBy = info->nOrderBy;
 	if (filter->nOrderBy > 0) {
+		gint i;
 		filter->aOrderBy = g_new (struct GdaVirtualOrderby, filter->nOrderBy);
 		for (i = 0; i < info->nOrderBy; i++) {
 			filter->aOrderBy[i].iColumn = info->aOrderBy[i].iColumn;
@@ -882,15 +887,18 @@ map_sqlite3_info_to_gda_filter (sqlite3_index_info *info, GdaVconnectionDataMode
 static void
 map_consume_gda_filter_to_sqlite3_info (GdaVconnectionDataModelFilter *filter, sqlite3_index_info *info)
 {
-	gint i;
 	g_assert (filter->nConstraint == info->nConstraint);
 	if (info->nConstraint > 0) {
-		for (i = 0; i < info->nConstraint; i++) {
-			info->aConstraintUsage[i].argvIndex = filter->aConstraintUsage[i].argvIndex;
-			info->aConstraintUsage[i].omit = filter->aConstraintUsage[i].omit ? 1 : 0;
+		gint i, j;
+		for (i = 0, j = 0; i < info->nConstraint; i++) {
+			if (! info->aConstraint[i].usable)
+				continue;
+			info->aConstraintUsage[i].argvIndex = filter->aConstraintUsage[j].argvIndex;
+			info->aConstraintUsage[i].omit = filter->aConstraintUsage[j].omit ? 1 : 0;
 		}
 		g_free (filter->aConstraint);
 		g_free (filter->aConstraintUsage);
+		j++;
 
 	}
 	if (filter->nOrderBy > 0)



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