Re: [gnome-db] patch: gda-postgres recset



On Fri, 2005-01-07 at 12:07 +0100, Rodrigo Moya wrote:
> On Fri, 2005-01-07 at 15:49 +1000, Bas Driessen wrote:
> > Hello,
> > 
> > Attached a patch for the postgres provider. The append-row recset method
> > needs to up the total number of rows in a data model. The attached patch
> > takes care of that. 
> > 
> > Further it includes all changes in the same file as send yesterday (not
> > to complicate roll-ins). It is a diff against the latest version in cvs.
> > 
> looks good, but missed the ChangeLog entry, could you please send a new
> patch that includes that?
> 

Thanks Rodrigo. Please find attached 2 patch files. If OK, the first one
that needs to be applied is "gda-postgres-recset.patch". This one
includes the changes as discussed earlier, but includes the ChangeLog
entry as requested (and some minor format/cleanup changes). Rodrigo
mentioned that my other patch is applied, so I have used that ChangeLog
as starting point for the diff.

Then I followed up Vivien's advise and double checked the effect of the
"R" marked rows on other gda-data-model functions. The only one that may
be changed is the gda-data-model-foreach function. We can force it to
skip the "R"emoved rows. If you agree, the change is in gda-data-
model.patch and should be applied after the gda-postgres-recset.patch,
since it uses that ChangeLog as starting point for the diff.

Regarding the returning of the number of rows in a data model. Even
though the rows are marked, I believe it should not effect the total
numbers of rows. Example; I have a data model with 10 rows. I remove row
2,4,6. So valid rows are 1,3,5,7,8 and 9. If I change the number of rows
from 10 to 7, then it would not make sense to check row 9 for a value,
since row 9 > max rows in the data model. Alternatively, a second
function can be created like gda_data_model_get_active_n_rows that will
return the number of active rows in a data model.

Please let me know your thoughts/concerns/advise etc :) .

Thanks,
Bas.


--- ChangeLog.orig	2005-01-07 23:38:40.812251477 +1000
+++ ChangeLog	2005-01-07 23:42:12.990690072 +1000
@@ -3,6 +3,14 @@
 	* libgda/gda-data-model-hash.c (gda_data_model_hash_append_row):
 	set row number of appended row.
 
+	* providers/postgres/gda-postgres-recordset.c
+	(gda_postgres_recordset_remove_row): implemented new method
+	for data model.
+
+	* providers/postgres/gda-postgres-recordset.c
+	(gda_postgres_recordset_append_row): increment number of
+	rows in the data model.
+
 2004-12-29  Aaron Gaudio <prothonotar tarnation dyndns org>
 
 	* libgda.spec.in: fixed includedir.
--- providers/postgres/gda-postgres-recordset.c.orig	2005-01-06 19:19:12.000000000 +1000
+++ providers/postgres/gda-postgres-recordset.c	2005-01-07 23:47:57.487832348 +1000
@@ -57,6 +57,7 @@
 static gint gda_postgres_recordset_get_n_rows 		      (GdaDataModel *model);
 static const GdaRow *gda_postgres_recordset_get_row 	      (GdaDataModel *model, gint rownum);
 static const GdaRow *gda_postgres_recordset_append_row        (GdaDataModel *model, const GList *values);
+static gboolean gda_postgres_recordset_remove_row 	      (GdaDataModel *model, const GdaRow *row);
 static gboolean gda_postgres_recordset_update_row 	      (GdaDataModel *model, const GdaRow *row);
 
 static GObjectClass *parent_class = NULL;
@@ -91,6 +92,7 @@
 	model_class->get_value_at = gda_postgres_recordset_get_value_at;
 	model_class->get_row = gda_postgres_recordset_get_row;
 	model_class->append_row = gda_postgres_recordset_append_row;
+	model_class->remove_row = gda_postgres_recordset_remove_row;
 	model_class->update_row = gda_postgres_recordset_update_row;
 }
 
@@ -313,10 +315,122 @@
 					  gda_postgres_make_error (pg_conn, NULL));
 	row = GDA_DATA_MODEL_CLASS (parent_class)->append_row (model, values);
 
+	/* up the total number of rows */
+	if (row)
+		recset->priv->nrows++;
+
 	return row;
 }
 
 static gboolean
+gda_postgres_recordset_remove_row (GdaDataModel *model, const GdaRow *row)
+{
+	GdaPostgresRecordset *recset = (GdaPostgresRecordset *) model;
+	GdaPostgresRecordsetPrivate *priv_data;
+	gint colnum, uk, i;
+	PGresult *pg_res, *pg_rm_res;
+	gchar *query, *query_where, *tmp;
+	GdaPostgresConnectionData *cnc_priv_data;
+	PGconn *pg_conn;
+	gboolean status = FALSE;
+	GdaValue *value;
+
+	g_return_val_if_fail (GDA_IS_POSTGRES_RECORDSET (recset), FALSE);
+	g_return_val_if_fail (recset->priv != NULL, FALSE);
+	g_return_val_if_fail (row != NULL, FALSE);
+
+	priv_data = recset->priv;
+	pg_res = priv_data->pg_res;
+	cnc_priv_data = g_object_get_data (G_OBJECT (priv_data->cnc),
+					   OBJECT_DATA_POSTGRES_HANDLE);
+	pg_conn = cnc_priv_data->pconn;
+
+	/* checks if the given row belongs to the given model */
+	if (gda_row_get_model ((GdaRow *) row) != model) {
+		gda_connection_add_error_string (priv_data->cnc,
+						_("Given row doesn't belong to the model."));
+		return FALSE;
+	}
+
+	/* checks if the table name has been guessed */
+	if (priv_data->table_name == NULL) {
+		gda_connection_add_error_string (priv_data->cnc,
+						_("Table name could not be guessed."));
+		return FALSE;
+	}
+
+	query_where = g_strdup ("WHERE TRUE ");
+
+	for (colnum = uk = 0;
+	     colnum != gda_data_model_get_n_columns (model);
+	     colnum++)
+	{
+		GdaFieldAttributes *attrs = gda_data_model_describe_column (model, colnum);
+		const gchar *column_name = PQfname (pg_res, colnum);
+		gchar *curval = gda_value_stringify (gda_row_get_value ((GdaRow *) row, colnum));
+
+		/* unique column: we will use it as an index */
+		if (gda_field_attributes_get_primary_key (attrs) ||
+		    gda_field_attributes_get_unique_key (attrs))
+		{
+			/* fills the 'where' part of the update command */
+			tmp = g_strdup_printf ("AND %s = '%s' ",
+					       column_name,
+					       curval);
+			query_where = g_strconcat (query_where, tmp, NULL);
+			g_free (tmp);
+			uk++;
+		}
+
+		g_free (curval);
+		gda_field_attributes_free (attrs);
+	}
+
+	if (uk == 0) {
+		gda_connection_add_error_string (priv_data->cnc,
+						_("Model doesn't have at least one unique key."));
+	}
+	else {
+		/* build the delete command */
+		query = g_strdup_printf ("DELETE FROM %s %s",
+					 priv_data->table_name,
+					 query_where);
+
+		/* remove the row */
+		pg_rm_res = PQexec (pg_conn, query);
+		g_free (query);
+
+		if (pg_rm_res != NULL) {
+			/* removal ok! */
+			if (PQresultStatus (pg_rm_res) == PGRES_COMMAND_OK)
+				status = TRUE;
+			else
+				gda_connection_add_error (priv_data->cnc,
+					 		  gda_postgres_make_error (pg_conn, pg_rm_res));
+			PQclear (pg_rm_res);
+		}
+		else
+			gda_connection_add_error (priv_data->cnc,
+						  gda_postgres_make_error (pg_conn, NULL));
+	}
+
+	g_free (query_where);
+
+        /* remove from data model by removing the data from the row and unsetting row id */
+	if (status == TRUE) {
+		for (i=0; i<gda_data_model_get_n_columns (model); i++) {
+			value = (GdaValue *) gda_row_get_value ((GdaRow *) row, i);
+			gda_value_set_string (value, "NULL");
+		}
+		gda_row_set_id ((GdaRow *) row, "R");
+                gda_data_model_row_removed (model, gda_row_get_number ((GdaRow *) row));
+                gda_data_model_changed (model);
+	}
+
+        return status;
+}
+
+static gboolean
 gda_postgres_recordset_update_row (GdaDataModel *model, const GdaRow *row)
 {
 	GdaPostgresRecordset *recset = (GdaPostgresRecordset *) model;
--- ChangeLog.orig	2005-01-07 23:58:19.264472856 +1000
+++ ChangeLog	2005-01-08 00:00:39.318998059 +1000
@@ -11,6 +11,9 @@
 	(gda_postgres_recordset_append_row): increment number of
 	rows in the data model.
 
+	* libgda/gda-data-model.c (gda_data_model_foreach):
+	Skip rows that are marked as "R"emoved.
+
 2004-12-29  Aaron Gaudio <prothonotar tarnation dyndns org>
 
 	* libgda.spec.in: fixed includedir.
--- libgda/gda-data-model.c.orig	2005-01-08 00:05:45.174105440 +1000
+++ libgda/gda-data-model.c	2005-01-08 00:03:17.598730392 +1000
@@ -829,6 +829,7 @@
 	gint r;
 	const GdaRow *row;
 	gboolean more;
+	gchar *rowid;
 
 	g_return_if_fail (GDA_IS_DATA_MODEL (model));
 	g_return_if_fail (func != NULL);
@@ -837,6 +838,12 @@
 	more = TRUE;
 	for (r = 0; more && r < rows ; r++) {
 		row = gda_data_model_get_row (model, r);
+
+		/* check if row is marked as "R"emoved */
+		rowid = (gchar *)gda_row_get_id(row);
+		if ((rowid != NULL) && (rowid[0] == 'R'))
+			continue;
+
 		/* call the callback function */
 		more = func (model, (GdaRow *) row, user_data);
 	}


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