libgda r3215 - in trunk: . WixInstaller doc/C doc/C/tmpl libgda libgda/providers-support libgda/sqlite po tests/data-models
- From: vivien svn gnome org
- To: svn-commits-list gnome org
- Subject: libgda r3215 - in trunk: . WixInstaller doc/C doc/C/tmpl libgda libgda/providers-support libgda/sqlite po tests/data-models
- Date: Tue, 23 Sep 2008 18:38:57 +0000 (UTC)
Author: vivien
Date: Tue Sep 23 18:38:57 2008
New Revision: 3215
URL: http://svn.gnome.org/viewvc/libgda?rev=3215&view=rev
Log:
2008-09-23 Vivien Malerba <malerba gnome-db org>
* sqlite/gda-sqlite-recordset.c: correctly handle the situation when the object
is created with col_types specified
* libgda/gda-data-model-iter.c: behave correctly when the data model emits the "reset" signal
* libgda/gda-data-select.[ch]:
- implemented in place re-running the SELECT statement
when on of the SELECT's parameters changes (this feature is optional, use the "auto-reset"
property to activate it), for bug #552708
- other corrections
* libgda/gda-data-model-query.[ch]: removed now redundant object
* tests/data-models/: removed the check_model_query test and added test to check_pmodel
* libgda/gda-data-proxy.c:
* libgda/libgda.h.in: updates due to the removal of the GdaDataModelQuery object
* libgda/gda-data-proxy.c: free'd memory access bug corrected in commit_row_modif()
* WixInstaller/make-zip-exe.sh: updated the generated archive's name
* libgda/providers-support/gda-pstmt.c
* doc/C: documentation updates and improvements
Removed:
trunk/doc/C/tmpl/gda-data-model-query.sgml
trunk/libgda/gda-data-model-query.c
trunk/libgda/gda-data-model-query.h
trunk/tests/data-models/check_model_query.c
Modified:
trunk/ChangeLog
trunk/WixInstaller/make-zip-exe.sh
trunk/doc/C/gda-sql-manual.xml
trunk/doc/C/howto.xml
trunk/doc/C/libgda-4.0-docs.sgml
trunk/doc/C/libgda-4.0-sections.txt
trunk/doc/C/libgda-4.0.types.in
trunk/doc/C/migration2.xml
trunk/doc/C/tmpl/gda-data-select.sgml
trunk/doc/C/tmpl/gda-pstmt.sgml
trunk/libgda/Makefile.am
trunk/libgda/gda-data-model-iter.c
trunk/libgda/gda-data-proxy.c
trunk/libgda/gda-data-select.c
trunk/libgda/libgda.h.in
trunk/libgda/providers-support/gda-pstmt.c
trunk/libgda/sqlite/gda-sqlite-recordset.c
trunk/libgda/sqlite/gda-sqlite-recordset.h
trunk/po/POTFILES.in
trunk/tests/data-models/ (props changed)
trunk/tests/data-models/Makefile.am
trunk/tests/data-models/check_pmodel.c
Modified: trunk/WixInstaller/make-zip-exe.sh
==============================================================================
--- trunk/WixInstaller/make-zip-exe.sh (original)
+++ trunk/WixInstaller/make-zip-exe.sh Tue Sep 23 18:38:57 2008
@@ -17,7 +17,7 @@
cross_path=/fillme
depend_path=/local/Win32
prefix=/fillme
-version=3.99.4
+version=3.99.5
@@ -25,7 +25,7 @@
# no modification below
#
current_dir=`pwd`
-archive=${current_dir}/gda-exe-${version}.zip
+archive=${current_dir}/gda-sql-${version}.zip
# remove current archive if it exists
@@ -101,4 +101,4 @@
#
# The End
#
-echo "Archive written to ${archive}"
\ No newline at end of file
+echo "Archive written to ${archive}"
Modified: trunk/doc/C/gda-sql-manual.xml
==============================================================================
--- trunk/doc/C/gda-sql-manual.xml (original)
+++ trunk/doc/C/gda-sql-manual.xml Tue Sep 23 18:38:57 2008
@@ -365,6 +365,12 @@
cnc1>
</programlisting>
</para>
+ <para>
+ It is possible for any application to create some extra objects in that database for its own purposes, with the
+ constraint that it <emphasis>should not</emphasis> create objects with names starting with an underscore (these
+ names are reserved for &LIBGDA;'s own purposes). In the previous example, the table named "gda_sql_query_buffers"
+ is the table internally used by the console tool to store the contents of named query buffers.
+ </para>
<sect2>
<title>Information about tables</title>
Modified: trunk/doc/C/howto.xml
==============================================================================
--- trunk/doc/C/howto.xml (original)
+++ trunk/doc/C/howto.xml Tue Sep 23 18:38:57 2008
@@ -442,5 +442,24 @@
</para>
</sect1>
+ <sect1>
+ <title>Add your own data to a GdaMetaStore</title>
+ <para>
+ Adding your own data in the <link linkend="GdaMetaStore">GdaMetaStore</link> associated to a connection
+ is a possibility to avoid for example to have another file to store your program-specific data (which
+ you obviously don't want to store in a connection).
+ </para>
+ <para>
+ Doing so is as easy as getting a pointer to the internal connection used by the
+ <link linkend="GdaMetaStore">GdaMetaStore</link> associated the connection, and then use
+ that connection directly as any other connection object.
+ </para>
+ <para>
+ However &LIBGDA; has some specific API to make this easier, described in the
+ <link linkend="GdaMetaStoreCustomData">section about adding custom data</link> to
+ a GdaMetaStore.
+ </para>
+ </sect1>
+
</chapter>
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 Tue Sep 23 18:38:57 2008
@@ -50,7 +50,6 @@
<!ENTITY libgda-GdaDataModelArray SYSTEM "xml/gda-data-model-array.xml">
<!ENTITY libgda-GdaDataModelBdb SYSTEM "xml/gda-data-model-bdb.xml">
<!ENTITY libgda-GdaDataModelDir SYSTEM "xml/gda-data-model-dir.xml">
-<!ENTITY libgda-GdaDataModelQuery SYSTEM "xml/gda-data-model-query.xml">
<!ENTITY libgda-GdaDataModel SYSTEM "xml/gda-data-model.xml">
<!ENTITY libgda-GdaDataModelIter SYSTEM "xml/gda-data-model-iter.xml">
<!ENTITY libgda-GdaDataModelImport SYSTEM "xml/gda-data-model-import.xml">
@@ -584,7 +583,6 @@
&libgda-GdaDataModelDir;
&libgda-GdaDataProxy;
&libgda-GdaDataComparator;
- &libgda-GdaDataModelQuery;
</chapter>
<chapter id="data_conv">
@@ -742,7 +740,8 @@
<sect1 id="GdaMetaStoreCustomData">
<title>Adding custom data</title>
<para>
- This section explains how to add application specific data (custom data) to a #GdaMetaStore object.
+ This section explains how to add application specific data (custom data) to a
+ <link linked="GdaMetaStore">GdaMetaStore</link> object.
</para>
<para>
Applications of course don't need to use that feature to manage their own data but it makes sense to use
@@ -760,16 +759,29 @@
<sect3>
<title>Declaring the new custom database objects</title>
<para>
+ The <link linkend="gda-meta-store-schema-add-custom-object">gda_meta_store_schema_add_custom_object()</link>
+ method canbe used to add custom objects, which have to be described using an XML syntax. The advantages
+ of using that method are:
+ <itemizedlist>
+ <listitem><para>The object's definition will be the same for all database types</para></listitem>
+ <listitem><para>If another object with a different definition already exists, then a error is returned</para></listitem>
+ </itemizedlist>
</para>
</sect3>
<sect3>
<title>Adding and removing data</title>
<para>
+ For the moment adding and removing data must be done as for any other database connection,
+ using the <link linkend="GdaMetaStore's">GdaMetaStore</link>'s internal connection obtained
+ with <link linkend="gda_meta_store_get_internal_connection">gda_meta_store_get_internal_connection()</link>.
</para>
</sect3>
<sect3>
<title>Removing custom database objects</title>
<para>
+ For the moment adding and removing data must be done as for any other database connection,
+ using the <link linkend="GdaMetaStore's">GdaMetaStore</link>'s internal connection obtained
+ with <link linkend="gda_meta_store_get_internal_connection">gda_meta_store_get_internal_connection()</link>.
</para>
</sect3>
<para>
@@ -1025,16 +1037,7 @@
</programlisting>
</para>
<para>
- The &gda-sql; tool uses the following environment variables, when set:
- <itemizedlist>
- <listitem><para>GDA_SQL_CNC: may contain an all-in-one connection string to open upon startup</para></listitem>
- <listitem><para>GDA_NO_PAGER: if set, then no pager will be used</para></listitem>
- <listitem><para>PAGER: if set, indicates which pager program to use (the "more" program is used if not set)</para></listitem>
- <listitem><para>GDA_SQL_EDITOR, EDITOR, VISUAL (by precedence order): if set specifies which editor is used (the "notepad.exe" editor is used on Windows
- platforms or the "vi" on others if not set)</para></listitem>
- <listitem><para>GDA_SQL_VIEWER_PNG: specifies the viewer to use to display graphs (as PNG files)</para></listitem>
- <listitem><para>GDA_SQL_VIEWER_PDF: specifies the viewer to use to display graphs (as PDF files)</para></listitem>
- </itemizedlist>
+ See the <link linkend="gda-sql">Gda SQL console tool manual section</link> for more information.
</para>
</chapter>
Modified: trunk/doc/C/libgda-4.0-sections.txt
==============================================================================
--- trunk/doc/C/libgda-4.0-sections.txt (original)
+++ trunk/doc/C/libgda-4.0-sections.txt Tue Sep 23 18:38:57 2008
@@ -200,30 +200,6 @@
</SECTION>
<SECTION>
-<FILE>gda-data-model-query</FILE>
-<TITLE>GdaDataModelQuery</TITLE>
-GdaDataModelQuery
-GdaDataModelQueryError
-GdaDataModelQueryClass
-GdaDataModelQueryPrivate
-gda_data_model_query_new
-gda_data_model_query_refresh
-gda_data_model_query_set_row_selection_condition
-gda_data_model_query_set_row_selection_condition_sql
-gda_data_model_query_compute_row_selection_condition
-gda_data_model_query_set_modification_statement
-gda_data_model_query_set_modification_statement_sql
-gda_data_model_query_compute_modification_statements
-<SUBSECTION Standard>
-GDA_DATA_MODEL_QUERY
-GDA_DATA_MODEL_QUERY_CLASS
-GDA_IS_DATA_MODEL_QUERY
-GDA_IS_DATA_MODEL_QUERY_CLASS
-GDA_TYPE_DATA_MODEL_QUERY
-gda_data_model_query_get_type
-</SECTION>
-
-<SECTION>
<FILE>gda-data-model-import</FILE>
<TITLE>GdaDataModelImport</TITLE>
GdaDataModelImport
Modified: trunk/doc/C/libgda-4.0.types.in
==============================================================================
--- trunk/doc/C/libgda-4.0.types.in (original)
+++ trunk/doc/C/libgda-4.0.types.in Tue Sep 23 18:38:57 2008
@@ -25,7 +25,6 @@
gda_data_model_get_type
gda_data_model_import_get_type
gda_data_model_iter_get_type
-gda_data_model_query_get_type
gda_data_access_wrapper_get_type
gda_data_proxy_get_type
gda_quark_list_get_type
Modified: trunk/doc/C/migration2.xml
==============================================================================
--- trunk/doc/C/migration2.xml (original)
+++ trunk/doc/C/migration2.xml Tue Sep 23 18:38:57 2008
@@ -157,6 +157,8 @@
<listitem><para>GdaDataModelFilterSQL</para></listitem>
<listitem><para>GdaGraph, GdaGraphItem, GdaGraphQuery</para></listitem>
<listitem><para>GdaGraphviz</para></listitem>
+ <listitem><para>GdaDataModelQuery (features redundant with the
+ <link linkend="GdaDataSelect">GdaDataSelect</link> object) </para></listitem>
</itemizedlist>
</para>
</sect2>
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 Tue Sep 23 18:38:57 2008
@@ -48,6 +48,11 @@
</para>
+<!-- ##### ARG GdaDataSelect:auto-reset ##### -->
+<para>
+
+</para>
+
<!-- ##### ARG GdaDataSelect:connection ##### -->
<para>
Modified: trunk/doc/C/tmpl/gda-pstmt.sgml
==============================================================================
--- trunk/doc/C/tmpl/gda-pstmt.sgml (original)
+++ trunk/doc/C/tmpl/gda-pstmt.sgml Tue Sep 23 18:38:57 2008
@@ -24,6 +24,12 @@
a #GdaStatement object in a connection using
<link linkend="gda-connection-add-prepared-statement">gda_connection_add_prepared_statement()</link>.
</para>
+<para>
+ The #GdaPStmt object can keep a reference to the #GdaStatement object (which can be set and get using
+ the <link linkend="gda-pstmt-set-gda-statement">gda_pstmt_set_gda_statement()</link> and
+ <link linkend="gda-pstmt-get-gda-statement">gda_pstmt_get_gda_statement()</link>), however that reference
+ if a weak one (which means it will be lost if the #GdaStatement object is destroyed).
+</para>
<!-- ##### SECTION See_Also ##### -->
<para>
Modified: trunk/libgda/Makefile.am
==============================================================================
--- trunk/libgda/Makefile.am (original)
+++ trunk/libgda/Makefile.am Tue Sep 23 18:38:57 2008
@@ -44,7 +44,6 @@
gda-data-model-iter.h \
gda-data-model-iter-extra.h \
gda-data-model-private.h \
- gda-data-model-query.h \
gda-data-access-wrapper.h \
gda-data-proxy.h \
gda-data-select.h \
@@ -98,7 +97,6 @@
gda-data-model-dsn-list.h \
gda-data-model-import.c \
gda-data-model-iter.c \
- gda-data-model-query.c \
gda-data-access-wrapper.c \
gda-data-proxy.c \
gda-data-select.c \
Modified: trunk/libgda/gda-data-model-iter.c
==============================================================================
--- trunk/libgda/gda-data-model-iter.c (original)
+++ trunk/libgda/gda-data-model-iter.c Tue Sep 23 18:38:57 2008
@@ -50,6 +50,7 @@
/* follow model changes */
static void model_row_updated_cb (GdaDataModel *model, gint row, GdaDataModelIter *iter);
static void model_row_removed_cb (GdaDataModel *model, gint row, GdaDataModelIter *iter);
+static void model_reset_cb (GdaDataModel *model, GdaDataModelIter *iter);
static GError *validate_holder_change_cb (GdaSet *paramlist, GdaHolder *param, const GValue *new_value);
static void holder_attr_changed_cb (GdaSet *paramlist, GdaHolder *param);
@@ -81,7 +82,7 @@
struct _GdaDataModelIterPrivate
{
GdaDataModel *data_model;
- gulong model_changes_signals[2];
+ gulong model_changes_signals[3];
gboolean keep_param_changes;
gint row; /* -1 if row is unknown */
};
@@ -185,6 +186,7 @@
iter->priv->row = -1;
iter->priv->model_changes_signals[0] = 0;
iter->priv->model_changes_signals[1] = 0;
+ iter->priv->model_changes_signals[2] = 0;
iter->priv->keep_param_changes = FALSE;
}
@@ -221,6 +223,14 @@
}
}
+static void
+model_reset_cb (GdaDataModel *model, GdaDataModelIter *iter)
+{
+ /* reset the iter to before the 1st row */
+ gda_data_model_iter_invalidate_contents (iter);
+ gda_data_model_iter_move_at_row (iter, -1);
+}
+
/*
* This function is called when a parameter in @paramlist is changed
* to make sure the change is propagated to the GdaDataModel
@@ -252,7 +262,7 @@
}
}
else if (! gda_data_model_set_value_at ((GdaDataModel *) iter->priv->data_model,
- col, iter->priv->row, gda_holder_get_value (param), &error)) {
+ col, iter->priv->row, new_value, &error)) {
if (!error)
g_set_error (&error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_ACCESS_ERROR,
_("GdaDataModel refused value change"));
@@ -321,6 +331,7 @@
if (iter->priv->data_model) {
g_signal_handler_disconnect (iter->priv->data_model, iter->priv->model_changes_signals [0]);
g_signal_handler_disconnect (iter->priv->data_model, iter->priv->model_changes_signals [1]);
+ g_signal_handler_disconnect (iter->priv->data_model, iter->priv->model_changes_signals [2]);
g_object_remove_weak_pointer (G_OBJECT (iter->priv->data_model),
(gpointer*) &(iter->priv->data_model));
iter->priv->data_model = NULL;
@@ -496,6 +507,7 @@
return;
g_signal_handler_disconnect (iter->priv->data_model, iter->priv->model_changes_signals [0]);
g_signal_handler_disconnect (iter->priv->data_model, iter->priv->model_changes_signals [1]);
+ g_signal_handler_disconnect (iter->priv->data_model, iter->priv->model_changes_signals [2]);
g_object_remove_weak_pointer (G_OBJECT (iter->priv->data_model),
(gpointer*) &(iter->priv->data_model));
}
@@ -507,6 +519,8 @@
G_CALLBACK (model_row_updated_cb), iter);
iter->priv->model_changes_signals [1] = g_signal_connect (G_OBJECT (ptr), "row-removed",
G_CALLBACK (model_row_removed_cb), iter);
+ iter->priv->model_changes_signals [2] = g_signal_connect (G_OBJECT (ptr), "reset",
+ G_CALLBACK (model_reset_cb), iter);
if (GDA_IS_DATA_SELECT (iter->priv->data_model)) {
GdaStatement *sel_stmt;
Modified: trunk/libgda/gda-data-proxy.c
==============================================================================
--- trunk/libgda/gda-data-proxy.c (original)
+++ trunk/libgda/gda-data-proxy.c Tue Sep 23 18:38:57 2008
@@ -25,7 +25,7 @@
#include "gda-data-model-array.h"
#include "gda-data-model-extra.h"
#include "gda-data-model-iter.h"
-#include "gda-data-model-query.h"
+#include "gda-data-select.h"
#include "gda-holder.h"
#include "gda-set.h"
#include "gda-marshal.h"
@@ -1777,11 +1777,12 @@
commit_row_modif (GdaDataProxy *proxy, RowModif *rm, gboolean adjust_display, GError **error)
{
gboolean err = FALSE;
- gint proxy_row;
+ gint proxy_row, model_row;
GError *lerror = NULL;
if (!rm)
return TRUE;
+ model_row = rm->model_row;
/* ensure that there is no sync to be done */
ensure_chunk_sync (proxy);
@@ -1921,12 +1922,7 @@
gda_data_proxy_signals[ROW_CHANGES_APPLIED],
0, proxy_row, -1);
}
- else if ((proxy->priv->catched_inserted_row < 0) &&
- !GDA_IS_DATA_MODEL_QUERY (proxy->priv->model)) {
- /* REM: the GdaDataModelQuery object does not emit any "row-inserted", "row-updated"
- * or "row_dremoved" signals but that is Ok as an exception: all the other data
- * model should be implemented correctly
- */
+ else if (proxy->priv->catched_inserted_row < 0) {
g_warning (_("Proxied data model reports the modifications as accepted, yet did not emit the "
"corresponding \"row-inserted\", \"row-updated\" or \"row-removed\" signal. This "
"is a bug of the %s's implementation (please report a bug)."),
@@ -1942,22 +1938,16 @@
/* signal row actually changed */
g_signal_emit (G_OBJECT (proxy),
gda_data_proxy_signals[ROW_CHANGES_APPLIED],
- 0, proxy_row, rm->model_row);
+ 0, proxy_row, model_row);
/* get rid of the commited change; if the changes have been applied correctly, @rm should
* have been removed from the proxy->priv->all_modifs list because the proxied model
* should habe emitted the "row_{inserted,removed,updated}" signals */
if (rm && g_slist_find (proxy->priv->all_modifs, rm)) {
- if (!GDA_IS_DATA_MODEL_QUERY (proxy->priv->model)) {
- /* REM: the GdaDataModelQuery object does not emit any "row-inserted", "row-updated"
- * or "row_dremoved" signals but that is Ok as an exception: all the other data
- * model should be implemented correctly
- */
- g_warning (_("Proxied data model reports the modifications as accepted, yet did not emit the "
- "corresponding \"row-inserted\", \"row-updated\" or \"row-removed\" signal. This "
- "is a bug of the %s's implementation (please report a bug)."),
- G_OBJECT_TYPE_NAME (proxy->priv->model));
- }
+ g_warning (_("Proxied data model reports the modifications as accepted, yet did not emit the "
+ "corresponding \"row-inserted\", \"row-updated\" or \"row-removed\" signal. This "
+ "is a bug of the %s's implementation (please report a bug)."),
+ G_OBJECT_TYPE_NAME (proxy->priv->model));
proxy->priv->new_rows = g_slist_remove (proxy->priv->new_rows, rm);
proxy->priv->all_modifs = g_slist_remove (proxy->priv->all_modifs, rm);
g_hash_table_remove (proxy->priv->modify_rows, GINT_TO_POINTER (rm->model_row));
@@ -3518,10 +3508,6 @@
return FALSE;
}
-#ifdef GDA_DEBUG_NO
- gda_object_dump (proxy, 5);
-#endif
-
return TRUE;
}
Modified: trunk/libgda/gda-data-select.c
==============================================================================
--- trunk/libgda/gda-data-select.c (original)
+++ trunk/libgda/gda-data-select.c Tue Sep 23 18:38:57 2008
@@ -72,6 +72,9 @@
gint iter_row; /* G_MININT if at start, G_MAXINT if at end, "external" row number */
GdaDataModelIter *iter;
+ GdaStatement *sel_stmt;
+ GdaSet *ext_params;
+ gboolean reset_with_ext_params_change;
GdaDataModelAccessFlags usage_flags;
/* attributes specific to data model modifications */
@@ -95,7 +98,8 @@
PROP_INS_QUERY,
PROP_UPD_QUERY,
PROP_DEL_QUERY,
- PROP_SEL_STMT
+ PROP_SEL_STMT,
+ PROP_RESET_WITH_EXT_PARAM
};
/* module error */
@@ -132,6 +136,8 @@
static GdaStatement *compute_single_select_stmt (GdaDataSelect *model, GError **error);
static gint *compute_insert_select_params_mapping (GdaSet *sel_params, GdaSet *ins_values, GdaSqlExpr *row_cond);
+static void ext_params_holder_changed_cb (GdaSet *paramlist, GdaHolder *param, GdaDataSelect *model);
+
/* GdaDataModel interface */
static void gda_data_select_data_model_init (GdaDataModelClass *iface);
@@ -253,6 +259,12 @@
"SELECT statement which was executed to yield to the data model",
GDA_TYPE_STATEMENT, G_PARAM_READABLE));
+ g_object_class_install_property (object_class, PROP_RESET_WITH_EXT_PARAM,
+ g_param_spec_boolean ("auto-reset", "Automatically reset itself",
+ "Automatically re-run the SELECT statement if any parameter "
+ "has chanegd since it was first executed", FALSE,
+ G_PARAM_READABLE | G_PARAM_WRITABLE));
+
/* virtual functions */
object_class->dispose = gda_data_select_dispose;
object_class->finalize = gda_data_select_finalize;
@@ -297,8 +309,13 @@
model->priv->index = g_hash_table_new (g_direct_hash, g_direct_equal);
model->prep_stmt = NULL;
model->priv->columns = NULL;
+ model->nb_stored_rows = 0;
model->advertized_nrows = -1; /* unknown number of rows */
+ model->priv->sel_stmt = NULL;
+ model->priv->ext_params = NULL;
+ model->priv->reset_with_ext_params_change = FALSE;
+
model->priv->iter_row = G_MININT;
model->priv->iter = NULL;
@@ -319,6 +336,94 @@
}
static void
+ext_params_holder_changed_cb (GdaSet *paramlist, GdaHolder *param, GdaDataSelect *model)
+{
+ if (model->priv->reset_with_ext_params_change) {
+ GdaDataSelect *new_model;
+ GdaStatement *select;
+ GError *error = NULL;
+
+ select = check_acceptable_statement (model, &error);
+ if (!select) {
+ g_warning (_("Could not re-run SELECT statement: %s"),
+ error && error->message ? error->message : _("No detail"));
+ if (error)
+ g_error_free (error);
+ return;
+ }
+ g_assert (model->prep_stmt);
+ GType *types = NULL;
+ if (model->prep_stmt->types) {
+ types = g_new (GType, model->prep_stmt->ncols + 1);
+ memcpy (types, model->prep_stmt->types, sizeof (GType) * model->prep_stmt->ncols);
+ types [model->prep_stmt->ncols] = G_TYPE_NONE;
+ }
+ new_model = (GdaDataSelect*) gda_connection_statement_execute_select_full (model->priv->cnc, select,
+ model->priv->ext_params,
+ model->priv->usage_flags,
+ types,
+ &error);
+ g_free (types);
+ if (!new_model) {
+ g_warning (_("Could not re-run SELECT statement: %s"),
+ error && error->message ? error->message : _("No detail"));
+ if (error)
+ g_error_free (error);
+ return;
+ }
+
+ g_assert (G_OBJECT_TYPE (model) == G_OBJECT_TYPE (new_model));
+
+ /* Raw model and new_model contents swap (except for the GObject part) */
+ GTypeQuery tq;
+ gpointer copy;
+ gint offset = sizeof (GObject);
+ gint size;
+ g_type_query (G_OBJECT_TYPE (model), &tq);
+ size = tq.instance_size - offset;
+ copy = g_malloc (size);
+ memcpy (copy, (gint8*) new_model + offset, size);
+ memcpy ((gint8*) new_model + offset, (gint8*) model + offset, size);
+ memcpy ((gint8*) model + offset, copy, size);
+
+ /* we need to keep some data from the old model */
+ GdaDataSelect *old_model = new_model; /* renamed for code's readability */
+ GdaDataSelectInternals *mi;
+
+ model->priv->reset_with_ext_params_change = old_model->priv->reset_with_ext_params_change;
+ mi = old_model->priv->modif_internals;
+ old_model->priv->modif_internals = model->priv->modif_internals;
+ model->priv->modif_internals = mi;
+
+ copy = old_model->priv->sel_stmt;
+ old_model->priv->sel_stmt = model->priv->sel_stmt;
+ model->priv->sel_stmt = (GdaStatement*) copy;
+
+ g_object_unref (old_model);
+
+ /* copy all the param's holders' values from model->priv->ext_params to
+ to model->priv->modif_internals->exec_set */
+ GSList *list;
+ for (list = model->priv->ext_params->holders; list; list = list->next) {
+ GdaHolder *h;
+ h = gda_set_get_holder (model->priv->modif_internals->exec_set,
+ gda_holder_get_id (list->data));
+ if (h)
+ if (! gda_holder_set_value (h, gda_holder_get_value (GDA_HOLDER (list->data)), &error)) {
+ g_warning (_("An error has occurred, the value returned by the \"exec-params\" "
+ "property will be wrong: %s"),
+ error && error->message ? error->message : _("No detail"));
+ if (error)
+ g_error_free (error);
+ }
+ }
+
+ /* signal a reset */
+ gda_data_model_reset ((GdaDataModel*) model);
+ }
+}
+
+static void
gda_data_select_dispose (GObject *object)
{
GdaDataSelect *model = (GdaDataSelect *) object;
@@ -329,6 +434,18 @@
if (model->priv) {
gint i;
+ if (model->priv->sel_stmt) {
+ g_object_unref (model->priv->sel_stmt);
+ model->priv->sel_stmt = NULL;
+ }
+
+ if (model->priv->ext_params) {
+ g_signal_handlers_disconnect_by_func (model->priv->ext_params,
+ G_CALLBACK (ext_params_holder_changed_cb), model);
+ g_object_unref (model->priv->ext_params);
+ model->priv->ext_params = NULL;
+ }
+
if (model->priv->modif_internals) {
_gda_data_select_internals_free (model->priv->modif_internals);
model->priv->modif_internals = NULL;
@@ -513,8 +630,14 @@
if (model->prep_stmt)
g_object_unref (model->prep_stmt);
model->prep_stmt = g_value_get_object (value);
- if (model->prep_stmt)
+ if (model->prep_stmt) {
+ GdaStatement *sel_stmt;
g_object_ref (model->prep_stmt);
+ sel_stmt = gda_pstmt_get_gda_statement (model->prep_stmt);
+ if (sel_stmt &&
+ gda_statement_get_statement_type (sel_stmt) == GDA_SQL_STATEMENT_SELECT)
+ model->priv->sel_stmt = gda_statement_copy (sel_stmt);
+ }
create_columns (model);
break;
case PROP_FLAGS: {
@@ -539,8 +662,12 @@
case PROP_PARAMS: {
GdaSet *set;
set = g_value_get_object (value);
- if (set)
+ if (set) {
+ model->priv->ext_params = g_object_ref (set);
+ g_signal_connect (model->priv->ext_params, "holder-changed",
+ G_CALLBACK (ext_params_holder_changed_cb), model);
model->priv->modif_internals->exec_set = gda_set_copy (set);
+ }
break;
}
case PROP_INS_QUERY:
@@ -564,6 +691,9 @@
if (model->priv->modif_internals->modif_stmts [UPD_QUERY])
g_object_ref (model->priv->modif_internals->modif_stmts [UPD_QUERY]);
break;
+ case PROP_RESET_WITH_EXT_PARAM:
+ model->priv->reset_with_ext_params_change = g_value_get_boolean (value);
+ break;
default:
break;
}
@@ -612,6 +742,9 @@
case PROP_SEL_STMT:
g_value_set_object (value, check_acceptable_statement (model, NULL));
break;
+ case PROP_RESET_WITH_EXT_PARAM:
+ g_value_set_boolean (value, model->priv->reset_with_ext_params_change);
+ break;
default:
break;
}
@@ -808,6 +941,10 @@
check_acceptable_statement (GdaDataSelect *model, GError **error)
{
GdaStatement *sel_stmt;
+
+ if (model->priv->sel_stmt)
+ return model->priv->sel_stmt;
+
if (! model->prep_stmt) {
g_set_error (error, GDA_DATA_SELECT_ERROR, GDA_DATA_SELECT_MODIFICATION_STATEMENT_ERROR,
_("Internal error: the \"prepared-stmt\" property has not been set"));
@@ -817,7 +954,7 @@
sel_stmt = gda_pstmt_get_gda_statement (model->prep_stmt);
if (! sel_stmt) {
g_set_error (error, GDA_DATA_SELECT_ERROR, GDA_DATA_SELECT_MODIFICATION_STATEMENT_ERROR,
- _("Internal error: can't get the prepared statement's actual statement"));
+ _("Can't get the prepared statement's actual statement"));
return NULL;
}
@@ -827,7 +964,8 @@
return NULL;
}
- return sel_stmt;
+ model->priv->sel_stmt = gda_statement_copy (sel_stmt);
+ return model->priv->sel_stmt;
}
/**
@@ -2020,13 +2158,7 @@
GdaSqlStatement *sel_sqlst;
GdaSqlExpr *row_cond = NULL;
- if (! model->prep_stmt) {
- g_set_error (error, GDA_DATA_SELECT_ERROR, GDA_DATA_SELECT_MODIFICATION_STATEMENT_ERROR,
- _("Internal error: the \"prepared-stmt\" property has not been set"));
- return NULL;
- }
-
- sel_stmt = gda_pstmt_get_gda_statement (model->prep_stmt);
+ sel_stmt = model->priv->sel_stmt;
if (! sel_stmt) {
g_set_error (error, GDA_DATA_SELECT_ERROR, GDA_DATA_SELECT_MODIFICATION_STATEMENT_ERROR,
_("Internal error: can't get the prepared statement's actual statement"));
@@ -2481,9 +2613,9 @@
ncols = gda_data_select_get_n_columns (model);
nvalues = g_list_length (values);
- if (nvalues >= ncols) {
+ if (nvalues > ncols) {
g_set_error (error, GDA_DATA_SELECT_ERROR, GDA_DATA_SELECT_MISSING_MODIFICATION_STATEMENT_ERROR,
- _("Too many values (%d as maximum)"), ncols-1);
+ _("Too many values (%d as maximum)"), ncols);
return FALSE;
}
Modified: trunk/libgda/libgda.h.in
==============================================================================
--- trunk/libgda/libgda.h.in (original)
+++ trunk/libgda/libgda.h.in Tue Sep 23 18:38:57 2008
@@ -35,7 +35,6 @@
#include <libgda/gda-data-comparator.h>
#include <libgda/gda-data-model-array.h>
@LIBGDA_BDB_INC@
-#include <libgda/gda-data-model-query.h>
#include <libgda/gda-data-model.h>
#include <libgda/gda-data-model-iter.h>
#include <libgda/gda-data-model-import.h>
Modified: trunk/libgda/providers-support/gda-pstmt.c
==============================================================================
--- trunk/libgda/providers-support/gda-pstmt.c (original)
+++ trunk/libgda/providers-support/gda-pstmt.c Tue Sep 23 18:38:57 2008
@@ -215,7 +215,10 @@
* gda_pstmt_get_gda_statement
* @pstmt: a #GdaPStmt object
*
- * Get a pointer to the #GdaStatement which led to the creation of this prepared statement
+ * Get a pointer to the #GdaStatement which led to the creation of this prepared statement.
+ *
+ * Note: if that statement has been modified since the creation of @pstmt, then this method
+ * will return %NULL
*
* Returns: the #GdaStatement
*/
Modified: trunk/libgda/sqlite/gda-sqlite-recordset.c
==============================================================================
--- trunk/libgda/sqlite/gda-sqlite-recordset.c (original)
+++ trunk/libgda/sqlite/gda-sqlite-recordset.c Tue Sep 23 18:38:57 2008
@@ -222,7 +222,7 @@
if (i >= _GDA_PSTMT (ps)->ncols)
g_warning (_("Column %d out of range (0-%d), ignoring its specified type"), i,
_GDA_PSTMT (ps)->ncols - 1);
- else
+ else
_GDA_PSTMT (ps)->types [i] = col_types [i];
}
}
@@ -238,6 +238,8 @@
gda_column_set_title (column, sqlite3_column_name (ps->sqlite_stmt, i));
gda_column_set_name (column, sqlite3_column_name (ps->sqlite_stmt, i));
gda_column_set_dbms_type (column, sqlite3_column_decltype (ps->sqlite_stmt, i));
+ if (_GDA_PSTMT (ps)->types [i] != GDA_TYPE_NULL)
+ gda_column_set_g_type (column, _GDA_PSTMT (ps)->types [i]);
}
}
Modified: trunk/libgda/sqlite/gda-sqlite-recordset.h
==============================================================================
--- trunk/libgda/sqlite/gda-sqlite-recordset.h (original)
+++ trunk/libgda/sqlite/gda-sqlite-recordset.h Tue Sep 23 18:38:57 2008
@@ -44,7 +44,7 @@
struct _GdaSqliteRecordset {
GdaDataSelect model;
- GdaSqliteRecordsetPrivate *priv;
+ GdaSqliteRecordsetPrivate *priv;
};
struct _GdaSqliteRecordsetClass {
Modified: trunk/po/POTFILES.in
==============================================================================
--- trunk/po/POTFILES.in (original)
+++ trunk/po/POTFILES.in Tue Sep 23 18:38:57 2008
@@ -11,7 +11,6 @@
libgda/gda-data-model-dsn-list.c
libgda/gda-data-model-import.c
libgda/gda-data-model-iter.c
-libgda/gda-data-model-query.c
libgda/gda-data-proxy.c
libgda/gda-data-select.c
libgda/gda-easy.c
Modified: trunk/tests/data-models/Makefile.am
==============================================================================
--- trunk/tests/data-models/Makefile.am (original)
+++ trunk/tests/data-models/Makefile.am Tue Sep 23 18:38:57 2008
@@ -7,8 +7,8 @@
-DTOP_SRC_DIR=\""$(top_srcdir)"\" \
-DTOP_BUILD_DIR=\""$(top_builddir)"\"
-check_PROGRAMS = check_model_import check_virtual check_data_proxy check_model_copy check_pmodel check_model_query
-TESTS = check_model_import check_virtual check_data_proxy check_model_copy check_pmodel check_model_query
+check_PROGRAMS = check_model_import check_virtual check_data_proxy check_model_copy check_pmodel
+TESTS = check_model_import check_virtual check_data_proxy check_model_copy check_pmodel
common_sources =
@@ -43,14 +43,6 @@
$(top_builddir)/tests/libgda-test-4.0.la \
$(LIBGDA_LIBS)
-check_model_query_SOURCES = $(common_sources) check_model_query.c
-check_model_query_CFLAGS = \
- -I$(top_srcdir)/libgda/sqlite
-check_model_query_LDADD = \
- $(top_builddir)/libgda/libgda-4.0.la \
- $(top_builddir)/tests/libgda-test-4.0.la \
- $(LIBGDA_LIBS)
-
EXTRA_DIST = \
check_virtual.csv \
city.csv \
@@ -61,4 +53,4 @@
pmodel_data_locations.xml
CLEANFILES = \
- pmodel.db modelquery.db pmodel.db-journal modelquery.db-journal
+ pmodel.db pmodel.db-journal
Modified: trunk/tests/data-models/check_pmodel.c
==============================================================================
--- trunk/tests/data-models/check_pmodel.c (original)
+++ trunk/tests/data-models/check_pmodel.c Tue Sep 23 18:38:57 2008
@@ -22,10 +22,10 @@
} SigEvent;
static GSList *signals = NULL;
static void monitor_model_signals (GdaDataModel *model);
-static void signal_callback (GdaDataModel *model, gint row, gchar *type);
static void clear_signals (void);
static gboolean check_expected_signal (GdaDataModel *model, gchar type, gint row);
static gboolean check_no_expected_signal (GdaDataModel *model);
+static gboolean compare_data_models (GdaDataModel *model1, GdaDataModel *model2, GError **error);
/* utility functions */
static GdaConnection *setup_connection (void);
@@ -57,9 +57,10 @@
static gint test12 (GdaConnection *cnc);
static gint test13 (GdaConnection *cnc);
static gint test14 (GdaConnection *cnc);
+static gint test15 (GdaConnection *cnc);
TestFunc tests[] = {
- test1,
+ test1,
test2,
test3,
test4,
@@ -72,7 +73,8 @@
test11,
test12,
test13,
- test14
+ test14,
+ test15
};
int
@@ -1554,6 +1556,84 @@
}
/*
+ * - Create a GdaDataSelect with a missing parameter
+ * - Set modification statements
+ * - Refresh data model and compare with direct SELECT.
+ *
+ * Returns the number of failures
+ */
+static gint
+test15 (GdaConnection *cnc)
+{
+ GError *error = NULL;
+ GdaDataModel *model, *rerun;
+ GdaStatement *stmt;
+ GdaSet *params;
+ gint nfailed = 0;
+
+ clear_signals ();
+
+ /* create GdaDataModelQuery */
+ stmt = stmt_from_string ("SELECT * FROM customers WHERE id <= ##theid::gint");
+ g_assert (gda_statement_get_parameters (stmt, ¶ms, NULL));
+
+ 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;
+ }
+ model = gda_connection_statement_execute_select (cnc, stmt, params, &error);
+ g_assert (model);
+
+ monitor_model_signals (model);
+
+ /**/
+ g_object_set_data (G_OBJECT (model), "mydata", "hey");
+
+ /**/
+ g_object_set (G_OBJECT (model), "auto-reset", TRUE, NULL);
+ if (! gda_set_set_holder_value (params, &error, "theid", 3)) {
+ nfailed++;
+#ifdef CHECK_EXTRA_INFO
+ g_print ("Can't set 'theid' value: %s \n",
+ error && error->message ? error->message : "No detail");
+#endif
+ goto out;
+ }
+ check_expected_signal (model, 'R', -1);
+
+ const gchar *dstr = g_object_get_data (G_OBJECT (model), "mydata");
+ if (!dstr || strcmp (dstr, "hey")) {
+ nfailed++;
+#ifdef CHECK_EXTRA_INFO
+ g_print ("Data model lost custom added data: expected 'hey' and got '%s'\n",
+ dstr);
+#endif
+ goto out;
+ }
+
+ rerun = gda_connection_statement_execute_select (cnc, stmt, params, &error);
+ g_assert (rerun);
+ if (! compare_data_models (model, rerun, NULL)) {
+ nfailed++;
+#ifdef CHECK_EXTRA_INFO
+ g_print ("Data model differs after a refresh\n");
+#endif
+ goto out;
+ }
+ g_object_unref (rerun);
+
+ out:
+ g_object_unref (model);
+ g_object_unref (stmt);
+
+ return nfailed;
+}
+
+/*
* Checking value function:
* - reads the value of @model at the provided column and row and compares with the expected @set_value
* - if @stmt is not NULL, then re-run the statement and compares with @model
@@ -1826,14 +1906,6 @@
* signals checking
*/
static void
-monitor_model_signals (GdaDataModel *model)
-{
- g_signal_connect (model, "row-updated", G_CALLBACK (signal_callback), "U");
- g_signal_connect (model, "row-removed", G_CALLBACK (signal_callback), "D");
- g_signal_connect (model, "row-inserted", G_CALLBACK (signal_callback), "I");
-}
-
-static void
signal_callback (GdaDataModel *model, gint row, gchar *type)
{
SigEvent *se;
@@ -1850,6 +1922,32 @@
}
static void
+signal_callback_1 (GdaDataModel *model, gchar *type)
+{
+ SigEvent *se;
+ se = g_new0 (SigEvent, 1);
+ se->model = model;
+ se->type = *type;
+ se->row = -1;
+ signals = g_slist_append (signals, se);
+#ifdef CHECK_EXTRA_INFO
+ g_print ("Received '%s' signal from model %p\n",
+ *type == 'R' ? "reset" : "???",
+ model);
+#endif
+}
+
+static void
+monitor_model_signals (GdaDataModel *model)
+{
+ g_signal_connect (model, "row-updated", G_CALLBACK (signal_callback), "U");
+ g_signal_connect (model, "row-removed", G_CALLBACK (signal_callback), "D");
+ g_signal_connect (model, "row-inserted", G_CALLBACK (signal_callback), "I");
+ g_signal_connect (model, "reset", G_CALLBACK (signal_callback_1), "R");
+}
+
+
+static void
clear_signals (void)
{
if (signals) {
@@ -1876,13 +1974,48 @@
}
#ifdef CHECK_EXTRA_INFO
else {
- g_print ("Expected signal '%s' for row %d from model %p and got ",
- (type == 'I') ? "row-inserted" : ((type == 'D') ? "row-removed" : "row-updated"),
+ gchar *exp;
+ switch (type) {
+ case 'I':
+ exp = "row-inserted";
+ break;
+ case 'U':
+ exp = "row-updated";
+ break;
+ case 'D':
+ exp = "row-removed";
+ break;
+ case 'R':
+ exp = "reset";
+ break;
+ default:
+ exp = "???";
+ break;
+ }
+ g_print ("Expected signal '%s' for row %d from model %p and got ", exp,
row, model);
- if (se)
+ if (se) {
+ switch (se->type) {
+ case 'I':
+ exp = "row-inserted";
+ break;
+ case 'U':
+ exp = "row-updated";
+ break;
+ case 'D':
+ exp = "row-removed";
+ break;
+ case 'R':
+ exp = "reset";
+ break;
+ default:
+ exp = "???";
+ break;
+ }
g_print ("signal '%s' for row %d from model %p\n",
- (se->type == 'I') ? "row-inserted" : ((se->type == 'D') ? "row-removed" : "row-updated"),
+ exp,
se->row, se->model);
+ }
else
g_print ("no signal\n");
}
@@ -1912,3 +2045,41 @@
return TRUE;
}
+
+static gboolean
+compare_data_models (GdaDataModel *model1, GdaDataModel *model2, GError **error)
+{
+ GdaDataComparator *cmp;
+ GError *lerror = NULL;
+ cmp = (GdaDataComparator*) gda_data_comparator_new (model1, model2);
+ if (! gda_data_comparator_compute_diff (cmp, &lerror)) {
+#ifdef CHECK_EXTRA_INFO
+ g_print ("Could not compute the data model differences: %s\n",
+ lerror && lerror->message ? lerror->message : "No detail");
+ g_print ("Model1 is:\n");
+ gda_data_model_dump (model1, stdout);
+ g_print ("Model2 is:\n");
+ gda_data_model_dump (model2, stdout);
+#endif
+ goto onerror;
+ }
+ if (gda_data_comparator_get_n_diffs (cmp) != 0) {
+#ifdef CHECK_EXTRA_INFO
+ g_print ("There are some differences when comparing data models...\n");
+ g_print ("Model1 is:\n");
+ gda_data_model_dump (model1, stdout);
+ g_print ("Model2 is:\n");
+ gda_data_model_dump (model2, stdout);
+#endif
+ g_set_error (&lerror, 0, 0,
+ "There are some differences when comparing data models...");
+ goto onerror;
+ }
+ g_object_unref (cmp);
+
+ return TRUE;
+
+ onerror:
+ g_propagate_error (error, lerror);
+ return FALSE;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]