libgda r3217 - in trunk: . doc/C doc/C/tmpl libgda libgda/sqlite providers/postgres providers/skel-implementation/capi tests/data-models tests/value-holders
- From: vivien svn gnome org
- To: svn-commits-list gnome org
- Subject: libgda r3217 - in trunk: . doc/C doc/C/tmpl libgda libgda/sqlite providers/postgres providers/skel-implementation/capi tests/data-models tests/value-holders
- Date: Fri, 26 Sep 2008 19:05:32 +0000 (UTC)
Author: vivien
Date: Fri Sep 26 19:05:32 2008
New Revision: 3217
URL: http://svn.gnome.org/viewvc/libgda?rev=3217&view=rev
Log:
2008-09-26 Vivien Malerba <malerba gnome-db org>
* providers/postgres/gda-postgres-provider.c:
* libgda/sqlite/gda-sqlite-provider.c: code cleanup
* providers/skel-implementation/capi/gda-capi-provider.c: adapted skeleton implementation
to support the GDA_STATEMENT_MODEL_ALLOW_NOPARAM flag
* libgda/gda-holder.c:
- the "g-type" property can now be set after construction, but only if it initially was
GDA_TYPE_NULL
- fixed a bug when the GdaHolder remained invalid even though it was not anymore
* libgda/gda-set.c: indentation correction
* libgda/gda-data-model-iter.c: adjust the GdaHolder's type when the data model
is reset (in case it was GDA_TYPE_NULL)
* tests/: new test cases
* doc/C:
* libgda/gda-connection.c: doc. updates
* libgda/gda-data-proxy.c: made find_or_create_row_modif() static
* libgda/gda-connection.c: made build_downstream_context_templates() and
build_upstream_context_templates() static
* README: point to the COPYING and COPYING.LIB files for the actual GPL and
LGPL text
Added:
trunk/doc/C/data_select.xml
Modified:
trunk/ChangeLog
trunk/NEWS
trunk/README
trunk/doc/C/libgda-4.0-docs.sgml
trunk/doc/C/limitations.xml
trunk/doc/C/tmpl/gda-data-select.sgml
trunk/libgda/gda-connection.c
trunk/libgda/gda-data-model-iter.c
trunk/libgda/gda-data-proxy.c
trunk/libgda/gda-holder.c
trunk/libgda/gda-set.c
trunk/libgda/sqlite/gda-sqlite-provider.c
trunk/providers/postgres/gda-postgres-provider.c
trunk/providers/skel-implementation/capi/gda-capi-provider.c
trunk/tests/data-models/check_pmodel.c
trunk/tests/value-holders/check_holder.c
Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS (original)
+++ trunk/NEWS Fri Sep 26 19:05:32 2008
@@ -1,3 +1,6 @@
+
+ - bug fixes: #508407, #552708
+
libgda 3.99.4, 2008-09-16
This version includes:
Modified: trunk/README
==============================================================================
--- trunk/README (original)
+++ trunk/README Fri Sep 26 19:05:32 2008
@@ -24,6 +24,10 @@
allows for commercial applications to be developed based on libgda. Its
command-line tools are under the GPL.
+See COPYING for the GPL license.
+See COPYING.LIB for the LGPL license.
+
+
Dependencies
------------
To compile libgda, you must have the following packages installed:
Added: trunk/doc/C/data_select.xml
==============================================================================
--- (empty file)
+++ trunk/doc/C/data_select.xml Fri Sep 26 19:05:32 2008
@@ -0,0 +1,107 @@
+<sect1 id="data-select">
+ <title>Advanced GdaDataSelect usage</title>
+ <para>
+ Whenever a SELECT statement is successfully executed (using the <link linkend="GdaConnection">GdaConnection</link>'s methods),
+ a new <link linkend="GdaDataSelect">GdaDataSelect</link> object is created, which can be used as any other
+ <link linkend="GdaDataModel">GdaDataModel</link> object. However this object has some extra features which are
+ described in this section.
+ </para>
+
+ <sect2 id="data-select-rerun">
+ <title>Automatic re-run of the SELECT statement</title>
+ <para>
+ If the SELECT statement which has been executed contained some parameters, then the
+ <link linkend="GdaDataSelect--auto-reset">auto-reset</link> property controls whether the
+ <link linkend="GdaDataSelect">GdaDataSelect</link> object should re-run the SELECT statement
+ to have an up-to-date contents. This feature is disabled by default but can be enabled anytime.
+ </para>
+ <para>
+ For example the following code (errors checking omitted for readability):
+ <programlisting>
+GdaStatement *stmt;
+GdaSqlParser *parser = ...;
+GdaDataModel *model;
+
+stmt = gda_sql_parser_parse_from_string (parser,
+ "SELECT * FROM customers WHERE id <= ##theid::gint",
+ NULL, NULL);
+gda_statement_get_parameters (stmt, &params, NULL);
+gda_set_set_holder_value (params, NULL, "theid", 9);
+model = gda_connection_statement_execute_select (cnc, stmt, params, NULL);
+g_object_set (G_OBJECT (model), "auto-reset", TRUE, NULL);
+g_object_unref (stmt);
+ </programlisting>
+ would create a <link linkend="GdaDataSelect">GdaDataSelect</link> object (the 'model' variable) with the
+ following contents:
+ <programlisting>
+id | name | default_served_by | country | city
+---+----------------+-------------------+---------+-----
+ 2 | Ed Lamton | 4 | SP | MDR
+ 3 | Lew Bonito | 1 | FR | TLS
+ 4 | Mark Lawrencep | | SP | MDR
+ 9 | Greg Popoff | 2 | SP | MDR
+ </programlisting>
+ and with the following changes:
+ <programlisting>
+gda_set_set_holder_value (params, NULL, "theid", 4);
+ </programlisting>
+ the contents of the data model will automatically be set to:
+ <programlisting>
+id | name | default_served_by | country | city
+---+----------------+-------------------+---------+-----
+ 2 | Ed Lamton | 4 | SP | MDR
+ 3 | Lew Bonito | 1 | FR | TLS
+ 4 | Mark Lawrencep | | SP | MDR
+ </programlisting>
+ </para>
+ <para>
+ Important note: with some database providers (such as SQLite), the column's types (if not specified when the statement
+ is run) cannot be determined untill there is a value in the column. This means that a column's type may change
+ over time from the GDA_TYPE_NULL type to its correct type.
+ </para>
+ </sect2>
+
+ <sect2 id="data-select-empty-rs">
+ <title>Invalid parameters</title>
+ <para>
+ If the SELECT statement which has been executed contained some parameters, and if it is not possible to
+ give correct values to the parameters when the data model resulting from the execution of the SELECT must be
+ created, then the execution should fail and no data model should be created (see the
+ <link linkend="gda-connection-statement-execute">gda_connection_statement_execute()</link>'s documentation).
+ However that default behaviour can be changed using the GDA_STATEMENT_MODEL_ALLOW_NOPARAM flag: the returned
+ data model will have no row and will automatically update its contents (re-run the SELECT statement)
+ when parameters are changed.
+ </para>
+ <para>
+ The example above can be modified as follows, note that the value of the 'theid' parameter is not set
+ which makes it invalid:
+ <programlisting>
+ GdaStatement *stmt;
+GdaSqlParser *parser = ...;
+GdaDataModel *model;
+
+stmt = gda_sql_parser_parse_from_string (parser,
+ "SELECT * FROM customers WHERE id <= ##theid::gint",
+ NULL, NULL);
+gda_statement_get_parameters (stmt, &params, NULL);
+model = gda_connection_statement_execute_select_full (cnc, stmt, params,
+ GDA_STATEMENT_MODEL_ALLOW_NOPARAM,
+ NULL, NULL);
+g_object_unref (stmt);
+ </programlisting>
+ The created data model contains no row, and with the following changes:
+ <programlisting>
+gda_set_set_holder_value (params, NULL, "theid", 4);
+ </programlisting>
+ the contents of the data model will automatically be set to:
+ <programlisting>
+id | name | default_served_by | country | city
+---+----------------+-------------------+---------+-----
+ 2 | Ed Lamton | 4 | SP | MDR
+ 3 | Lew Bonito | 1 | FR | TLS
+ 4 | Mark Lawrencep | | SP | MDR
+ </programlisting>
+ </para>
+ </sect2>
+
+</sect1>
Modified: trunk/doc/C/libgda-4.0-docs.sgml
==============================================================================
--- trunk/doc/C/libgda-4.0-docs.sgml (original)
+++ trunk/doc/C/libgda-4.0-docs.sgml Fri Sep 26 19:05:32 2008
@@ -39,6 +39,7 @@
<!ENTITY migration SYSTEM "migration.xml">
<!ENTITY migration2 SYSTEM "migration2.xml">
<!ENTITY data-validation SYSTEM "data_validation.xml">
+<!ENTITY data-select SYSTEM "data_select.xml">
<!ENTITY limitations SYSTEM "limitations.xml">
<!ENTITY libgda-GdaCommand SYSTEM "xml/gda-command.xml">
<!ENTITY libgda-config SYSTEM "xml/gda-config.xml">
@@ -506,7 +507,6 @@
&libgda-GdaSqlParser;
&libgda-GdaStatement;
&libgda-GdaBatch;
- &libgda-GdaDataSelect;
&libgda-GdaHolder;
&libgda-GdaSet;
&libgda-GdaSqlStatement;
@@ -571,8 +571,10 @@
</para>
&libgda-GValue;
&data-validation;
+ &data-select;
&libgda-GdaBlobOp;
&libgda-GdaDataModel;
+ &libgda-GdaDataSelect;
&libgda-GdaColumn;
&libgda-GdaDataModelIter;
&libgda-GdaDataModelImport;
Modified: trunk/doc/C/limitations.xml
==============================================================================
--- trunk/doc/C/limitations.xml (original)
+++ trunk/doc/C/limitations.xml Fri Sep 26 19:05:32 2008
@@ -37,6 +37,16 @@
</para>
</sect2>
+ <sect2><title>Statements execution</title>
+ <para>
+ <itemizedlist>
+ <listitem><para>It is not possible to execute a SELECT statement with invalid parameters and
+ with the GDA_STATEMENT_MODEL_ALLOW_NOPARAM flag as this feature is currently not implemented.
+ </para></listitem>
+ </itemizedlist>
+ </para>
+ </sect2>
+
</sect1>
<sect1 id="limitations_oracle"><title>For Oracle</title>
@@ -84,6 +94,16 @@
connections to be opened from the thread which initializes &LIBGDA;. Otherwise there is no limitation.
</para>
</sect2>
+
+ <sect2><title>Statements execution</title>
+ <para>
+ <itemizedlist>
+ <listitem><para>It is not possible to execute a SELECT statement with invalid parameters and
+ with the GDA_STATEMENT_MODEL_ALLOW_NOPARAM flag if the GDA_STATEMENT_MODEL_CURSOR_FORWARD
+ flag is also specified</para></listitem>
+ </itemizedlist>
+ </para>
+ </sect2>
</sect1>
<sect1 id="limitations_sqlite"><title>For SQLite</title>
Modified: trunk/doc/C/tmpl/gda-data-select.sgml
==============================================================================
--- trunk/doc/C/tmpl/gda-data-select.sgml (original)
+++ trunk/doc/C/tmpl/gda-data-select.sgml Fri Sep 26 19:05:32 2008
@@ -36,7 +36,7 @@
<!-- ##### SECTION See_Also ##### -->
<para>
-
+ The <link linkend="data-select">Advanced GdaDataSelect usage</link> section.
</para>
<!-- ##### SECTION Stability_Level ##### -->
Modified: trunk/libgda/gda-connection.c
==============================================================================
--- trunk/libgda/gda-connection.c (original)
+++ trunk/libgda/gda-connection.c Fri Sep 26 19:05:32 2008
@@ -1550,7 +1550,11 @@
* then the resulting data model will re-run itself, see the GdaDataSelect's
* <link linkend="GdaDataSelect--auto-reset">auto-reset</link> property for more information.
*
- * Also see the <link linkend="limitations">provider's limitations</link> section.
+ * Note4: if @model_usage does not contain the GDA_STATEMENT_MODEL_RANDOM_ACCESS or GDA_STATEMENT_MODEL_CURSOR_FORWARD
+ * flags, then the default will be to return a random access data model
+ *
+ * Also see the <link linkend="limitations">provider's limitations</link>, and the
+ * <link linkend="data-select">Advanced GdaDataSelect usage</link> sections.
*
* Returns: a #GObject, or %NULL if an error occurred
*/
@@ -1997,7 +2001,7 @@
/* builds a list of #GdaMetaContext contexts templates: contexts which have a non NULL table_name,
* and empty or partially filled column names and values specifications */
-GSList *
+static GSList *
build_upstream_context_templates (GdaMetaStore *store, GdaMetaContext *context, GSList *elist, GError **error)
{
GSList *depend_on_contexts;
@@ -2027,7 +2031,7 @@
/* builds a list of #GdaMetaContext contexts templates: contexts which have a non NULL table_name,
* and empty or partially filled column names and values specifications */
-GSList *
+static GSList *
build_downstream_context_templates (GdaMetaStore *store, GdaMetaContext *context, GSList *elist, GError **error)
{
GSList *depending_contexts;
Modified: trunk/libgda/gda-data-model-iter.c
==============================================================================
--- trunk/libgda/gda-data-model-iter.c (original)
+++ trunk/libgda/gda-data-model-iter.c Fri Sep 26 19:05:32 2008
@@ -229,6 +229,22 @@
/* reset the iter to before the 1st row */
gda_data_model_iter_invalidate_contents (iter);
gda_data_model_iter_move_at_row (iter, -1);
+
+ /* adjust GdaHolder's type if a column's type has changed from GDA_TYPE_NULL
+ * to something else */
+ gint i;
+ GSList *list;
+ for (i = 0, list = ((GdaSet*) iter)->holders;
+ list;
+ i++, list = list->next) {
+ if (gda_holder_get_g_type ((GdaHolder *) list->data) == GDA_TYPE_NULL) {
+ GdaColumn *col;
+ col = gda_data_model_describe_column (model, i);
+ if (gda_column_get_g_type (col) != GDA_TYPE_NULL)
+ g_object_set (G_OBJECT (list->data), "g-type",
+ gda_column_get_g_type (col), NULL);
+ }
+ }
}
/*
Modified: trunk/libgda/gda-data-proxy.c
==============================================================================
--- trunk/libgda/gda-data-proxy.c (original)
+++ trunk/libgda/gda-data-proxy.c Fri Sep 26 19:05:32 2008
@@ -1137,13 +1137,13 @@
}
-RowModif *find_or_create_row_modif (GdaDataProxy *proxy, gint proxy_row, gint col, RowValue **ret_rv);
+static RowModif *find_or_create_row_modif (GdaDataProxy *proxy, gint proxy_row, gint col, RowValue **ret_rv);
/*
* Stores the new RowValue in @rv
*/
-RowModif *
+static RowModif *
find_or_create_row_modif (GdaDataProxy *proxy, gint proxy_row, gint col, RowValue **ret_rv)
{
RowModif *rm = NULL;
Modified: trunk/libgda/gda-holder.c
==============================================================================
--- trunk/libgda/gda-holder.c (original)
+++ trunk/libgda/gda-holder.c Fri Sep 26 19:05:32 2008
@@ -226,7 +226,7 @@
g_param_spec_ulong ("g-type", NULL, NULL,
0, G_MAXULONG, GDA_TYPE_NULL,
(G_PARAM_READABLE |
- G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)));
+ G_PARAM_WRITABLE | G_PARAM_CONSTRUCT)));
g_object_class_install_property (object_class, PROP_PLUGIN,
g_param_spec_string ("plugin", NULL, NULL, NULL,
(G_PARAM_READABLE | G_PARAM_WRITABLE)));
@@ -289,8 +289,6 @@
{
GObject *obj;
- g_return_val_if_fail (type != G_TYPE_INVALID, NULL);
-
obj = g_object_new (GDA_TYPE_HOLDER, "g-type", type, NULL);
return (GdaHolder *) obj;
@@ -530,7 +528,10 @@
holder->priv->descr = g_value_dup_string (value);
break;
case PROP_GDA_TYPE:
- holder->priv->g_type = g_value_get_ulong (value);
+ if (holder->priv->g_type == GDA_TYPE_NULL)
+ holder->priv->g_type = g_value_get_ulong (value);
+ else
+ g_warning (_("The 'g-type' property cannot be changed"));
break;
case PROP_PLUGIN:
ptr = g_value_get_string (value);
@@ -901,6 +902,7 @@
if (!do_copy && value)
gda_value_free (value);
holder->priv->invalid_forced = FALSE;
+ holder->priv->valid = newvalid;
return TRUE;
}
Modified: trunk/libgda/gda-set.c
==============================================================================
--- trunk/libgda/gda-set.c (original)
+++ trunk/libgda/gda-set.c Fri Sep 26 19:05:32 2008
@@ -1450,21 +1450,21 @@
retval = FALSE;
}
- if (retval) {
+ if (retval) {
/* signal the holder validate-set */
- GError *lerror = NULL;
+ GError *lerror = NULL;
#ifdef GDA_DEBUG_signal
- g_print (">> 'VALIDATE_SET' from %s\n", __FUNCTION__);
+ g_print (">> 'VALIDATE_SET' from %s\n", __FUNCTION__);
#endif
- g_signal_emit (G_OBJECT (set), gda_set_signals[VALIDATE_SET], 0, &lerror);
+ g_signal_emit (G_OBJECT (set), gda_set_signals[VALIDATE_SET], 0, &lerror);
#ifdef GDA_DEBUG_signal
- g_print ("<< 'VALIDATE_SET' from %s\n", __FUNCTION__);
+ g_print ("<< 'VALIDATE_SET' from %s\n", __FUNCTION__);
#endif
- if (lerror) {
- g_propagate_error (error, lerror);
- retval = FALSE;
+ if (lerror) {
+ g_propagate_error (error, lerror);
+ retval = FALSE;
+ }
}
- }
#ifdef GDA_DEBUG_NO
g_print ("== HOLDER %p: valid= %d, value=%s\n", holders->data, gda_holder_is_valid (GDA_HOLDER (holders->data)),
Modified: trunk/libgda/sqlite/gda-sqlite-provider.c
==============================================================================
--- trunk/libgda/sqlite/gda-sqlite-provider.c (original)
+++ trunk/libgda/sqlite/gda-sqlite-provider.c Fri Sep 26 19:05:32 2008
@@ -1957,14 +1957,12 @@
break;
}
- if (params) {
- h = gda_set_get_holder (params, pname);
- if (!h) {
- gchar *tmp = gda_alphanum_to_text (g_strdup (pname + 1));
- if (tmp) {
- h = gda_set_get_holder (params, tmp);
- g_free (tmp);
- }
+ h = gda_set_get_holder (params, pname);
+ if (!h) {
+ gchar *tmp = gda_alphanum_to_text (g_strdup (pname + 1));
+ if (tmp) {
+ h = gda_set_get_holder (params, tmp);
+ g_free (tmp);
}
}
if (!h) {
Modified: trunk/providers/postgres/gda-postgres-provider.c
==============================================================================
--- trunk/providers/postgres/gda-postgres-provider.c (original)
+++ trunk/providers/postgres/gda-postgres-provider.c Fri Sep 26 19:05:32 2008
@@ -2042,14 +2042,12 @@
break;
}
- if (params) {
- h = gda_set_get_holder (params, pname);
- if (!h) {
- gchar *tmp = gda_alphanum_to_text (g_strdup (pname + 1));
- if (tmp) {
- h = gda_set_get_holder (params, tmp);
- g_free (tmp);
- }
+ h = gda_set_get_holder (params, pname);
+ if (!h) {
+ gchar *tmp = gda_alphanum_to_text (g_strdup (pname + 1));
+ if (tmp) {
+ h = gda_set_get_holder (params, tmp);
+ g_free (tmp);
}
}
if (!h) {
Modified: trunk/providers/skel-implementation/capi/gda-capi-provider.c
==============================================================================
--- trunk/providers/skel-implementation/capi/gda-capi-provider.c (original)
+++ trunk/providers/skel-implementation/capi/gda-capi-provider.c Fri Sep 26 19:05:32 2008
@@ -950,6 +950,9 @@
{
GdaCapiPStmt *ps;
CapiConnectionData *cdata;
+ gboolean allow_noparam;
+ gboolean empty_rs = FALSE; /* TRUE when @allow_noparam is TRUE and there is a problem with @params
+ => resulting data model will be empty (0 row) */
g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
g_return_val_if_fail (gda_connection_get_provider (cnc) == provider, NULL);
@@ -962,6 +965,17 @@
return FALSE;
}
+ if (! (model_usage & GDA_STATEMENT_MODEL_RANDOM_ACCESS) &&
+ ! (model_usage & GDA_STATEMENT_MODEL_CURSOR_FORWARD))
+ model_usage |= GDA_STATEMENT_MODEL_RANDOM_ACCESS;
+
+ allow_noparam = (model_usage & GDA_STATEMENT_MODEL_ALLOW_NOPARAM) &&
+ (gda_statement_get_statement_type (stmt) == GDA_SQL_STATEMENT_SELECT);
+
+ if (last_inserted_row)
+ *last_inserted_row = NULL;
+
+ /* Get private data */
cdata = (CapiConnectionData*) gda_connection_internal_get_provider_data (cnc);
if (!cdata)
return FALSE;
@@ -1014,24 +1028,41 @@
}
}
if (!h) {
- gchar *str;
- str = g_strdup_printf (_("Missing parameter '%s' to execute query"), pname);
- event = gda_connection_event_new (GDA_CONNECTION_EVENT_ERROR);
- gda_connection_event_set_description (event, str);
- g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
- GDA_SERVER_PROVIDER_MISSING_PARAM_ERROR, str);
- g_free (str);
- break;
+ if (! allow_noparam) {
+ gchar *str;
+ str = g_strdup_printf (_("Missing parameter '%s' to execute query"), pname);
+ event = gda_connection_event_new (GDA_CONNECTION_EVENT_ERROR);
+ gda_connection_event_set_description (event, str);
+ g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
+ GDA_SERVER_PROVIDER_MISSING_PARAM_ERROR, str);
+ g_free (str);
+ break;
+ }
+ else {
+ /* bind param to NULL */
+ TO_IMPLEMENT;
+ empty_rs = TRUE;
+ continue;
+ }
+
}
if (!gda_holder_is_valid (h)) {
- gchar *str;
- str = g_strdup_printf (_("Parameter '%s' is invalid"), pname);
- event = gda_connection_event_new (GDA_CONNECTION_EVENT_ERROR);
- gda_connection_event_set_description (event, str);
- g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
- GDA_SERVER_PROVIDER_MISSING_PARAM_ERROR, str);
- g_free (str);
- break;
+ if (! allow_noparam) {
+ gchar *str;
+ str = g_strdup_printf (_("Parameter '%s' is invalid"), pname);
+ event = gda_connection_event_new (GDA_CONNECTION_EVENT_ERROR);
+ gda_connection_event_set_description (event, str);
+ g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
+ GDA_SERVER_PROVIDER_MISSING_PARAM_ERROR, str);
+ g_free (str);
+ break;
+ }
+ else {
+ /* bind param to NULL */
+ TO_IMPLEMENT;
+ empty_rs = TRUE;
+ continue;
+ }
}
/* actual binding using the C API, for parameter at position @i */
@@ -1048,6 +1079,32 @@
event = gda_connection_event_new (GDA_CONNECTION_EVENT_COMMAND);
gda_connection_event_set_description (event, _GDA_PSTMT (ps)->sql);
gda_connection_add_event (cnc, event);
+
+ if (empty_rs) {
+ /* There are some missing parameters, so the SQL can't be executed but we still want
+ * to execute something to get the columns correctly. A possibility is to actually
+ * execute another SQL which is the code shown here.
+ *
+ * To adapt depending on the C API and its features */
+ GdaStatement *estmt;
+ gchar *esql;
+ estmt = gda_select_alter_select_for_empty (stmt, error);
+ if (!estmt)
+ return NULL;
+ esql = gda_statement_to_sql (estmt, NULL, error);
+ g_object_unref (estmt);
+ if (!esql)
+ return NULL;
+
+ /* Execute the 'esql' SQL code */
+ g_free (esql);
+
+ TO_IMPLEMENT;
+ }
+ else {
+ /* Execute the _GDA_PSTMT (ps)->sql SQL code */
+ TO_IMPLEMENT;
+ }
/* execute prepared statement using C API depending on its kind */
if (! g_ascii_strncasecmp (_GDA_PSTMT (ps)->sql, "SELECT", 6) ||
Modified: trunk/tests/data-models/check_pmodel.c
==============================================================================
--- trunk/tests/data-models/check_pmodel.c (original)
+++ trunk/tests/data-models/check_pmodel.c Fri Sep 26 19:05:32 2008
@@ -60,6 +60,7 @@
static gint test14 (GdaConnection *cnc);
static gint test15 (GdaConnection *cnc);
static gint test16 (GdaConnection *cnc);
+static gint test17 (GdaConnection *cnc);
TestFunc tests[] = {
test1,
@@ -77,7 +78,8 @@
test13,
test14,
test15,
- test16
+ test16,
+ test17
};
int
@@ -104,10 +106,9 @@
}
g_object_unref (cnc);
- if (number_failed == 0)
- g_print ("Ok.\n");
- else
- g_print ("%d failed\n", number_failed);
+
+ g_print ("TESTS COUNT: %d\n", i);
+ g_print ("FAILURES: %d\n", number_failed);
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}
@@ -1754,6 +1755,114 @@
return nfailed;
}
+/*
+ * - Create a GdaDataSelect with a missing parameter
+ * - run it to be empty and create an iterator
+ * - set param's value so it refreshes
+ * - make sure the iterator's types are up to date with the data model ones.
+ *
+ * Returns the number of failures
+ */
+static gint
+test17 (GdaConnection *cnc)
+{
+ GError *error = NULL;
+ GdaDataModel *model;
+ GdaStatement *stmt;
+ GdaDataModelIter *iter;
+ GdaSet *params;
+ gint nfailed = 0;
+
+ /* create GdaDataModelQuery */
+ stmt = stmt_from_string ("SELECT * FROM customers WHERE id <= ##theid::gint");
+ g_assert (gda_statement_get_parameters (stmt, ¶ms, NULL));
+
+ model = gda_connection_statement_execute_select_full (cnc, stmt, params, GDA_STATEMENT_MODEL_ALLOW_NOPARAM,
+ NULL, &error);
+ g_assert (model);
+ iter = gda_data_model_create_iter (model);
+
+ gint i, nullcol = -1;
+ GdaColumn *column;
+ GSList *list;
+ for (i = 0, list = ((GdaSet*) iter)->holders;
+ list;
+ i++, list = list->next) {
+ if (gda_holder_get_g_type ((GdaHolder *) list->data) == GDA_TYPE_NULL)
+ nullcol = i;
+ column = gda_data_model_describe_column (model, i);
+ if (gda_holder_get_g_type ((GdaHolder *) list->data) !=
+ gda_column_get_g_type (column)) {
+ nfailed++;
+#ifdef CHECK_EXTRA_INFO
+ g_print ("Iter's GdaHolder for column %d reports the '%s' type when it should be '%s'",
+ nullcol,
+ g_type_name (gda_holder_get_g_type ((GdaHolder *) list->data)),
+ g_type_name (gda_column_get_g_type (column)));
+#endif
+ goto out;
+ }
+ }
+ if (nullcol == -1) {
+#ifdef CHECK_EXTRA_INFO
+ g_print ("Could not find a GDA_TYPE_NULL column, test will be invalid");
+#endif
+ goto out;
+ }
+
+ /**/
+ if (! gda_set_set_holder_value (params, &error, "theid", 9)) {
+ nfailed++;
+#ifdef CHECK_EXTRA_INFO
+ g_print ("Can't set 'theid' value: %s \n",
+ error && error->message ? error->message : "No detail");
+#endif
+ goto out;
+ }
+
+ column = gda_data_model_describe_column (model, nullcol);
+ if (gda_holder_get_g_type ((GdaHolder *) g_slist_nth_data (((GdaSet*) iter)->holders, nullcol)) !=
+ gda_column_get_g_type (column)) {
+ nfailed++;
+#ifdef CHECK_EXTRA_INFO
+ g_print ("Iter's GdaHolder for column %d reports the '%s' type when it should be '%s'",
+ nullcol,
+ g_type_name (gda_holder_get_g_type ((GdaHolder *) g_slist_nth_data (((GdaSet*) iter)->holders,
+ nullcol))),
+ g_type_name (gda_column_get_g_type (column)));
+#endif
+ goto out;
+ }
+
+ /**/
+ if (gda_data_model_iter_is_valid (iter)) {
+ nfailed++;
+#ifdef CHECK_EXTRA_INFO
+ g_print ("Iter should be invalid, and it is at row %d\n",
+ gda_data_model_iter_get_row (iter));
+#endif
+ goto out;
+ }
+ dump_data_model (model);
+ while (gda_data_model_iter_move_next (iter));
+ if (gda_data_model_iter_is_valid (iter)) {
+ nfailed++;
+#ifdef CHECK_EXTRA_INFO
+ g_print ("Iter could not be moved up to the end, and remained 'locked' at row %d\n",
+ gda_data_model_iter_get_row (iter));
+#endif
+ goto out;
+ }
+
+
+ out:
+ g_object_unref (model);
+ g_object_unref (stmt);
+
+ return nfailed;
+}
+
+
static void
dump_data_model (GdaDataModel *model)
{
Modified: trunk/tests/value-holders/check_holder.c
==============================================================================
--- trunk/tests/value-holders/check_holder.c (original)
+++ trunk/tests/value-holders/check_holder.c Fri Sep 26 19:05:32 2008
@@ -31,6 +31,7 @@
static gboolean test8 (GError **error);
static gboolean test9 (GError **error);
static gboolean test10 (GError **error);
+static gboolean test11 (GError **error);
TestFunc tests[] = {
test1,
@@ -42,7 +43,8 @@
test7,
test8,
test9,
- test10
+ test10,
+ test11
};
int
@@ -878,6 +880,59 @@
return TRUE;
}
+static gboolean
+test11 (GError **error)
+{
+ GdaHolder *h;
+ const GValue *cvalue;
+ GValue *value;
+
+ h = gda_holder_new (GDA_TYPE_NULL);
+ emitted_signals_monitor_holder (h);
+
+ /***/
+ value = gda_value_new_from_string ("my string", G_TYPE_STRING);
+ emitted_signals_reset ();
+ if (gda_holder_set_value (h, value, NULL)) {
+ g_set_error (error, 0, 0,
+ "GdaHolder's change should have failed");
+ return FALSE;
+ }
+ gda_value_free (value);
+
+ /***/
+ if (!gda_holder_set_value (h, NULL, error))
+ return FALSE;
+ if (!emitted_signals_find (h, "changed", error))
+ return FALSE;
+ if (!emitted_signals_chech_empty (NULL, "changed", error))
+ return FALSE;
+
+ /***/
+ g_object_set (G_OBJECT (h), "g-type", G_TYPE_STRING, NULL);
+ value = gda_value_new_from_string ("my other string", G_TYPE_STRING);
+ emitted_signals_reset ();
+ if (!gda_holder_set_value (h, value, error))
+ return FALSE;
+ if (!emitted_signals_find (h, "changed", error))
+ return FALSE;
+ if (!emitted_signals_chech_empty (NULL, "changed", error))
+ return FALSE;
+
+ /***/
+ cvalue = gda_holder_get_value (h);
+ if (!cvalue || gda_value_differ (value, cvalue)) {
+ g_set_error (error, 0, 0,
+ "GdaHolder's value is incorrect");
+ return FALSE;
+ }
+ gda_value_free (value);
+
+ g_object_unref (h);
+
+ return TRUE;
+}
+
/*
* Signals testing
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]