[libgda] Bugs fixed in GdaDataSelect, new example using GdaDataSelect
- From: Vivien Malerba <vivien src gnome org>
- To: svn-commits-list gnome org
- Subject: [libgda] Bugs fixed in GdaDataSelect, new example using GdaDataSelect
- Date: Wed, 24 Jun 2009 13:38:28 +0000 (UTC)
commit b75d1397596d8224e2a032819232c82e6d5160bd
Author: Vivien Malerba <malerba gnome-db org>
Date: Wed Jun 24 15:38:11 2009 +0200
Bugs fixed in GdaDataSelect, new example using GdaDataSelect
* fixed 2 bugs in GdaDataSelect regarding internal rows handling
* added a new WritableSelect example to show how to use the GdaDataSelect
object
Makefile.am | 6 +-
libgda/gda-data-select.c | 14 ++-
samples/README | 2 +
samples/WritableSelect/README | 100 ++++++++++++++++++++
samples/WritableSelect/example.c | 192 ++++++++++++++++++++++++++++++++++++++
5 files changed, 307 insertions(+), 7 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 401e6de..a0d2360 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -71,6 +71,7 @@ example_files = \
samples/XSLT/data2.xml \
samples/XSLT/test.xsl \
samples/XSLT/transform.c \
+<<<<<<< HEAD:Makefile.am
samples/MetaStore/Makefile \
samples/MetaStore/README \
samples/MetaStore/background.c \
@@ -83,7 +84,10 @@ example_files = \
samples/SqlBuilder/example.c \
samples/AsyncExec/Makefile \
samples/AsyncExec/README \
- samples/AsyncExec/example.c
+ samples/AsyncExec/example.c \
+ samples/WritableSelect/README \
+ samples/WritableSelect/example.c \
+ samples/WritableSelect/Makefile
EXTRA_DIST = \
COPYING \
diff --git a/libgda/gda-data-select.c b/libgda/gda-data-select.c
index 718ce21..fadcd54 100644
--- a/libgda/gda-data-select.c
+++ b/libgda/gda-data-select.c
@@ -1722,8 +1722,7 @@ gda_data_select_get_value_at (GdaDataModel *model, gint col, gint row, GError **
GdaDataModel *tmpmodel;
if (!dstmt->select || !dstmt->params) {
g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_ACCESS_ERROR,
- "%s", _("Unable to retreive data after modifications, no further modification will be allowed"));
- imodel->priv->sh->modif_internals->safely_locked = TRUE;
+ "%s", _("Unable to retreive data after modifications"));
return NULL;
}
tmpmodel = gda_connection_statement_execute_select (imodel->priv->cnc,
@@ -1808,7 +1807,8 @@ gda_data_select_get_attributes_at (GdaDataModel *model, gint col, gint row)
imodel = (GdaDataSelect *) model;
g_return_val_if_fail (imodel->priv, 0);
- if (imodel->priv->sh->modif_internals->safely_locked || !imodel->priv->sh->modif_internals->modif_stmts [UPD_QUERY])
+ if (imodel->priv->sh->modif_internals->safely_locked ||
+ !imodel->priv->sh->modif_internals->modif_stmts [UPD_QUERY])
flags = GDA_VALUE_ATTR_NO_MODIF;
GdaColumn *gdacol = g_slist_nth_data (imodel->priv->sh->columns, col);
if (gdacol) {
@@ -2448,7 +2448,7 @@ vector_set_value_at (GdaDataSelect *imodel, BVector *bv, GdaDataModelIter *iter,
}
}
else {
- cvalue = gda_data_model_get_value_at ((GdaDataModel*) imodel, i, int_row, error);
+ cvalue = gda_data_model_get_value_at ((GdaDataModel*) imodel, i, row, error);
if (!cvalue)
return FALSE;
}
@@ -2809,6 +2809,8 @@ gda_data_select_append_values (GdaDataModel *model, const GList *values, GError
/* compute added row's number */
row = imodel->advertized_nrows;
+ if (imodel->priv->sh->del_rows)
+ row -= imodel->priv->sh->del_rows->len;
imodel->advertized_nrows++;
int_row = external_to_internal_row (imodel, row, error);
imodel->advertized_nrows--;
@@ -2908,7 +2910,8 @@ gda_data_select_append_values (GdaDataModel *model, const GList *values, GError
GdaSet *last_insert;
if (gda_connection_statement_execute_non_select (imodel->priv->cnc, stmt,
- imodel->priv->sh->modif_internals->modif_set, &last_insert, error) == -1)
+ imodel->priv->sh->modif_internals->modif_set,
+ &last_insert, error) == -1)
return -1;
/* mark that this row has been modified */
@@ -2957,7 +2960,6 @@ gda_data_select_append_values (GdaDataModel *model, const GList *values, GError
#ifdef GDA_DEBUG_NO
dump_d (imodel);
#endif
-
imodel->advertized_nrows++;
gda_data_model_row_inserted ((GdaDataModel *) imodel, row);
diff --git a/samples/README b/samples/README
index 6bae51a..55982f8 100644
--- a/samples/README
+++ b/samples/README
@@ -20,5 +20,7 @@ Currently the contents are:
* in Tree/: simple example to show how to use the GdaTree object
* in SqlBuilder: simple example to show how to use GdaSqlBuilder object to build various statements
* in AsyncExec: simple example illustrating how to perform asynchronous statement execution
+* in WritableSelect/: example to show how to modify a GdaDataModel returned after
+ the execution of a SELECT statement
Good luck and happy hacking!
diff --git a/samples/WritableSelect/README b/samples/WritableSelect/README
new file mode 100644
index 0000000..6e370a9
--- /dev/null
+++ b/samples/WritableSelect/README
@@ -0,0 +1,100 @@
+Writing to a data model created by executing a SELECT
+=====================================================
+
+Description:
+------------
+
+The example in this directory illustrate how to write to a data model created
+when executing a SELECT statement. It opens a connection to the SalesTest DSN,
+obtains all the data in the "customers" table, and then modify the contents
+of the returned data model (after each modification, the data model's contents
+is printed and the actual data in the "customers" is also printed).
+
+Note that for this to work, the meta data associated to the "customers" table must
+be up to date, which is why gda_connection_update_meta_store() is called before
+modifying the data model.
+
+Compiling and running:
+----------------------
+
+To compile (make sure Libgda is installed prior to this):
+> make
+
+and to run:
+> ./example
+
+The result should be similar to:
+** Data model is:
+id | name
+---+----------------
+ 2 | Ed Lamton
+ 3 | Lew Bonito
+ 4 | Mark Lawrencep
+ 9 | Greg Popoff
+10 | Vladimir Zirkov
+(5 rows)
+
+Computed UPDATE: UPDATE customers SET id=##+0::int, name=##+1::string WHERE id = ##-0::int
+Computed DELETE: DELETE FROM customers WHERE id = ##-0::int
+Computed INSERT: INSERT INTO customers (id, name) VALUES (##+0::int, ##+1::string)
+
+
+** Removing row 0
+** Data model is now:
+id | name
+---+----------------
+ 3 | Lew Bonito
+ 4 | Mark Lawrencep
+ 9 | Greg Popoff
+10 | Vladimir Zirkov
+(4 rows)
+** Table's contents is now:
+id | name
+---+----------------
+ 3 | Lew Bonito
+ 4 | Mark Lawrencep
+ 9 | Greg Popoff
+10 | Vladimir Zirkov
+(4 rows)
+
+
+** Adding a row
+** Data model is now:
+id | name
+---+----------------
+ 3 | Lew Bonito
+ 4 | Mark Lawrencep
+ 9 | Greg Popoff
+10 | Vladimir Zirkov
+11 | Hiro
+(5 rows)
+** Table's contents is now:
+id | name
+---+----------------
+ 3 | Lew Bonito
+ 4 | Mark Lawrencep
+ 9 | Greg Popoff
+10 | Vladimir Zirkov
+11 | Hiro
+(5 rows)
+
+
+** Modifying row 2
+** Data model is now:
+id | name
+---+----------------
+ 3 | Lew Bonito
+ 4 | Mark Lawrencep
+ 9 | Tom
+10 | Vladimir Zirkov
+11 | Hiro
+(5 rows)
+** Table's contents is now:
+id | name
+---+----------------
+ 3 | Lew Bonito
+ 4 | Mark Lawrencep
+ 9 | Tom
+10 | Vladimir Zirkov
+11 | Hiro
+(5 rows)
diff --git a/samples/WritableSelect/example.c b/samples/WritableSelect/example.c
new file mode 100644
index 0000000..1c0d97b
--- /dev/null
+++ b/samples/WritableSelect/example.c
@@ -0,0 +1,192 @@
+#include <libgda/libgda.h>
+#include <sql-parser/gda-sql-parser.h>
+
+GdaSqlParser *parser;
+
+GdaConnection *open_connection (void);
+void display_customers (GdaConnection *cnc);
+void run_sql_non_select (GdaConnection *cnc, const gchar *sql);
+
+int
+main (int argc, char *argv[])
+{
+ gda_init ();
+
+ GdaConnection *cnc;
+ GError *error = NULL;
+ GdaStatement *stmt;
+ GdaDataModel *model;
+ gchar *str;
+ GValue *name;
+
+ /* open connection */
+ cnc = open_connection ();
+
+ /* begin transaction */
+ if (! gda_connection_begin_transaction (cnc, NULL, GDA_TRANSACTION_ISOLATION_UNKNOWN,
+ &error)) {
+ g_print ("Could not begin transaction: %s\n",
+ error && error->message ? error->message : "No detail");
+ exit (1);
+ }
+
+ /* execute SELECT */
+ stmt = gda_sql_parser_parse_string (parser, "SELECT id, name FROM customers ORDER BY id", NULL, NULL);
+ g_assert (stmt);
+ model = gda_connection_statement_execute_select (cnc, stmt, NULL, &error);
+ g_object_unref (stmt);
+ if (!model) {
+ g_print ("Could not execute SELECT statement: %s\n",
+ error && error->message ? error->message : "No detail");
+ exit (1);
+ }
+
+ g_print ("** Data model is:\n");
+ gda_data_model_dump (model, stdout);
+
+ /*
+ * make sure the mete data is up to date
+ */
+ g_print ("Computing meta data, this may take a while; in real applications, this should be cached to avoid waiting\n");
+ if (! gda_connection_update_meta_store (cnc, NULL, &error)) {
+ g_print ("Could not fetch meta data: %s\n",
+ error && error->message ? error->message : "No detail");
+ exit (1);
+ }
+
+ /*
+ * Make the data model compute the modification statements which
+ * will actually be executed when the data model is modified
+ */
+ if (! gda_data_select_compute_modification_statements (GDA_DATA_SELECT (model), &error)) {
+ g_print ("Could not compute modification statements: %s\n",
+ error && error->message ? error->message : "No detail");
+ exit (1);
+ }
+
+ g_object_get (G_OBJECT (model), "update-stmt", &stmt, NULL);
+ str = gda_statement_to_sql (stmt, NULL, NULL);
+ g_print ("Computed UPDATE: %s\n", str);
+ g_free (str);
+ g_object_unref (stmt);
+ g_object_get (G_OBJECT (model), "delete-stmt", &stmt, NULL);
+ str = gda_statement_to_sql (stmt, NULL, NULL);
+ g_print ("Computed DELETE: %s\n", str);
+ g_free (str);
+ g_object_unref (stmt);
+ g_object_get (G_OBJECT (model), "insert-stmt", &stmt, NULL);
+ str = gda_statement_to_sql (stmt, NULL, NULL);
+ g_print ("Computed INSERT: %s\n", str);
+ g_free (str);
+ g_object_unref (stmt);
+
+ /*
+ * remove row 4 (5th row)
+ */
+ g_print ("\n\n** Removing row 0\n");
+ if (! gda_data_model_remove_row (model, 0, &error)) {
+ g_print ("Could not remove row 1: %s\n",
+ error && error->message ? error->message : "No detail");
+ exit (1);
+ }
+ g_print ("** Data model is now:\n");
+ gda_data_model_dump (model, stdout);
+ g_print ("** Table's contents is now:\n");
+ display_customers (cnc);
+
+ /*
+ * add a row: the row's values is a list of GValue pointers
+ * (or NULL pointers where the default value should be inserted
+ */
+ GList *list;
+ g_print ("\n\n** Adding a row\n");
+ list = g_list_append (NULL, NULL);
+ g_value_set_string ((name = gda_value_new (G_TYPE_STRING)), "Hiro");
+ list = g_list_append (list, name);
+ if (! gda_data_model_append_values (model, list, &error)) {
+ g_print ("Could add a row: %s\n",
+ error && error->message ? error->message : "No detail");
+ exit (1);
+ }
+ gda_value_free (name);
+ g_list_free (list);
+ g_print ("** Data model is now:\n");
+ gda_data_model_dump (model, stdout);
+ g_print ("** Table's contents is now:\n");
+ display_customers (cnc);
+
+ /*
+ * alter row 2
+ */
+ g_print ("\n\n** Modifying row 2\n");
+ g_value_set_string ((name = gda_value_new (G_TYPE_STRING)), "Tom");
+ if (! gda_data_model_set_value_at (model, 1, 2, name, &error)) {
+ g_print ("Could not modify row 3: %s\n",
+ error && error->message ? error->message : "No detail");
+ exit (1);
+ }
+ gda_value_free (name);
+ g_print ("** Data model is now:\n");
+ gda_data_model_dump (model, stdout);
+ g_print ("** Table's contents is now:\n");
+ display_customers (cnc);
+
+ /* rollback transaction */
+ gda_connection_rollback_transaction (cnc, NULL, NULL);
+
+ gda_connection_close (cnc);
+
+ return 0;
+}
+
+/*
+ * Open a connection to the example.db file
+ */
+GdaConnection *
+open_connection ()
+{
+ GdaConnection *cnc;
+ GError *error = NULL;
+
+ /* open connection */
+ cnc = gda_connection_open_from_dsn ("SalesTest", NULL,
+ GDA_CONNECTION_OPTIONS_NONE,
+ &error);
+ if (!cnc) {
+ g_print ("Could not open connection: %s\n",
+ error && error->message ? error->message : "No detail");
+ exit (1);
+ }
+
+ /* create an SQL parser */
+ parser = gda_connection_create_parser (cnc);
+ if (!parser) /* @cnc doe snot provide its own parser => use default one */
+ parser = gda_sql_parser_new ();
+ /* attach the parser object to the connection */
+ g_object_set_data_full (G_OBJECT (cnc), "parser", parser, g_object_unref);
+
+ return cnc;
+}
+
+/*
+ * display the contents of the 'products' table
+ */
+void
+display_customers (GdaConnection *cnc)
+{
+ GdaDataModel *data_model;
+ GdaSqlParser *parser;
+ GdaStatement *stmt;
+ gchar *sql = "SELECT id, name FROM customers ORDER BY id";
+ GError *error = NULL;
+
+ parser = g_object_get_data (G_OBJECT (cnc), "parser");
+ stmt = gda_sql_parser_parse_string (parser, sql, NULL, NULL);
+ data_model = gda_connection_statement_execute_select (cnc, stmt, NULL, &error);
+ g_object_unref (stmt);
+ if (!data_model)
+ g_error ("Could not get the contents of the 'products' table: %s\n",
+ error && error->message ? error->message : "No detail");
+ gda_data_model_dump (data_model, stdout);
+ g_object_unref (data_model);
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]