[gnome-db] turning postgres recordset into a GdaDataModelArray derived object



	Here it is. Please help me! I keep getting NULL values even
	just before calling append_row in get_value_at

-- 
Gonzalo Paniagua Javier <gonzalo gnome-db org>
http://www.gnome-db.org/~gonzalo/

Index: gda-postgres-provider.c
===================================================================
RCS file: /cvs/gnome/libgda/providers/postgres/gda-postgres-provider.c,v
retrieving revision 1.29
diff -u -r1.29 gda-postgres-provider.c
--- gda-postgres-provider.c	9 May 2002 22:52:26 -0000	1.29
+++ gda-postgres-provider.c	10 May 2002 00:50:41 -0000
@@ -381,6 +381,7 @@
 			PGresult *pg_res;
 			GdaDataModel *recset;
 			gint status;
+			gint i;
 
 			pg_res = PQexec(pconn, arr[n]);
 			if (pg_res == NULL) {
@@ -400,6 +401,10 @@
 				if (GDA_IS_DATA_MODEL (recset)) {
 					gda_data_model_set_command_text (recset, arr[n]);
 					gda_data_model_set_command_type (recset, GDA_COMMAND_TYPE_SQL);
+					for (i = PQnfields (pg_res) - 1; i >= 0; i--)
+						gda_data_model_set_column_title (recset, i, 
+									PQfname (pg_res, i));
+
 					reclist = g_list_append (reclist, recset);
 				}
 			}
@@ -581,6 +586,8 @@
 
 	recset = GDA_DATA_MODEL (reclist->data);
 	g_list_free (reclist);
+	// Set it here instead of the SQL query to allow i18n
+	gda_data_model_set_column_title (recset, 0, _("Tables"));
 
 	return recset;
 }
@@ -619,7 +626,7 @@
 
 	/* create the recordset */
 	recset = GDA_DATA_MODEL_ARRAY (gda_data_model_array_new (1));
-	gda_data_model_set_column_title (GDA_DATA_MODEL (recset), 0, _("Type"));
+	gda_data_model_set_column_title (GDA_DATA_MODEL (recset), 0, _("Types"));
 
 	/* fill the recordset */
 	priv_data = g_object_get_data (G_OBJECT (cnc), OBJECT_DATA_POSTGRES_HANDLE);
@@ -649,6 +656,8 @@
 
 	recset = GDA_DATA_MODEL (reclist->data);
 	g_list_free (reclist);
+	// Set it here instead of the SQL query to allow i18n
+	gda_data_model_set_column_title (recset, 0, _("Views"));
 
 	return recset;
 }
@@ -672,6 +681,8 @@
 
 	recset = GDA_DATA_MODEL (reclist->data);
 	g_list_free (reclist);
+	// Set it here instead of the SQL query to allow i18n
+	gda_data_model_set_column_title (recset, 0, _("Indexes"));
 
 	return recset;
 }
@@ -696,6 +707,8 @@
 
 	recset = GDA_DATA_MODEL (reclist->data);
 	g_list_free (reclist);
+	// Set it here instead of the SQL query to allow i18n
+	gda_data_model_set_column_title (recset, 0, _("Aggregates"));
 
 	return recset;
 }
@@ -719,6 +732,8 @@
 
 	recset = GDA_DATA_MODEL (reclist->data);
 	g_list_free (reclist);
+	// Set it here instead of the SQL query to allow i18n
+	gda_data_model_set_column_title (recset, 0, _("Triggers"));
 
 	return recset;
 }
@@ -727,8 +742,6 @@
 gda_postgres_init_md_recset (GdaConnection *cnc)
 {
 	GdaDataModelArray *recset;
-	//GdaValueType data_type;
-	//gint defined_size;
 	gint i;
 	GdaPostgresColData cols[8] = {
 		{ N_("Field name")	, GDA_VALUE_TYPE_STRING  },
@@ -742,16 +755,8 @@
 		};
 
 	recset = GDA_DATA_MODEL_ARRAY (gda_data_model_array_new (sizeof cols / sizeof cols[0]));
-	for (i = 0; i < sizeof cols / sizeof cols[0]; i++) {
-		//data_type = cols[i].data_type;
-		//defined_size =  (data_type == GDA_VALUE_TYPE_STRING) ? NAMEDATALEN : 
-		//		(data_type == GDA_VALUE_TYPE_INTEGER) ? sizeof(gint) : 1;
-
-		//gda_server_recordset_model_set_field_defined_size (recset, i, defined_size);
+	for (i = 0; i < sizeof cols / sizeof cols[0]; i++)
 		gda_data_model_set_column_title (GDA_DATA_MODEL (recset), i, _(cols[i].col_name));
-		//gda_server_recordset_model_set_field_scale (recset, i, 0);
-		//gda_server_recordset_model_set_field_gdatype (recset, i, data_type);
-	}
 
 	return recset;
 }
@@ -1081,6 +1086,8 @@
 
 	recset = GDA_DATA_MODEL (reclist->data);
 	g_list_free (reclist);
+	// Set it here instead of the SQL query to allow i18n
+	gda_data_model_set_column_title (recset, 0, _("Databases"));
 
 	return recset;
 }
@@ -1104,6 +1111,8 @@
 
 	recset = GDA_DATA_MODEL (reclist->data);
 	g_list_free (reclist);
+	// Set it here instead of the SQL query to allow i18n
+	gda_data_model_set_column_title (recset, 0, _("Users"));
 
 	return recset;
 }
@@ -1130,6 +1139,8 @@
 
 	recset = GDA_DATA_MODEL (reclist->data);
 	g_list_free (reclist);
+	// Set it here instead of the SQL query to allow i18n
+	gda_data_model_set_column_title (recset, 0, _("Sequences"));
 
 	return recset;
 }
Index: gda-postgres-recordset.c
===================================================================
RCS file: /cvs/gnome/libgda/providers/postgres/gda-postgres-recordset.c,v
retrieving revision 1.15
diff -u -r1.15 gda-postgres-recordset.c
--- gda-postgres-recordset.c	9 May 2002 04:47:26 -0000	1.15
+++ gda-postgres-recordset.c	10 May 2002 00:50:41 -0000
@@ -29,51 +29,110 @@
 #include "gda-postgres.h"
 #include "gda-postgres-recordset.h"
 
-#define OBJECT_DATA_RECSET_HANDLE "GDA_Postgres_RecsetHandle"
+#ifdef PARENT_TYPE
+#undef PARENT_TYPE
+#endif
 
-typedef struct {
+#define PARENT_TYPE GDA_TYPE_DATA_MODEL_ARRAY
+
+struct _GdaPostgresRecordsetPrivate {
 	PGresult *pg_res;
-	GdaConnection *gda_conn;
+	GdaConnection *cnc;
 
 	gint ntypes;
 	GdaPostgresTypeOid *type_data;
 	GHashTable *h_table;
-} GdaPostgresRecordsetPrivate;
+};
+
+
+static void gda_postgres_recordset_class_init (GdaPostgresRecordsetClass *klass);
+static void gda_postgres_recordset_init       (GdaPostgresRecordset *recset,
+					       GdaPostgresRecordsetClass *klass);
+static void gda_postgres_recordset_finalize   (GObject *object);
+static const GdaValue *get_value_at_func      (GdaDataModel *model, gint col, gint row);
+static GdaFieldAttributes *describe_func      (GdaDataModel *model, gint col);
+static gint get_n_rows_func 		      (GdaDataModel *model);
+static gint get_n_columns_func 		      (GdaDataModel *model);
+
+static GObjectClass *parent_class = NULL;
 
 /*
  * Private functions
  */
 
+/*
+ * Object init and finalize
+ */
+static void
+gda_postgres_recordset_init (GdaPostgresRecordset *recset,
+			     GdaPostgresRecordsetClass *klass)
+{
+	g_return_if_fail (GDA_IS_POSTGRES_RECORDSET (recset));
+
+	recset->priv = g_new0 (GdaPostgresRecordsetPrivate, 1);
+	recset->priv->cnc = NULL;
+	recset->priv->pg_res = NULL;
+	recset->priv->ntypes = 0;
+	recset->priv->type_data = NULL;
+	recset->priv->h_table = NULL;
+}
+
 static void
-free_postgres_res (gpointer data)
+gda_postgres_recordset_class_init (GdaPostgresRecordsetClass *klass)
 {
-	GdaPostgresRecordsetPrivate *priv_data = (GdaPostgresRecordsetPrivate *) data;
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	GdaDataModelClass *model_class = GDA_DATA_MODEL_CLASS (klass);
+
+	parent_class = g_type_class_peek_parent (klass);
+
+	object_class->finalize = gda_postgres_recordset_finalize;
+	model_class->get_n_rows = get_n_rows_func;
+	model_class->get_n_columns = get_n_columns_func;
+	model_class->describe_column = describe_func;
+	model_class->get_value_at = get_value_at_func;
+}
+
+static void
+gda_postgres_recordset_finalize (GObject * object)
+{
+	GdaPostgresRecordset *recset = (GdaPostgresRecordset *) object;
+
+	g_return_if_fail (GDA_IS_POSTGRES_RECORDSET (recset));
 
-	g_return_if_fail (priv_data != NULL);
+	if (recset->priv->pg_res != NULL) {
+		PQclear (recset->priv->pg_res);
+		recset->priv->pg_res = NULL;
+	}
+
+	g_free (recset->priv);
+	recset->priv = NULL;
 
-	PQclear (priv_data->pg_res);
-	g_free (priv_data);
+	parent_class->finalize (object);
 }
 
+/*
+ * Overrides
+ */
+
 static const GdaValue *
 get_value_at_func (GdaDataModel *model, gint col, gint row)
 {
+	GdaPostgresRecordset *recset = (GdaPostgresRecordset *) model;
 	GdaPostgresRecordsetPrivate *priv_data;
 	gint field_count;
 	gint row_count;
 	PGresult *pg_res;
-	GdaValue *value;
-	gchar *thevalue;
-	GdaValueType ftype;
-	gboolean isNull;
+	gint i;
+	GList *row_list = NULL;
 
-	g_return_val_if_fail (GDA_IS_DATA_MODEL (model), NULL);
-	priv_data = g_object_get_data (G_OBJECT (model), OBJECT_DATA_RECSET_HANDLE);
-	g_return_val_if_fail (priv_data != NULL, 0);
+	g_return_val_if_fail (GDA_IS_POSTGRES_RECORDSET (model), NULL);
+	g_return_val_if_fail (recset->priv != NULL, 0);
 
+	g_print ("Estoy en get_value_at\n");
+	priv_data = recset->priv;
 	pg_res = priv_data->pg_res;
 	if (!pg_res) {
-		gda_connection_add_error_string (priv_data->gda_conn,
+		gda_connection_add_error_string (priv_data->cnc,
 						_("Invalid PostgreSQL handle"));
 		return NULL;
 	}
@@ -85,34 +144,55 @@
 		return NULL; // For the last row don't add an error.
 
 	if (row < 0 || row > row_count) {
-		gda_connection_add_error_string (priv_data->gda_conn,
+		gda_connection_add_error_string (priv_data->cnc,
 						_("Row number out of range"));
 		return NULL;
 	}
 
-	if (field_count < 0 || col > field_count) {
-		gda_connection_add_error_string (priv_data->gda_conn,
+	if (field_count < 0 || col >= field_count) {
+		gda_connection_add_error_string (priv_data->cnc,
 						_("Column number out of range"));
 		return NULL;
 	}
 
-	thevalue = PQgetvalue(pg_res, row, col);
+	for (i = 0; i < field_count; i++) {
+		gchar *thevalue;
+		GdaValueType ftype;
+		gboolean isNull;
+		GdaValue *value;
+
+		thevalue = PQgetvalue(pg_res, row, i);
+
+		ftype = gda_postgres_type_oid_to_gda (priv_data->type_data,
+						      priv_data->ntypes, 
+						      PQftype (pg_res, i));
+		isNull = *thevalue != '\0' ? FALSE : PQgetisnull (pg_res, row, i);
+		thevalue = PQgetvalue(pg_res, row, col);
+
+		ftype = gda_postgres_type_oid_to_gda (priv_data->type_data,
+						      priv_data->ntypes, 
+						      PQftype (pg_res, col));
+
+		value = gda_value_new_null ();
+		gda_postgres_set_value (value, PQfname (pg_res, col), ftype,
+					thevalue, PQfsize (pg_res, col), isNull);
 
-	ftype = gda_postgres_type_oid_to_gda (priv_data->type_data,
-					      priv_data->ntypes, 
-					      PQftype (pg_res, col));
-	isNull = *thevalue != '\0' ? FALSE : PQgetisnull (pg_res, row, col);
+		row_list = g_list_append (row_list, value);
+	}
 
-	value = gda_value_new_null ();
-	gda_postgres_set_value (value, PQfname (pg_res, col), ftype,
-			 	thevalue, PQfsize (pg_res, col), isNull);
+	if (row_list == NULL)
+		return NULL;
 
-	return value;
+	gda_data_model_append_row (GDA_DATA_MODEL (model),
+				   (const GList *) row_list);
+	g_list_foreach (row_list, (GFunc) gda_value_free, NULL);
+	return GDA_DATA_MODEL_CLASS (parent_class)->get_value_at (model, col,row);
 }
 
 static GdaFieldAttributes *
 describe_func (GdaDataModel *model, gint col)
 {
+	GdaPostgresRecordset *recset = (GdaPostgresRecordset *) model;
 	GdaPostgresRecordsetPrivate *priv_data;
 	PGresult *pg_res;
 	gint field_count;
@@ -120,20 +200,21 @@
 	gint scale;
 	GdaFieldAttributes *field_attrs;
 
-	g_return_val_if_fail (GDA_IS_DATA_MODEL (model), NULL);
-	priv_data = g_object_get_data (G_OBJECT (model), OBJECT_DATA_RECSET_HANDLE);
-	g_return_val_if_fail (priv_data != NULL, 0);
+	g_return_val_if_fail (GDA_IS_POSTGRES_RECORDSET (recset), NULL);
+	g_return_val_if_fail (recset->priv != NULL, 0);
 
+	g_print ("Estoy en describe_func\n");
+	priv_data = recset->priv;
 	pg_res = priv_data->pg_res;
 	if (!pg_res) {
-		gda_connection_add_error_string (priv_data->gda_conn,
+		gda_connection_add_error_string (priv_data->cnc,
 						_("Invalid PostgreSQL handle"));
 		return NULL;
 	}
 
 	field_count = PQnfields (pg_res);
 	if (field_count >= col){
-		gda_connection_add_error_string (priv_data->gda_conn,
+		gda_connection_add_error_string (priv_data->cnc,
 						_("Column out of range"));
 		return NULL;
 	}
@@ -164,13 +245,15 @@
 static gint
 get_n_columns_func (GdaDataModel *model)
 {
+	GdaPostgresRecordset *recset = (GdaPostgresRecordset *) model;
 	GdaPostgresRecordsetPrivate *priv_data;
 	PGresult *pg_res;
 
 	g_return_val_if_fail (GDA_IS_DATA_MODEL (model), 0);
-	priv_data = g_object_get_data (G_OBJECT (model), OBJECT_DATA_RECSET_HANDLE);
-	g_return_val_if_fail (priv_data != NULL, 0);
+	g_return_val_if_fail (recset->priv != NULL, 0);
 
+	g_print ("Estoy en get_n_cols\n");
+	priv_data = recset->priv;
 	pg_res = priv_data->pg_res;
 	if (!pg_res)
 		return 0;
@@ -181,13 +264,15 @@
 static gint
 get_n_rows_func (GdaDataModel *model)
 {
+	GdaPostgresRecordset *recset = (GdaPostgresRecordset *) model;
 	GdaPostgresRecordsetPrivate *priv_data;
 	PGresult *pg_res;
 
 	g_return_val_if_fail (GDA_IS_DATA_MODEL (model), 0);
-	priv_data = g_object_get_data (G_OBJECT (model), OBJECT_DATA_RECSET_HANDLE);
-	g_return_val_if_fail (priv_data != NULL, 0);
+	g_return_val_if_fail (recset->priv != NULL, 0);
 
+	g_print ("Estoy en get_n_rows\n");
+	priv_data = recset->priv;
 	pg_res = priv_data->pg_res;
 	if (!pg_res)
 		return 0;
@@ -199,12 +284,32 @@
  * Public functions
  */
 
+GType
+gda_postgres_recordset_get_type (void)
+{
+	static GType type = 0;
+
+	if (!type) {
+		static const GTypeInfo info = {
+			sizeof (GdaPostgresRecordsetClass),
+			(GBaseInitFunc) NULL,
+			(GBaseFinalizeFunc) NULL,
+			(GClassInitFunc) gda_postgres_recordset_class_init,
+			NULL,
+			NULL,
+			sizeof (GdaPostgresRecordset),
+			0,
+			(GInstanceInitFunc) gda_postgres_recordset_init
+		};
+		type = g_type_register_static (PARENT_TYPE, "GdaPostgresRecordset", &info, 0);
+	}
+	return type;
+}
+
 GdaDataModel *
 gda_postgres_recordset_new (GdaConnection *cnc, PGresult *pg_res)
 {
-	GdaDataModel *model;
-	GdaDataModelClass *klass;
-	GdaPostgresRecordsetPrivate *priv_data;
+	GdaPostgresRecordset *model;
 	GdaPostgresConnectionData *cnc_priv_data;
 
 	g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
@@ -212,28 +317,16 @@
 
 	cnc_priv_data = g_object_get_data (G_OBJECT (cnc), OBJECT_DATA_POSTGRES_HANDLE);
 
-	priv_data = g_new (GdaPostgresRecordsetPrivate, 1);
-	priv_data->pg_res = pg_res;
-	priv_data->gda_conn = cnc;
-	priv_data->ntypes = cnc_priv_data->ntypes;
-	priv_data->type_data = cnc_priv_data->type_data;
-	priv_data->h_table = cnc_priv_data->h_table;
-
-	model = g_object_new (GDA_TYPE_DATA_MODEL, NULL);
-	klass = GDA_DATA_MODEL_CLASS (G_OBJECT_GET_CLASS (model));
-
-	klass->changed = NULL;
-	klass->begin_edit = NULL;
-	klass->cancel_edit = NULL;
-	klass->end_edit = NULL;
-	klass->get_n_rows = get_n_rows_func;
-	klass->get_n_columns = get_n_columns_func;
-	klass->describe_column = describe_func;
-	klass->get_value_at = get_value_at_func;
-
-	g_object_set_data_full (G_OBJECT (model), OBJECT_DATA_RECSET_HANDLE,
-				priv_data, (GDestroyNotify) free_postgres_res);
+	g_print ("Creo un recordset\n");
+	model = g_object_new (GDA_TYPE_POSTGRES_RECORDSET, NULL);
+	model->priv->pg_res = pg_res;
+	model->priv->cnc = cnc;
+	model->priv->ntypes = cnc_priv_data->ntypes;
+	model->priv->type_data = cnc_priv_data->type_data;
+	model->priv->h_table = cnc_priv_data->h_table;
+	gda_data_model_array_set_n_columns (GDA_DATA_MODEL_ARRAY (model),
+					    PQntuples (pg_res));
 
-	return model;
+	return GDA_DATA_MODEL (model);
 }
 
Index: gda-postgres-recordset.h
===================================================================
RCS file: /cvs/gnome/libgda/providers/postgres/gda-postgres-recordset.h,v
retrieving revision 1.4
diff -u -r1.4 gda-postgres-recordset.h
--- gda-postgres-recordset.h	9 May 2002 04:47:26 -0000	1.4
+++ gda-postgres-recordset.h	10 May 2002 00:50:41 -0000
@@ -32,6 +32,26 @@
 
 G_BEGIN_DECLS
 
+#define GDA_TYPE_POSTGRES_RECORDSET            (gda_postgres_recordset_get_type())
+#define GDA_POSTGRES_RECORDSET(obj)            (G_TYPE_CHECK_INSTANCE_CAST (obj, GDA_TYPE_POSTGRES_RECORDSET, GdaPostgresRecordset))
+#define GDA_POSTGRES_RECORDSET_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST (klass, GDA_TYPE_POSTGRES_RECORDSET, GdaPostgresRecordsetClass))
+#define GDA_IS_POSTGRES_RECORDSET(obj)         (G_TYPE_CHECK_INSTANCE_TYPE (obj, GDA_TYPE_POSTGRES_RECORDSET))
+#define GDA_IS_POSTGRES_RECORDSET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDA_TYPE_POSTGRES_RECORDSET))
+
+typedef struct _GdaPostgresRecordset        GdaPostgresRecordset;
+typedef struct _GdaPostgresRecordsetClass   GdaPostgresRecordsetClass;
+typedef struct _GdaPostgresRecordsetPrivate GdaPostgresRecordsetPrivate;
+
+struct _GdaPostgresRecordset {
+	GdaDataModelArray model;
+	GdaPostgresRecordsetPrivate *priv;
+};
+
+struct _GdaPostgresRecordsetClass {
+	GdaDataModelArrayClass parent_class;
+};
+
+GType          gda_postgres_recordset_get_type (void);
 GdaDataModel *gda_postgres_recordset_new (GdaConnection *cnc, PGresult *pgres);
 
 G_END_DECLS


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