Re: [gnome-db] GdaDataModel is hard to implement on Vala



Find attached a patch (ready to commit) to implement missing invokers
on GdaDataModel. This allows vala extensions to implement GdaDataModel
with no problems.

2011/12/22 Daniel Espinosa <esodan gmail com>:
> I'm implementing GdaDataModel interface in an Gee Collection object
> called GdaData.DataModelIterable, but I can't implement the following
> virtual functions:
>
>                [NoWrapper]
>                public abstract bool i_get_notify ();
>                [NoWrapper]
>                public abstract bool i_iter_at_row (Gda.DataModelIter iter, int row);
>                [NoWrapper]
>                public abstract bool i_iter_next (Gda.DataModelIter iter);
>                [NoWrapper]
>                public abstract bool i_iter_prev (Gda.DataModelIter iter);
>                [NoWrapper]
>                public abstract bool i_iter_set_value (Gda.DataModelIter iter, int
> col, GLib.Value value) throws GLib.Error;
>                [NoWrapper]
>                public abstract void i_set_notify (bool do_notify_changes);
>
> These functions are declared *abstract* because they must be
> implemented and with the annotation [NoWrapper] because they don't
> have any function in the public header to call like the for example
> get_n_rows ();
>
>                [CCode (vfunc_name = "i_get_n_rows")]
>                public abstract int get_n_rows ();
>
> In the last function implementors must declare a get_n_rows ().
>
> In the case of the above functions they have the following problems:
>
> * i_iter_at_row, i_iter_next, i_iter_prev are functions that are
> implemented on a separated object GdaDataModelIter, then how to deal
> with that in C? Is this correct or can be modified in future version?
>
>
>  * i_set_notify and  i_get_notify they have a function that wrap it
> but they are "incompatible" because require different number of
> arguments and return type: freeze() and thaw (), initially I've
> declared them in GIR  as the one to call for the virtual functions but
> fails when Vala try to use them. Now they are declared as above with
> no invoker and with [NoWrapper] in Vala bindings.
>
> To fix all this problems is possible to add the following functions to
> the GdaDataModel just to have an invoker as a function to call and
> make easy to Vala (and maybe other languages) to implement
> GdaDataModel interface:
>
> gda_data_model_get_notify (GdaDataModel*)
> gda_data_model_set_notify (GdaDataModel*, gboolean)
> gda_data_model_iter_at_row (GdaDataModel*, GdaDataModelIter*, int)
> gda_data_model_iter_next (GdaDataModel*, GdaDataModelIter*)
> gda_data_model_iter_prev (GdaDataModel*, GdaDataModelIter*)
>
> Please tell me if this is correct in order to implement them and
> continue on Vala extensions.
>
> --
> Trabajar, la mejor arma para tu superación
> "de grano en grano, se hace la arena" (R) (en trámite, pero para los
> cuates: LIBRE)



-- 
Trabajar, la mejor arma para tu superación
"de grano en grano, se hace la arena" (R) (en trámite, pero para los
cuates: LIBRE)
From 7a3d2824f4dbf602eda98870c719b866d3120968 Mon Sep 17 00:00:00 2001
From: Daniel Espinosa <despinosa src gnome org>
Date: Thu, 22 Dec 2011 16:13:57 -0600
Subject: [PATCH] Added invokers for virtual funtions on GdaDataModel
 interface.

* Added i_set_notify, i_get_notify, i_iter_next, i_iter_prev, i_iter_at_row,
i_iter_set_value, invokers just to allow Vala classes to implement GdaDataModel
interface.

* GdaData.DataModelIterable now implements Gda.DataModel interface
---
 libgda/data/DataModelIterator.vala |   49 ++++++------
 libgda/data/GdaData-5.0.gir        |  101 +----------------------
 libgda/gda-data-model.c            |  159 ++++++++++++++++++++++++++++++++++++
 libgda/gda-data-model.h            |    8 ++
 4 files changed, 193 insertions(+), 124 deletions(-)

diff --git a/libgda/data/DataModelIterator.vala b/libgda/data/DataModelIterator.vala
index c6ec4da..c610eb9 100644
--- a/libgda/data/DataModelIterator.vala
+++ b/libgda/data/DataModelIterator.vala
@@ -22,7 +22,7 @@
  
  namespace GdaData {
  	
- 	public class DataModelIterable : Gee.AbstractCollection<Value?>
+ 	public class DataModelIterable : Gee.AbstractCollection<Value?>, Gda.DataModel
  	{
  		private Gda.DataModel model;
  		
@@ -329,30 +329,31 @@
 		}
 		
 		// THIS FUNCTIONS HAVEN'T DEFAULT IMPLEMENTATION OR PUBLIC API AND THEN CAN'T BE IMPLEMENTED HERE
-//		public bool i_get_notify () {
-//			return this.model.notify_changes i_get_notify ();
-//		}
+		public bool get_notify () {
+			
+			return this.model.get_notify ();
+		}
 
-//		public bool i_iter_at_row (Gda.DataModelIter iter, int row) {
-//			return ((Gda.DataSelect)this.model).i_iter_at_row (iter, row);
-//		}
-//		
-//		public bool i_iter_next (Gda.DataModelIter iter) {
-//			return ((Gda.DataSelect)this.model).i_iter_next (iter);
-//		}
-//		
-//		public bool i_iter_prev (Gda.DataModelIter iter) {
-//			return ((Gda.DataSelect)this.model).i_iter_prev (iter);
-//		}
-//		
-//		public bool i_iter_set_value (Gda.DataModelIter iter, int col, GLib.Value value) throws GLib.Error {
-//			return ((Gda.DataSelect)this.model).i_iter_set_value (iter, col, value);
-//		}
-//		
-//		public void i_set_notify (bool do_notify_changes)
-//		{
-//			((Gda.DataSelect)this.model).i_set_notify (do_notify_changes);
-//		}
+		public bool iter_at_row (Gda.DataModelIter iter, int row) {
+			return this.model.iter_at_row (iter, row);
+		}
+		
+		public bool iter_next (Gda.DataModelIter iter) {
+			return this.model.iter_next (iter);
+		}
+		
+		public bool iter_prev (Gda.DataModelIter iter) {
+			return this.model.iter_prev (iter);
+		}
+		
+		public bool iter_set_value (Gda.DataModelIter iter, int col, GLib.Value value) throws GLib.Error {
+			return this.model.iter_set_value (iter, col, value);
+		}
+		
+		public void set_notify (bool do_notify_changes)
+		{
+			this.model.set_notify (do_notify_changes);
+		}
 		public bool remove_row (int row) throws GLib.Error {
 			return this.model.remove_row (row);
 		}
diff --git a/libgda/data/GdaData-5.0.gir b/libgda/data/GdaData-5.0.gir
index 062bf9b..9328cbd 100644
--- a/libgda/data/GdaData-5.0.gir
+++ b/libgda/data/GdaData-5.0.gir
@@ -99,6 +99,7 @@
 	</record>
 	<record name="ObjectPrivate" c:type="GdaDataObjectPrivate" disguised="1"/>
 	<class name="DataModelIterable" c:type="GdaDataDataModelIterable" glib:type-name="GdaDataDataModelIterable" glib:get-type="gda_data_data_model_iterable_get_type" glib:type-struct="DataModelIterableClass" parent="Gee.AbstractCollection">
+		<implements name="Gda.DataModel"/>
 		<field name="parent_instance">
 			<type name="Gee.AbstractCollection" c:type="GeeAbstractCollection"/>
 		</field>
@@ -128,106 +129,6 @@
 				<type name="none"/>
 			</return-value>
 		</method>
-		<method name="append_row" c:identifier="gda_data_data_model_iterable_append_row" throws="1">
-			<return-value transfer-ownership="full">
-				<type name="gint" c:type="gint"/>
-			</return-value>
-		</method>
-		<method name="create_iter" c:identifier="gda_data_data_model_iterable_create_iter">
-			<return-value transfer-ownership="full">
-				<type name="Gda.DataModelIter" c:type="GdaDataModelIter*"/>
-			</return-value>
-		</method>
-		<method name="describe_column" c:identifier="gda_data_data_model_iterable_describe_column">
-			<parameters>
-				<parameter name="col" transfer-ownership="none">
-					<type name="gint" c:type="gint"/>
-				</parameter>
-			</parameters>
-			<return-value transfer-ownership="none">
-				<type name="Gda.Column" c:type="GdaColumn*"/>
-			</return-value>
-		</method>
-		<method name="get_access_flags" c:identifier="gda_data_data_model_iterable_get_access_flags">
-			<return-value transfer-ownership="full">
-				<type name="Gda.DataModelAccessFlags" c:type="GdaDataModelAccessFlags"/>
-			</return-value>
-		</method>
-		<method name="get_attributes_at" c:identifier="gda_data_data_model_iterable_get_attributes_at">
-			<parameters>
-				<parameter name="col" transfer-ownership="none">
-					<type name="gint" c:type="gint"/>
-				</parameter>
-				<parameter name="row" transfer-ownership="none">
-					<type name="gint" c:type="gint"/>
-				</parameter>
-			</parameters>
-			<return-value transfer-ownership="full">
-				<type name="Gda.ValueAttribute" c:type="GdaValueAttribute"/>
-			</return-value>
-		</method>
-		<method name="get_n_columns" c:identifier="gda_data_data_model_iterable_get_n_columns">
-			<return-value transfer-ownership="full">
-				<type name="gint" c:type="gint"/>
-			</return-value>
-		</method>
-		<method name="get_n_rows" c:identifier="gda_data_data_model_iterable_get_n_rows">
-			<return-value transfer-ownership="full">
-				<type name="gint" c:type="gint"/>
-			</return-value>
-		</method>
-		<method name="get_value_at" c:identifier="gda_data_data_model_iterable_get_value_at" throws="1">
-			<parameters>
-				<parameter name="col" transfer-ownership="none">
-					<type name="gint" c:type="gint"/>
-				</parameter>
-				<parameter name="row" transfer-ownership="none">
-					<type name="gint" c:type="gint"/>
-				</parameter>
-			</parameters>
-			<return-value transfer-ownership="none" allow-none="1">
-				<type name="GObject.Value" c:type="GValue*"/>
-			</return-value>
-		</method>
-		<method name="remove_row" c:identifier="gda_data_data_model_iterable_remove_row" throws="1">
-			<parameters>
-				<parameter name="row" transfer-ownership="none">
-					<type name="gint" c:type="gint"/>
-				</parameter>
-			</parameters>
-			<return-value transfer-ownership="full">
-				<type name="gboolean" c:type="gboolean"/>
-			</return-value>
-		</method>
-		<method name="send_hint" c:identifier="gda_data_data_model_iterable_send_hint">
-			<parameters>
-				<parameter name="hint" transfer-ownership="none">
-					<type name="Gda.DataModelHint" c:type="GdaDataModelHint"/>
-				</parameter>
-				<parameter name="hint_value" transfer-ownership="none" allow-none="1">
-					<type name="GObject.Value" c:type="GValue*"/>
-				</parameter>
-			</parameters>
-			<return-value transfer-ownership="full">
-				<type name="none"/>
-			</return-value>
-		</method>
-		<method name="set_value_at" c:identifier="gda_data_data_model_iterable_set_value_at" throws="1">
-			<parameters>
-				<parameter name="col" transfer-ownership="none">
-					<type name="gint" c:type="gint"/>
-				</parameter>
-				<parameter name="row" transfer-ownership="none">
-					<type name="gint" c:type="gint"/>
-				</parameter>
-				<parameter name="value" transfer-ownership="none">
-					<type name="GObject.Value" c:type="GValue"/>
-				</parameter>
-			</parameters>
-			<return-value transfer-ownership="full">
-				<type name="gboolean" c:type="gboolean"/>
-			</return-value>
-		</method>
 		<property name="element-type">
 			<type name="GObject.Type" c:type="GType"/>
 		</property>
diff --git a/libgda/gda-data-model.c b/libgda/gda-data-model.c
index 13721bd..40f2509 100644
--- a/libgda/gda-data-model.c
+++ b/libgda/gda-data-model.c
@@ -392,6 +392,55 @@ gda_data_model_thaw (GdaDataModel *model)
 }
 
 /**
+ * gda_data_model_set_notify:
+ * @model: a #GdaDataModel object.
+ * @do_notify_changes: Set to TRUE if you require notifications.
+ *
+ * Enable or disable notifications changes on the given data model.
+ * 
+ * Note: This function must be implemented but is recommended to use #gda_data_model_thaw
+ * and #gda_data_model_freeze functions instead.
+ *
+ * Virtual: i_set_notify
+ */
+void
+gda_data_model_set_notify (GdaDataModel *model, gboolean do_notify_changes)
+{
+	g_return_if_fail (GDA_IS_DATA_MODEL (model));
+	if (GDA_DATA_MODEL_GET_CLASS (model)->i_set_notify)
+		(GDA_DATA_MODEL_GET_CLASS (model)->i_set_notify) (model, do_notify_changes);
+	else {
+		/* method not supported */
+		g_warning ("%s() method not supported\n", __FUNCTION__);
+	}
+}
+
+/**
+ * gda_data_model_get_notify:
+ * @model: a #GdaDataModel object.
+ *
+ * Returns the status of notifications changes on the given data model.
+ * 
+ * Note: This function must be implemented but is recommended to use #gda_data_model_thaw
+ * and #gda_data_model_freeze functions instead.
+ *
+ * Virtual: i_get_notify
+ */
+gboolean
+gda_data_model_get_notify (GdaDataModel *model)
+{
+	g_return_val_if_fail (GDA_IS_DATA_MODEL (model), FALSE);
+	if (GDA_DATA_MODEL_GET_CLASS (model)->i_get_notify)
+		return (GDA_DATA_MODEL_GET_CLASS (model)->i_get_notify) (model);
+	else {
+		/* method not supported */
+		g_warning ("%s() method not supported\n", __FUNCTION__);
+		return FALSE;
+	}
+}
+
+
+/**
  * gda_data_model_get_access_flags:
  * @model: a #GdaDataModel object.
  *
@@ -887,6 +936,116 @@ gda_data_model_create_iter (GdaDataModel *model)
 }
 
 /**
+ * gda_data_model_iter_at_row:
+ * @model: a #GdaDataModel object.
+ * @iter: a #GdaDataModelIter object.
+ * @row: a row to point to with @iter
+ *
+ * Moves @iter to the row number given by @row.
+ * 
+ * Note: This function must be implemented but is recommended to use #GdaDataModelIter 
+ * object directly.
+ *
+ * Virtual: i_iter_at_row
+ */
+gboolean
+gda_data_model_iter_at_row (GdaDataModel *model, GdaDataModelIter *iter, gint row)
+{
+	g_return_val_if_fail (GDA_IS_DATA_MODEL (model), FALSE);
+	g_return_val_if_fail (GDA_IS_DATA_MODEL_ITER (model), FALSE);
+	if (GDA_DATA_MODEL_GET_CLASS (model)->i_iter_at_row)
+		return (GDA_DATA_MODEL_GET_CLASS (model)->i_iter_at_row) (model, iter, row);
+	else {
+		/* method not supported */
+		g_warning ("%s() method not supported\n", __FUNCTION__);
+		return FALSE;
+	}
+}
+
+/**
+ * gda_data_model_iter_next:
+ * @model: a #GdaDataModel object.
+ * @iter: a #GdaDataModelIter object.
+ *
+ * Moves @iter to the next row in @model.
+ * 
+ * Note: This function must be implemented but is recommended to use #GdaDataModelIter 
+ * object directly.
+ *
+ * Virtual: i_iter_next
+ */
+gboolean
+gda_data_model_iter_next (GdaDataModel *model, GdaDataModelIter *iter)
+{
+	g_return_val_if_fail (GDA_IS_DATA_MODEL (model), FALSE);
+	g_return_val_if_fail (GDA_IS_DATA_MODEL_ITER (model), FALSE);
+	if (GDA_DATA_MODEL_GET_CLASS (model)->i_iter_next)
+		return (GDA_DATA_MODEL_GET_CLASS (model)->i_iter_next) (model, iter);
+	else {
+		/* method not supported */
+		g_warning ("%s() method not supported\n", __FUNCTION__);
+		return FALSE;
+	}
+}
+
+/**
+ * gda_data_model_iter_set_value:
+ * @model: a #GdaDataModel object.
+ * @iter: a #GdaDataModelIter object.
+ * @col: the number of column to set value to
+ * @value: the to use to set on
+ * @error: a place to set errors
+ *
+ * Set @value to the given @column and row pointed by @iter in the given @model.
+ * 
+ * Note: This function must be implemented but is recommended to use #GdaDataModelIter 
+ * object directly.
+ *
+ * Virtual: i_iter_set_value
+ */
+gboolean 
+gda_data_model_iter_set_value (GdaDataModel *model, GdaDataModelIter *iter, gint col,
+						       const GValue *value, GError **error)
+{
+	g_return_val_if_fail (GDA_IS_DATA_MODEL (model), FALSE);
+	g_return_val_if_fail (GDA_IS_DATA_MODEL_ITER (model), FALSE);
+	if (GDA_DATA_MODEL_GET_CLASS (model)->i_iter_set_value)
+		return (GDA_DATA_MODEL_GET_CLASS (model)->i_iter_set_value) (model, iter, col, value, error);
+	else {
+		/* method not supported */
+		g_warning ("%s() method not supported\n", __FUNCTION__);
+		return FALSE;
+	}
+}
+
+
+/**
+ * gda_data_model_iter_prev:
+ * @model: a #GdaDataModel object.
+ * @iter: a #GdaDataModelIter object.
+ *
+ * Moves @iter to the next row in @model.
+ * 
+ * Note: This function must be implemented but is recommended to use #GdaDataModelIter 
+ * object directly.
+ *
+ * Virtual: i_iter_prev
+ */
+gboolean 
+gda_data_model_iter_prev (GdaDataModel *model, GdaDataModelIter *iter)
+{
+	g_return_val_if_fail (GDA_IS_DATA_MODEL (model), FALSE);
+	g_return_val_if_fail (GDA_IS_DATA_MODEL_ITER (model), FALSE);
+	if (GDA_DATA_MODEL_GET_CLASS (model)->i_iter_prev)
+		return (GDA_DATA_MODEL_GET_CLASS (model)->i_iter_prev) (model, iter);
+	else {
+		/* method not supported */
+		g_warning ("%s() method not supported\n", __FUNCTION__);
+		return FALSE;
+	}
+}
+
+/**
  * gda_data_model_append_values:
  * @model: a #GdaDataModel object.
  * @values: (element-type GLib.Value) (allow-none): #GList of #GValue* representing the row to add.  The
diff --git a/libgda/gda-data-model.h b/libgda/gda-data-model.h
index b3cfeb8..2235cb7 100644
--- a/libgda/gda-data-model.h
+++ b/libgda/gda-data-model.h
@@ -186,8 +186,16 @@ const GValue       *gda_data_model_get_typed_value_at     (GdaDataModel *model,
 							   GType expected_type, gboolean nullok, GError **error);
 GdaValueAttribute   gda_data_model_get_attributes_at      (GdaDataModel *model, gint col, gint row);
 GdaDataModelIter   *gda_data_model_create_iter            (GdaDataModel *model);
+gboolean            gda_data_model_iter_at_row            (GdaDataModel *model, GdaDataModelIter *iter, 
+                               gint row);
+gboolean            gda_data_model_iter_next              (GdaDataModel *model, GdaDataModelIter *iter); 
+gboolean            gda_data_model_iter_prev              (GdaDataModel *model, GdaDataModelIter *iter);
+gboolean            gda_data_model_iter_set_value         (GdaDataModel *model, GdaDataModelIter *iter, gint col,
+						       const GValue *value, GError **error);
 void                gda_data_model_freeze                 (GdaDataModel *model);
 void                gda_data_model_thaw                   (GdaDataModel *model);
+void                gda_data_model_set_notify             (GdaDataModel *model, gboolean do_notify_changes);
+gboolean            gda_data_model_get_notify             (GdaDataModel *model);
 gboolean            gda_data_model_set_value_at           (GdaDataModel *model, gint col, gint row, 
 							   const GValue *value, GError **error);
 gboolean            gda_data_model_set_values             (GdaDataModel *model, gint row, 
-- 
1.7.6.4



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