libgda r3211 - in trunk: . doc/C doc/C/tmpl libgda libgda/sqlite tests/data-models tools
- From: vivien svn gnome org
- To: svn-commits-list gnome org
- Subject: libgda r3211 - in trunk: . doc/C doc/C/tmpl libgda libgda/sqlite tests/data-models tools
- Date: Thu, 18 Sep 2008 18:52:53 +0000 (UTC)
Author: vivien
Date: Thu Sep 18 18:52:53 2008
New Revision: 3211
URL: http://svn.gnome.org/viewvc/libgda?rev=3211&view=rev
Log:
2008-09-18 Vivien Malerba <malerba gnome-db org>
* libgda/gda-data-model.c: make gda_data_model_dump() work whith data models which
can only be accessed with a cursor
* libgda/gda-meta-store.c: handle the 'autoinc' column attribute, and bug fixes
* libgda/sqlite/gda-sqlite-ddl.c: correctly handle the "INTEGER PRIMARY KEY AUTOINCREMENT"
* doc/C: better documentation for GdaDataProxy
* tools/gda-sql.c:
- allow to pass a file name on the command line to open as an SQLite or MDB file
- reorganized "query buffer" commands:
- \e [FILE]: Edit the query buffer (or file) with external editor
- \g [QUERY_BUFFER_NAME]: Execute contents of query buffer, or named query buffer
- \qa: List all saved query buffers in dictionary
- \qd QUERY_BUFFER_NAME: Delete query buffer from dictionary
- \ql QUERY_BUFFER_NAME: Load query buffer from dictionary
- \qp: Show the contents of the query buffer
- \qr [FILE]: Reset the query buffer (fill buffer with contents of file)
- \qs QUERY_BUFFER_NAME: Save query buffer to dictionary
- \qw FILE: Write query buffer to file
* tests/data-models/check_pmodel.c: more testing
Added:
trunk/doc/C/data_proxy1.dia (contents, props changed)
trunk/doc/C/data_proxy1.png (contents, props changed)
trunk/doc/C/data_proxy2.dia (contents, props changed)
trunk/doc/C/data_proxy2.png (contents, props changed)
trunk/doc/C/data_proxy3.dia (contents, props changed)
trunk/doc/C/data_proxy3.png (contents, props changed)
trunk/doc/C/data_proxy4.dia (contents, props changed)
trunk/doc/C/data_proxy4.png (contents, props changed)
trunk/doc/C/data_proxy5.dia (contents, props changed)
trunk/doc/C/data_proxy5.png (contents, props changed)
trunk/doc/C/gda-sql-graph.png (contents, props changed)
Modified:
trunk/ChangeLog
trunk/doc/C/Makefile.am
trunk/doc/C/gda-sql-manual.xml
trunk/doc/C/libgda-4.0-docs.sgml
trunk/doc/C/tmpl/gda-data-proxy.sgml
trunk/libgda/gda-data-model.c
trunk/libgda/gda-meta-store.c
trunk/libgda/sqlite/gda-sqlite-ddl.c
trunk/tests/data-models/check_pmodel.c
trunk/tools/gda-sql.c
Modified: trunk/doc/C/Makefile.am
==============================================================================
--- trunk/doc/C/Makefile.am (original)
+++ trunk/doc/C/Makefile.am Thu Sep 18 18:52:53 2008
@@ -51,7 +51,9 @@
stmt-update.png stmt-compound.png information_schema.png \
MetaStore1.png MetaStore2.png i_s_data_types.png \
writable_data_model.png GdaDataModelIter.png \
- data_validation_holder.png data_validation_proxy.png data_validation_set.png
+ data_validation_holder.png data_validation_proxy.png data_validation_set.png \
+ data_proxy1.png data_proxy2.png data_proxy3.png data_proxy4.png data_proxy5.png \
+ gda-sql-graph.png
# Extra options to supply to gtkdoc-fixref
FIXXREF_OPTIONS=
Added: trunk/doc/C/data_proxy1.dia
==============================================================================
Binary file. No diff available.
Added: trunk/doc/C/data_proxy1.png
==============================================================================
Binary file. No diff available.
Added: trunk/doc/C/data_proxy2.dia
==============================================================================
Binary file. No diff available.
Added: trunk/doc/C/data_proxy2.png
==============================================================================
Binary file. No diff available.
Added: trunk/doc/C/data_proxy3.dia
==============================================================================
Binary file. No diff available.
Added: trunk/doc/C/data_proxy3.png
==============================================================================
Binary file. No diff available.
Added: trunk/doc/C/data_proxy4.dia
==============================================================================
Binary file. No diff available.
Added: trunk/doc/C/data_proxy4.png
==============================================================================
Binary file. No diff available.
Added: trunk/doc/C/data_proxy5.dia
==============================================================================
Binary file. No diff available.
Added: trunk/doc/C/data_proxy5.png
==============================================================================
Binary file. No diff available.
Added: trunk/doc/C/gda-sql-graph.png
==============================================================================
Binary file. No diff available.
Modified: trunk/doc/C/gda-sql-manual.xml
==============================================================================
--- trunk/doc/C/gda-sql-manual.xml (original)
+++ trunk/doc/C/gda-sql-manual.xml Thu Sep 18 18:52:53 2008
@@ -96,9 +96,14 @@
</itemizedlist>
</para>
<para>
- Connections to be opened can be specified on the command line using either defined data
- sources (the ones listed using the <option>-l</option> option), or using connection strings
- which have the following format: "[<provider>://][<username>[:<password>] ]<connection_params>". Note that if provided, <username>, <password> and <provider> must be encoded as per RFC 1738.
+ Connections to be opened can be specified on the command line using either:
+ <itemizedlist>
+ <listitem><para>defined data sources (the ones listed using the <option>-l</option> option)</para></listitem>
+ <listitem><para>connection strings which have the following format:
+ "[<provider>://][<username>[:<password>] ]<connection_params>".
+ Note that if provided, <username>, <password> and <provider> must be encoded as per RFC 1738</para></listitem>
+ <listitem><para>for SQLite and MS Access files: the file name</para></listitem>
+ </itemizedlist>
</para>
<para>
Connections can also be opened while the tool is running using the <command>.c</command>
@@ -108,7 +113,8 @@
Examples:
<programlisting>
[prompt]> gda-sql-4.0 Sales
-[prompt]> gda-sql-4.0 Postgresql://username DB_NAME=mydb SQLite://DB_NAME=fspot Sales
+[prompt]> gda-sql-4.0 Postgresql://username DB_NAME=mydb SQLite://DB_NAME=fspot Sales
+[prompt]> gda-sql-4.0 path/to/dbfile.db
</programlisting>
</para>
</sect1>
@@ -118,15 +124,197 @@
<chapter id="gda-sql-manual-open">
<title>Connections management</title>
<para>
- Blah.
+ The console tool is able to handle several connections at the same time, they can dynamically be opened and
+ closed during a session. The current connection in use is indicated by the prompt.
+ Use the <command>.c</command> command to open a connection with the connection name (the name by which
+ the connection is identified within the tool) and a connection string; for example:
+ <programlisting>
+gda> .c cnc1 SalesTest
+cnc1>
+ </programlisting>
</para>
+ <para>
+ The list of connection can be listed using the same <command>.c</command> command without any argument, for example:
+ <programlisting>
+ia32> .c
+ List of opened connections
+Name | Provider | DSN or connection string | Username
+-----+----------+--------------------------+---------
+cnc1 | SQLite | SalesTest |
+ia32 | SQLite | IA32Instructions |
+(2 rows)
- <sect1>
- <title>Connection string's format</title>
- </sect1>
+ia32>
+ </programlisting>
+ </para>
+ <para>
+ To switch from one connection to the other, use the <command>.c</command> command with the connection name to use
+ as single argument, for example to switch from using the "ia32" to the "cnc1" connection:
+ <programlisting>
+ia32> .c cnc1
+cnc1>
+ </programlisting>
+ </para>
<sect1>
<title>Meta data</title>
+ <para>
+ When a connection is opened for the first time, the tool get all the possible meta data associated to that connection (list of
+ tables, table's columns and their constraints, views, etc). The meta data are refered to when the user wants for example
+ to list a table's attributes, or for command line completion.
+ </para>
+ <para>
+ If some modifications to the database structure have been made (either from the SQL console or from another tool), then
+ the meta data must be updated using the <command>.meta</command> command, which does not output anything unless an error
+ occurred.
+ </para>
+ <para>
+ As the meta data are also stored in a database, the console tool allows one to directly execute SQL commands in the
+ meta data database associated to a connection. The meta data connection associated to a connection is by convention named
+ as the tilde character concatenated with the connection name (for example if the connection is named "cnc1", then the connection
+ to its meta data will be named "~cnc1"). To open a meta data connection, make sure the current connection is the one for which
+ you want to access the meta data, and then use the <command>.c ~</command> command:
+ <programlisting>
+cnc1> .c ~
+Getting database schema information, this may take some time... Done.
+~cnc1> .dt
+ List of tables
+Schema | Name | Type | Owner | Description
+-------+----------------------------------+------------+-------+------------
+main | _attributes | BASE TABLE | |
+main | _builtin_data_types | BASE TABLE | |
+main | _character_sets | BASE TABLE | |
+main | _check_column_usage | BASE TABLE | |
+main | _collations | BASE TABLE | |
+main | _columns | BASE TABLE | |
+main | _domain_constraints | BASE TABLE | |
+main | _domains | BASE TABLE | |
+main | _element_types | BASE TABLE | |
+main | _enums | BASE TABLE | |
+main | _information_schema_catalog_name | BASE TABLE | |
+main | _key_column_usage | BASE TABLE | |
+main | _parameters | BASE TABLE | |
+main | _referential_constraints | BASE TABLE | |
+main | _routine_columns | BASE TABLE | |
+main | _routines | BASE TABLE | |
+main | _schemata | BASE TABLE | |
+main | _table_constraints | BASE TABLE | |
+main | _tables | BASE TABLE | |
+main | _triggers | BASE TABLE | |
+main | _udt | BASE TABLE | |
+main | _udt_columns | BASE TABLE | |
+main | _view_column_usage | BASE TABLE | |
+main | _views | BASE TABLE | |
+main | gda_sql_query_buffers | BASE TABLE | |
+(25 rows)
+
+~cnc1> SELECT table_name FROM _tables;
+table_name
+---------------
+customers
+locations
+orders
+order_contents
+roles
+salesrep
+sales_orga
+warehouses
+categories
+products
+products_copied
+(11 rows)
+
+~cnc1>
+ </programlisting>
+ </para>
+
+ <sect2>
+ <title>Information about tables</title>
+ <para>
+ Use the <command>.dt</command> command to list all the tables (or list only one table if the table name is specified as
+ an argument to the command):
+ <programlisting>
+cnc1> .dt
+ List of tables
+Schema | Name | Type | Owner | Description
+-------+-----------------+------------+-------+------------
+main | categories | BASE TABLE | |
+main | customers | BASE TABLE | |
+main | locations | BASE TABLE | |
+main | order_contents | BASE TABLE | |
+main | orders | BASE TABLE | |
+main | products | BASE TABLE | |
+main | products_copied | BASE TABLE | |
+main | roles | BASE TABLE | |
+main | sales_orga | BASE TABLE | |
+main | salesrep | BASE TABLE | |
+main | warehouses | BASE TABLE | |
+(11 rows)
+
+cnc1> .dt customers
+ List of tables
+Schema | Name | Type | Owner | Description
+-------+-----------+------------+-------+------------
+main | customers | BASE TABLE | |
+(1 row)
+
+cnc1>
+ </programlisting>
+ </para>
+ <para>
+ To display the details about a single table, use the <command>.d <table_name></command> command:
+ <programlisting>
+cnc1> .d customers
+ List of columns for table 'customers'
+Column | Type | Nullable | Default | Extra
+------------------+---------+----------+---------+---------------
+id | integer | no | | Auto increment
+name | string | no | '' |
+default_served_by | integer | yes | |
+country | string | yes | |
+city | string | yes | |
+(5 rows)
+
+Primary key 'primary_key' (id)
+Foreign key 'fk_locations' (country, city) references main.locations (country, city)
+Foreign key 'fk_salesrep' (default_served_by) references main.salesrep (default_served_by)
+cnc1>
+ </programlisting>
+ </para>
+
+ <para>
+ Finally, the <command>.graph [TABLE1 [TABLE2...]]</command> will create a graph of all the tables (or
+ only the tables mentionned as arguments). The graph creates a <application>GraphViz</application> file
+ named "graph.dot" which can then be processed with the GraphViz'<command>dot</command> command to
+ produce an image or a PDF file for example.
+ </para>
+ <para>
+ If the <envar>GDA_SQL_VIEWER_PNG</envar> or <envar>GDA_SQL_VIEWER_PDF</envar> environment variables are set
+ (for example to <application>eog</application> or <application>evince</application>) and if the <command>dot</command> command
+ is installed, then the console tool will perform the transformation and display the graph (if under a graphical session).
+ The following figure shows an example of graph:
+ <mediaobject>
+ <imageobject role="html">
+ <imagedata fileref="gda-sql-graph.png" format="PNG" contentwidth="140mm"/>
+ </imageobject>
+ <textobject>
+ <phrase>Sample output from the ".graph" command</phrase>
+ </textobject>
+ </mediaobject>
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Information about views</title>
+ <para>
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Information about other objects</title>
+ <para>
+ </para>
+ </sect2>
</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 Thu Sep 18 18:52:53 2008
@@ -584,17 +584,6 @@
&libgda-GdaDataProxy;
&libgda-GdaDataComparator;
&libgda-GdaDataModelQuery;
- <para>
- The following UML diagram shows the various implementations of the GdaDataModel interface and their usage:
- <mediaobject>
- <imageobject role="html">
- <imagedata fileref="DataModels.png" format="PNG"/>
- </imageobject>
- <textobject>
- <phrase>Various implementations of the GdaDataModel interface</phrase>
- </textobject>
- </mediaobject>
- </para>
</chapter>
<chapter id="data_conv">
Modified: trunk/doc/C/tmpl/gda-data-proxy.sgml
==============================================================================
--- trunk/doc/C/tmpl/gda-data-proxy.sgml (original)
+++ trunk/doc/C/tmpl/gda-data-proxy.sgml Thu Sep 18 18:52:53 2008
@@ -33,8 +33,75 @@
</itemizedlist>
</para></listitem>
</itemizedlist>
+ This situation is illustrated in the following schema, where there is a direct mapping between the proxy's
+ rows and the proxied data model's rows:
+ <mediaobject>
+ <imageobject role="html">
+ <imagedata fileref="data_proxy1.png" format="PNG" contentwidth="170mm"/>
+ </imageobject>
+ <textobject>
+ <phrase>GdaDataProxy's values mapping regarding the proxied data model</phrase>
+ </textobject>
+ </mediaobject>
+
Note that unless explicitely mentionned, the columns are read-only.
</para>
+<para>
+ The following figures illustrate row mappings bewteen the data proxy and the proxied data model in
+ several situations (which can be combined, but are shown alone for simplicity):
+ <itemizedlist>
+ <listitem><para>situation where rows 1 and 5 have been marked as deleted from the data proxy, using
+ <link linkend="gda-data-proxy-delete">gda_data_proxy_delete()</link> method, the data
+ proxy has 2 rows less than the proxied data model:
+ <mediaobject>
+ <imageobject role="html">
+ <imagedata fileref="data_proxy2.png" format="PNG" contentwidth="100mm"/>
+ </imageobject>
+ <textobject>
+ <phrase>GdaDataProxy with 2 rows marked as deleted</phrase>
+ </textobject>
+ </mediaobject>
+ </para></listitem>
+
+ <listitem><para>situation where the data proxy only shows a sample of the proxied data model
+ at any given time, using the
+ <link linkend="gda-data-proxy-set-sample-size">gda_data_proxy_set_sample_size()</link> method
+ (the sample here is 4 rows wide, and starts at row 3):
+ <mediaobject>
+ <imageobject role="html">
+ <imagedata fileref="data_proxy3.png" format="PNG" contentwidth="100mm"/>
+ </imageobject>
+ <textobject>
+ <phrase>GdaDataProxy with a sample size of 4</phrase>
+ </textobject>
+ </mediaobject>
+ </para></listitem>
+
+ <listitem><para>situation where the data proxy shows a row of NULL values, using the
+ <link linkend="GdaDataproxy--prepend-null-entry">"prepend-null-entry"</link> property:
+ <mediaobject>
+ <imageobject role="html">
+ <imagedata fileref="data_proxy4.png" format="PNG" contentwidth="100mm"/>
+ </imageobject>
+ <textobject>
+ <phrase>GdaDataProxy with an extra row of NULL values</phrase>
+ </textobject>
+ </mediaobject>
+ </para></listitem>
+
+ <listitem><para>situation where a row has been added to the data proxy, using for example the
+ <link linkend="gda_data_model_append_row">gda_data_model_append_row()</link> method:
+ <mediaobject>
+ <imageobject role="html">
+ <imagedata fileref="data_proxy5.png" format="PNG" contentwidth="100mm"/>
+ </imageobject>
+ <textobject>
+ <phrase>GdaDataProxy where a row has been added</phrase>
+ </textobject>
+ </mediaobject>
+ </para></listitem>
+ </itemizedlist>
+</para>
<!-- ##### SECTION See_Also ##### -->
<para>
Modified: trunk/libgda/gda-data-model.c
==============================================================================
--- trunk/libgda/gda-data-model.c (original)
+++ trunk/libgda/gda-data-model.c Thu Sep 18 18:52:53 2008
@@ -30,6 +30,7 @@
#include <libgda/gda-data-model-extra.h>
#include <libgda/gda-data-model-iter.h>
#include <libgda/gda-data-model-import.h>
+#include <libgda/gda-data-access-wrapper.h>
#include <libgda/gda-log.h>
#include <libgda/gda-util.h>
#include <libgda/gda-row.h>
@@ -2065,7 +2066,18 @@
g_string_append_c (string, '\n');
/* ... and data */
- if (allok && gda_data_model_get_access_flags (model) & GDA_DATA_MODEL_ACCESS_RANDOM) {
+ GdaDataModel *ramodel;
+ if (gda_data_model_get_access_flags (model) & GDA_DATA_MODEL_ACCESS_RANDOM)
+ ramodel = g_object_ref (model);
+ else {
+ if (! (gda_data_model_get_access_flags (model) & GDA_DATA_MODEL_ACCESS_CURSOR_BACKWARD)) {
+ g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_ACCESS_ERROR,
+ _("Data model does not support backward cursor move, not displaying data"));
+ allok = FALSE;
+ }
+ ramodel = gda_data_access_wrapper_new (model);
+ }
+ if (allok) {
for (j = 0; j < n_rows; j++) {
/* determine height for each column in that row */
gint *cols_height = g_new (gint, n_cols + col_offset);
@@ -2081,7 +2093,7 @@
for (i = 0; i < n_cols; i++) {
if (!dump_attributes) {
- value = gda_data_model_get_value_at (model, i, j, error);
+ value = gda_data_model_get_value_at (ramodel, i, j, error);
if (!value) {
allok = FALSE;
break;
@@ -2096,7 +2108,7 @@
}
else {
GdaValueAttribute attrs;
- attrs = gda_data_model_get_attributes_at (model, i, j);
+ attrs = gda_data_model_get_attributes_at (ramodel, i, j);
str = g_strdup_printf ("%u", attrs);
}
if (str) {
@@ -2182,9 +2194,8 @@
}
g_string_append_printf (string, ngettext("(%d row)\n", "(%d rows)\n", n_rows), n_rows);
}
- else
- g_string_append (string, _("Model does not support random access, not showing data\n"));
+ g_object_unref (ramodel);
g_free (cols_size);
g_free (cols_is_num);
Modified: trunk/libgda/gda-meta-store.c
==============================================================================
--- trunk/libgda/gda-meta-store.c (original)
+++ trunk/libgda/gda-meta-store.c Thu Sep 18 18:52:53 2008
@@ -140,7 +140,8 @@
gchar *column_type;
GType gtype;
gboolean pkey;
- gboolean nullok;
+ gboolean nullok;
+ gboolean autoinc;
} TableColumn;
static void table_column_free (TableColumn *tcol);
#define TABLE_COLUMN(x) ((TableColumn*)(x))
@@ -897,7 +898,7 @@
if (! gda_server_operation_set_value_at (op, tcol->nullok ? "FALSE" : "TRUE", error,
"/FIELDS_A/@COLUMN_NNUL/%d", index))
goto onerror;
- if (! gda_server_operation_set_value_at (op, "FALSE", error,
+ if (! gda_server_operation_set_value_at (op, tcol->autoinc ? "TRUE" : "FALSE", error,
"/FIELDS_A/@COLUMN_AUTOINC/%d", index))
goto onerror;
repl = provider_specific_match (specific_hash, prov, "dummy", "/FIELDS_A/@COLUMN_PKEY");
@@ -1279,6 +1280,7 @@
xmlChar *cname, *ctype, *xstr;
gboolean pkey = FALSE;
gboolean nullok = FALSE;
+ gboolean autoinc = FALSE;
if (strcmp ((gchar *) cnode->name, "column"))
continue;
@@ -1297,6 +1299,12 @@
nullok = TRUE;
xmlFree (xstr);
}
+ xstr = xmlGetProp (cnode, BAD_CAST "autoinc");
+ if (xstr) {
+ if ((*xstr == 't') || (*xstr == 'T'))
+ autoinc = TRUE;
+ xmlFree (xstr);
+ }
ctype = xmlGetProp (cnode, BAD_CAST "type");
/* a field */
@@ -1381,13 +1389,40 @@
TABLE_INFO (dbobj)->type_cols_array [colindex+1] = G_TYPE_NONE;
/* TableColumn */
- TableColumn *tcol = g_new0 (TableColumn, 1);
- TABLE_INFO (dbobj)->columns = g_slist_append (TABLE_INFO (dbobj)->columns, tcol);
- tcol->column_name = g_strdup ((gchar *) cname);
- tcol->column_type = ctype ? g_strdup ((gchar *) ctype) : NULL;
- tcol->gtype = ptype;
- tcol->pkey = pkey;
- tcol->nullok = nullok;
+ TableColumn *tcol = NULL;
+ GSList *tlist;
+ for (tlist = TABLE_INFO (dbobj)->columns; tlist; tlist = tlist->next) {
+ if (((TableColumn*) tlist->data)->column_name &&
+ !strcmp (((TableColumn*) tlist->data)->column_name, cname)) {
+ tcol = (TableColumn*) tlist->data;
+ if ((tcol->gtype != ptype) ||
+ (tcol->pkey != pkey) ||
+ (tcol->nullok != nullok) ||
+ (tcol->autoinc != autoinc) ||
+ (! tcol->column_type && ctype) ||
+ (tcol->column_type && !ctype) ||
+ (tcol->column_type && strcmp (tcol->column_type, (gchar *) ctype))) {
+ g_set_error (error, 0, 0,
+ _("Column '%s' already exists and has different characteristics"),
+ tcol->column_name);
+ xmlFree (cname);
+ if (ctype)
+ xmlFree (ctype);
+ goto onerror;
+ }
+ break;
+ }
+ }
+ if (!tcol) {
+ tcol = g_new0 (TableColumn, 1);
+ TABLE_INFO (dbobj)->columns = g_slist_append (TABLE_INFO (dbobj)->columns, tcol);
+ tcol->column_name = g_strdup ((gchar *) cname);
+ tcol->column_type = ctype ? g_strdup ((gchar *) ctype) : NULL;
+ tcol->gtype = ptype;
+ tcol->pkey = pkey;
+ tcol->nullok = nullok;
+ tcol->autoinc = autoinc;
+ }
/* free mem */
xmlFree (cname);
@@ -3107,6 +3142,46 @@
* with the GDA_META_STORE_SCHEMA_OBJECT_CONFLICT_ERROR error code</para></listitem>
* </itemizedlist>
*
+ * The @xml_description defines the table of view's definition, for example:
+ * <programlisting><![CDATA[<table name="mytable">
+ <column name="id" pkey="TRUE"/>
+ <column name="value"/>
+</table>]]></programlisting>
+ *
+ * The partial DTD for this XML description of the object to add is the following (the top node must be
+ * a <table> or a <view>):
+ * <programlisting><![CDATA[<!ELEMENT table (column*,check*,fkey*,unique*)>
+<!ATTLIST table
+ name NMTOKEN #REQUIRED>
+
+<!ELEMENT column EMPTY>
+<!ATTLIST column
+ name NMTOKEN #REQUIRED
+ type CDATA #IMPLIED
+ pkey (TRUE|FALSE) #IMPLIED
+ autoinc (TRUE|FALSE) #IMPLIED
+ nullok (TRUE|FALSE) #IMPLIED>
+
+<!ELEMENT check (#PCDATA)>
+
+<!ELEMENT fkey (part+)>
+<!ATTLIST fkey
+ ref_table NMTOKEN #REQUIRED>
+
+<!ELEMENT part EMPTY>
+<!ATTLIST part
+ column NMTOKEN #IMPLIED
+ ref_column NMTOKEN #IMPLIED>
+
+<!ELEMENT unique (column*)>
+
+<!ELEMENT view (definition)>
+<!ATTLIST view
+ name NMTOKEN #REQUIRED
+ descr CDATA #IMPLIED>
+
+<!ELEMENT definition (#PCDATA)>]]></programlisting>
+ *
* Returns: TRUE if the new object has sucessfully been added
*/
gboolean
@@ -3121,7 +3196,7 @@
GdaMetaStruct *mstruct = NULL;
GError *lerror = NULL;
- GSList *pre_p_db_objects;
+ GSList *pre_p_db_objects = NULL;
g_return_val_if_fail (GDA_IS_META_STORE (store), FALSE);
g_return_val_if_fail (xml_description && *xml_description, FALSE);
@@ -3154,7 +3229,7 @@
/* keep a list of custom DB objects _before_ adding the new one(s) (more than
* one if there are dependencies) */
pre_p_db_objects = g_slist_copy (store->priv->p_db_objects);
-
+
/* create DbObject structure from XML description, stored in @store's custom db objects */
if (!strcmp ((gchar *) node->name, "table"))
dbo = create_table_object (klass, store, node, error);
@@ -3167,7 +3242,7 @@
doc = NULL;
/* check for an already existing database object with the same name */
- g_print ("Obj name: %s\n", dbo->obj_name);
+ /*g_print ("Obj name: %s\n", dbo->obj_name);*/
/* make sure the private connection's meta store is up to date about the requested object */
switch (dbo->obj_type) {
@@ -3212,7 +3287,7 @@
if (eobj) {
gboolean conflict = FALSE;
- g_print ("Check Existing object's conformance...\n");
+ /*g_print ("Check Existing object's conformance...\n");*/
switch (eobj->obj_type) {
case GDA_META_DB_TABLE:
if (dbo->obj_type != GDA_SERVER_OPERATION_CREATE_TABLE)
@@ -3258,7 +3333,7 @@
goto onerror;
/* actually create the object in database */
- g_print ("Creating object: %s\n", dbo->obj_name);
+ /*g_print ("Creating object: %s\n", dbo->obj_name);*/
if (dbo->create_op) {
if (!gda_server_provider_perform_operation (prov, store->priv->cnc, dbo->create_op, error))
goto onerror;
Modified: trunk/libgda/sqlite/gda-sqlite-ddl.c
==============================================================================
--- trunk/libgda/sqlite/gda-sqlite-ddl.c (original)
+++ trunk/libgda/sqlite/gda-sqlite-ddl.c Thu Sep 18 18:52:53 2008
@@ -78,6 +78,7 @@
/* manually defined fields */
first = TRUE;
for (i = 0; i < nrows; i++) {
+ gboolean pkautoinc = FALSE;
hasfields = TRUE;
if (first)
first = FALSE;
@@ -88,84 +89,101 @@
g_string_append (string, g_value_get_string (value));
g_string_append_c (string, ' ');
- value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_TYPE/%d", i);
- g_string_append (string, g_value_get_string (value));
-
- value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_SIZE/%d", i);
- if (value && G_VALUE_HOLDS (value, G_TYPE_UINT)) {
- g_string_append_printf (string, "(%d", g_value_get_uint (value));
-
- value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_SCALE/%d", i);
- if (value && G_VALUE_HOLDS (value, G_TYPE_UINT))
- g_string_append_printf (string, ",%d)", g_value_get_uint (value));
- else
- g_string_append (string, ")");
+ if (nbpkfields == 1) {
+ value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_AUTOINC/%d", i);
+ if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value)) {
+ const gchar *tmp;
+ value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_TYPE/%d", i);
+ tmp = g_value_get_string (value);
+ if (!g_ascii_strcasecmp (tmp, "gint") ||
+ !g_ascii_strcasecmp (tmp, "int")) {
+ g_string_append (string, "INTEGER PRIMARY KEY AUTOINCREMENT");
+ pkautoinc = TRUE;
+ }
+ }
}
- value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_DEFAULT/%d", i);
- if (value && G_VALUE_HOLDS (value, G_TYPE_STRING)) {
- const gchar *str = g_value_get_string (value);
- if (str && *str) {
- g_string_append (string, " DEFAULT ");
- g_string_append (string, str);
+ if (!pkautoinc) {
+ value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_TYPE/%d", i);
+ g_string_append (string, g_value_get_string (value));
+
+ value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_SIZE/%d", i);
+ if (value && G_VALUE_HOLDS (value, G_TYPE_UINT)) {
+ g_string_append_printf (string, "(%d", g_value_get_uint (value));
+
+ value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_SCALE/%d", i);
+ if (value && G_VALUE_HOLDS (value, G_TYPE_UINT))
+ g_string_append_printf (string, ",%d)", g_value_get_uint (value));
+ else
+ g_string_append (string, ")");
}
- }
- value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_NNUL/%d", i);
- if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value))
- g_string_append (string, " NOT NULL");
-
- value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_UNIQUE/%d", i);
- if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value))
- g_string_append (string, " UNIQUE");
+ value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_DEFAULT/%d", i);
+ if (value && G_VALUE_HOLDS (value, G_TYPE_STRING)) {
+ const gchar *str = g_value_get_string (value);
+ if (str && *str) {
+ g_string_append (string, " DEFAULT ");
+ g_string_append (string, str);
+ }
+ }
- if (nbpkfields == 1) {
- value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_PKEY/%d", i);
- if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value)) {
- g_string_append (string, " PRIMARY KEY");
-
- value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_CONFLICT/%d", i);
- if (value && G_VALUE_HOLDS (value, G_TYPE_STRING)) {
- const gchar *str = g_value_get_string (value);
- if (str && *str) {
- g_string_append (string, " ON CONFLICT ");
- g_string_append (string, str);
- }
+ value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_NNUL/%d", i);
+ if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value))
+ g_string_append (string, " NOT NULL");
+
+ value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_UNIQUE/%d", i);
+ if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value))
+ g_string_append (string, " UNIQUE");
+
+ if (nbpkfields == 1) {
+ value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_PKEY/%d", i);
+ if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value)) {
+ g_string_append (string, " PRIMARY KEY");
- }
- value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_AUTOINC/%d", i);
- if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value))
- g_string_append (string, " AUTOINCREMENT");
+ value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_CONFLICT/%d", i);
+ if (value && G_VALUE_HOLDS (value, G_TYPE_STRING)) {
+ const gchar *str = g_value_get_string (value);
+ if (str && *str) {
+ g_string_append (string, " ON CONFLICT ");
+ g_string_append (string, str);
+ }
+
+ }
+ value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_AUTOINC/%d", i);
+ if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value)) {
+ g_string_append (string, " AUTOINCREMENT");
+ }
+ }
+
}
-
- }
- else {
- if (!conflict_algo) {
- value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_CONFLICT/%d", i);
- if (value && G_VALUE_HOLDS (value, G_TYPE_STRING)) {
- const gchar *str = g_value_get_string (value);
- if (str && *str)
- conflict_algo = g_strdup (str);
- }
+ else {
+ if (!conflict_algo) {
+ value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_CONFLICT/%d", i);
+ if (value && G_VALUE_HOLDS (value, G_TYPE_STRING)) {
+ const gchar *str = g_value_get_string (value);
+ if (str && *str)
+ conflict_algo = g_strdup (str);
+ }
+ }
}
- }
- value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_CHECK/%d", i);
- if (value && G_VALUE_HOLDS (value, G_TYPE_STRING)) {
- const gchar *str = g_value_get_string (value);
- if (str && *str) {
- g_string_append (string, " CHECK (");
- g_string_append (string, str);
- g_string_append_c (string, ')');
+ value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_CHECK/%d", i);
+ if (value && G_VALUE_HOLDS (value, G_TYPE_STRING)) {
+ const gchar *str = g_value_get_string (value);
+ if (str && *str) {
+ g_string_append (string, " CHECK (");
+ g_string_append (string, str);
+ g_string_append_c (string, ')');
+ }
}
- }
-
- value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_COLLATE/%d", i);
- if (value && G_VALUE_HOLDS (value, G_TYPE_STRING)) {
- const gchar *str = g_value_get_string (value);
- if (str && *str) {
- g_string_append (string, " COLLATE ");
- g_string_append (string, str);
+
+ value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_COLLATE/%d", i);
+ if (value && G_VALUE_HOLDS (value, G_TYPE_STRING)) {
+ const gchar *str = g_value_get_string (value);
+ if (str && *str) {
+ g_string_append (string, " COLLATE ");
+ g_string_append (string, str);
+ }
}
}
}
Modified: trunk/tests/data-models/check_pmodel.c
==============================================================================
--- trunk/tests/data-models/check_pmodel.c (original)
+++ trunk/tests/data-models/check_pmodel.c Thu Sep 18 18:52:53 2008
@@ -1243,9 +1243,15 @@
clear_signals ();
/* create GdaDataSelect */
- stmt = stmt_from_string ("SELECT * FROM customers WHERE id <= ##id::int");
+ stmt = stmt_from_string ("SELECT * FROM customers WHERE id <= ##id::int ORDER BY name");
g_assert (gda_statement_get_parameters (stmt, ¶ms, NULL));
- g_assert (gda_set_set_holder_value (params, &error, "id", "9"));
+ g_assert (gda_set_set_holder_value (params, &error, "id", 9));
+
+ model = gda_connection_statement_execute_select (cnc, stmt, params, &error);
+ g_assert (model);
+ gda_data_model_dump (model, stdout);
+ g_object_unref (model);
+
model = gda_connection_statement_execute_select_full (cnc, stmt, params,
GDA_STATEMENT_MODEL_CURSOR_FORWARD,
NULL, &error);
@@ -1308,6 +1314,47 @@
#endif
goto out;
}
+ gda_value_free (value);
+
+ /**/
+ g_value_set_int ((value = gda_value_new (G_TYPE_INT)), 1);
+ if (! gda_data_model_iter_set_value_at (iter, 0, value, &error)) {
+ nfailed++;
+#ifdef CHECK_EXTRA_INFO
+ g_print ("GdaDataModelIter value set failed: %s\n",
+ error && error->message ? error->message : "No detail");
+#endif
+ goto out;
+ }
+ if (! check_expected_signal (model, 'U', 1)) {
+ nfailed++;
+ goto out;
+ }
+ cvalue = gda_data_model_iter_get_value_at (iter, 0);
+ if (!cvalue) {
+ nfailed++;
+#ifdef CHECK_EXTRA_INFO
+ g_print ("gda_data_model_iter_get_value_at() failed after modification\n");
+#endif
+ goto out;
+ }
+ if (gda_value_differ (cvalue, value)) {
+ nfailed++;
+#ifdef CHECK_EXTRA_INFO
+ g_print ("gda_data_model_iter_get_value_at() and modified value differ\n");
+#endif
+ goto out;
+ }
+
+ GdaDataModel *rerun;
+ rerun = gda_connection_statement_execute_select (cnc, stmt, params, &error);
+ g_assert (rerun);
+ gda_data_model_dump (rerun, stdout);
+
+ gda_value_free (value);
+
+
+
g_object_unref (iter);
Modified: trunk/tools/gda-sql.c
==============================================================================
--- trunk/tools/gda-sql.c (original)
+++ trunk/tools/gda-sql.c Thu Sep 18 18:52:53 2008
@@ -888,22 +888,50 @@
GdaConnection *newcnc = NULL;
ConnectionSetting *cs = NULL;
static gint cncindex = 0;
+ gchar *real_cnc_string;
if (cnc_name && ! connection_name_is_valid (cnc_name)) {
g_set_error (error, 0, 0,
_("Connection name '%s' is invalid"), cnc_name);
return NULL;
}
-
+
GdaDsnInfo *info;
gchar *user, *pass, *real_cnc, *real_provider, *real_auth_string = NULL;
- gda_connection_string_split (cnc_string, &real_cnc, &real_provider, &user, &pass);
+
+ /* if cnc string is a regular file, then use it with SQLite */
+ if (g_file_test (cnc_string, G_FILE_TEST_IS_REGULAR)) {
+ gchar *path, *file, *e1, *e2;
+ const gchar *pname = "SQLite";
+
+ path = g_path_get_dirname (cnc_string);
+ file = g_path_get_basename (cnc_string);
+ if (g_str_has_suffix (file, ".mdb")) {
+ pname = "MSAccess";
+ file [strlen (file) - 4] = 0;
+ }
+ else if (g_str_has_suffix (file, ".db"))
+ file [strlen (file) - 3] = 0;
+ e1 = gda_rfc1738_encode (path);
+ e2 = gda_rfc1738_encode (file);
+ g_free (path);
+ g_free (file);
+ real_cnc_string = g_strdup_printf ("%s://DB_DIR=%s;DB_NAME=%s", pname, e1, e2);
+ g_free (e1);
+ g_free (e2);
+ gda_connection_string_split (real_cnc_string, &real_cnc, &real_provider, &user, &pass);
+ }
+ else {
+ gda_connection_string_split (cnc_string, &real_cnc, &real_provider, &user, &pass);
+ real_cnc_string = g_strdup (cnc_string);
+ }
if (!real_cnc) {
g_free (user);
g_free (pass);
g_free (real_provider);
g_set_error (error, GDA_CONNECTION_ERROR, GDA_CONNECTION_DSN_NOT_FOUND_ERROR,
_("Malformed connection string '%s'"), cnc_string);
+ g_free (real_cnc_string);
return NULL;
}
@@ -918,6 +946,7 @@
g_free (real_provider);
g_set_error (error, GDA_CONNECTION_ERROR, GDA_CONNECTION_DSN_NOT_FOUND_ERROR,
_("No username for '%s'"), cnc_string);
+ g_free (real_cnc_string);
return NULL;
}
g_free (user);
@@ -933,6 +962,7 @@
g_free (real_provider);
g_set_error (error, GDA_CONNECTION_ERROR, GDA_CONNECTION_DSN_NOT_FOUND_ERROR,
_("No password for '%s'"), cnc_string);
+ g_free (real_cnc_string);
return NULL;
}
g_free (pass);
@@ -955,10 +985,11 @@
info = gda_config_get_dsn_info (real_cnc);
if (info && !real_provider)
- newcnc = gda_connection_open_from_dsn (cnc_string, real_auth_string, 0, error);
+ newcnc = gda_connection_open_from_dsn (real_cnc_string, real_auth_string, 0, error);
else
- newcnc = gda_connection_open_from_string (NULL, cnc_string, real_auth_string, 0, error);
+ newcnc = gda_connection_open_from_string (NULL, real_cnc_string, real_auth_string, 0, error);
+ g_free (real_cnc_string);
g_free (real_cnc);
g_free (user);
g_free (pass);
@@ -1324,6 +1355,10 @@
GError **error, MainData *data);
static GdaInternalCommandResult *extra_command_query_buffer_from_dict (GdaConnection *cnc, const gchar **args,
GError **error, MainData *data);
+static GdaInternalCommandResult *extra_command_query_buffer_list_dict (GdaConnection *cnc, const gchar **args,
+ GError **error, MainData *data);
+static GdaInternalCommandResult *extra_command_query_buffer_delete_dict (GdaConnection *cnc, const gchar **args,
+ GError **error, MainData *data);
static GdaInternalCommandResult *extra_command_set (GdaConnection *cnc, const gchar **args,
GError **error, MainData *data);
@@ -1552,7 +1587,7 @@
c = g_new0 (GdaInternalCommand, 1);
c->group = _("Query buffer");
- c->name = g_strdup_printf (_("%s [FILE]"), "r");
+ c->name = g_strdup_printf (_("%s [FILE]"), "qr");
c->description = _("Reset the query buffer (fill buffer with contents of file)");
c->args = NULL;
c->command_func = (GdaInternalCommandFunc) extra_command_reset_buffer;
@@ -1562,7 +1597,7 @@
c = g_new0 (GdaInternalCommand, 1);
c->group = _("Query buffer");
- c->name = "p";
+ c->name = "qp";
c->description = _("Show the contents of the query buffer");
c->args = NULL;
c->command_func = (GdaInternalCommandFunc) extra_command_show_buffer;
@@ -1572,8 +1607,8 @@
c = g_new0 (GdaInternalCommand, 1);
c->group = _("Query buffer");
- c->name = "g";
- c->description = _("Execute contents of query buffer");
+ c->name = g_strdup_printf (_("%s [QUERY_BUFFER_NAME]"), "g");
+ c->description = _("Execute contents of query buffer, or named query buffer");
c->args = NULL;
c->command_func = (GdaInternalCommandFunc) extra_command_exec_buffer;
c->user_data = data;
@@ -1582,7 +1617,7 @@
c = g_new0 (GdaInternalCommand, 1);
c->group = _("Query buffer");
- c->name = g_strdup_printf (_("%s FILE"), "w");
+ c->name = g_strdup_printf (_("%s FILE"), "qw");
c->description = _("Write query buffer to file");
c->args = NULL;
c->command_func = (GdaInternalCommandFunc) extra_command_write_buffer;
@@ -1592,7 +1627,7 @@
c = g_new0 (GdaInternalCommand, 1);
c->group = _("Query buffer");
- c->name = g_strdup_printf (_("%s [QUERY_NAME]"), "w_dict");
+ c->name = g_strdup_printf (_("%s QUERY_BUFFER_NAME"), "qs");
c->description = _("Save query buffer to dictionary");
c->args = NULL;
c->command_func = (GdaInternalCommandFunc) extra_command_query_buffer_to_dict;
@@ -1602,8 +1637,8 @@
c = g_new0 (GdaInternalCommand, 1);
c->group = _("Query buffer");
- c->name = g_strdup_printf (_("%s QUERY_NAME"), "r_dict");
- c->description = _("Set named query from dictionary into query buffer");
+ c->name = g_strdup_printf (_("%s QUERY_BUFFER_NAME"), "ql");
+ c->description = _("Load query buffer from dictionary");
c->args = NULL;
c->command_func = (GdaInternalCommandFunc) extra_command_query_buffer_from_dict;
c->user_data = data;
@@ -1612,6 +1647,26 @@
c = g_new0 (GdaInternalCommand, 1);
c->group = _("Query buffer");
+ c->name = g_strdup_printf (_("%s QUERY_BUFFER_NAME"), "qd");
+ c->description = _("Delete query buffer from dictionary");
+ c->args = NULL;
+ c->command_func = (GdaInternalCommandFunc) extra_command_query_buffer_delete_dict;
+ c->user_data = data;
+ c->arguments_delimiter_func = NULL;
+ commands->commands = g_slist_prepend (commands->commands, c);
+
+ c = g_new0 (GdaInternalCommand, 1);
+ c->group = _("Query buffer");
+ c->name = g_strdup_printf (_("%s"), "qa");
+ c->description = _("List all saved query buffers in dictionary");
+ c->args = NULL;
+ c->command_func = (GdaInternalCommandFunc) extra_command_query_buffer_list_dict;
+ c->user_data = data;
+ c->arguments_delimiter_func = NULL;
+ commands->commands = g_slist_prepend (commands->commands, c);
+
+ c = g_new0 (GdaInternalCommand, 1);
+ c->group = _("Query buffer");
c->name = g_strdup_printf (_("%s [NAME [VALUE|_null_]]"), "set");
c->description = _("Set or show internal parameter, or list all if no parameters");
c->args = NULL;
@@ -2374,6 +2429,15 @@
return NULL;
}
+ if (args[0] && *args[0]) {
+ /* load named query buffer first */
+ res = extra_command_query_buffer_from_dict (cnc, args, error, data);
+ if (!res)
+ return NULL;
+ gda_internal_command_exec_result_free (res);
+ res = NULL;
+ }
+
if (!data->current->query_buffer)
data->current->query_buffer = g_string_new ("");
if (*data->current->query_buffer->str != 0)
@@ -2412,12 +2476,64 @@
return res;
}
-static GdaStatement *
-find_statement_in_connection_meta_store (GdaConnection *cnc, const gchar *query_name)
+#define QUERY_BUFFERS_TABLE_NAME "gda_sql_query_buffers"
+#define QUERY_BUFFERS_TABLE_DESC \
+ "<table name=\"" QUERY_BUFFERS_TABLE_NAME "\"> " \
+ " <column name=\"id\" type=\"gint\" pkey=\"TRUE\" autoinc=\"TRUE\"/>" \
+ " <column name=\"name\"/>" \
+ " <column name=\"sql\"/>" \
+ "</table>"
+#define QUERY_BUFFERS_TABLE_INSERT \
+ "INSERT INTO " QUERY_BUFFERS_TABLE_NAME " (name, sql) VALUES (##name::string, ##sql::string)"
+#define QUERY_BUFFERS_TABLE_SELECT \
+ "SELECT name, sql FROM " QUERY_BUFFERS_TABLE_NAME " ORDER BY name"
+#define QUERY_BUFFERS_TABLE_SELECT_ONE \
+ "SELECT sql FROM " QUERY_BUFFERS_TABLE_NAME " WHERE name = ##name::string"
+#define QUERY_BUFFERS_TABLE_DELETE \
+ "DELETE FROM " QUERY_BUFFERS_TABLE_NAME " WHERE name = ##name::string"
+
+static GdaInternalCommandResult *
+extra_command_query_buffer_list_dict (GdaConnection *cnc, const gchar **args,
+ GError **error, MainData *data)
{
- GdaStatement *stmt = NULL;
- TO_IMPLEMENT;
- return stmt;
+ GdaInternalCommandResult *res = NULL;
+
+ if (!data->current) {
+ g_set_error (error, 0, 0, _("No connection opened"));
+ return NULL;
+ }
+
+ /* Meta store's init */
+ GdaMetaStore *mstore;
+ mstore = gda_connection_get_meta_store (data->current->cnc);
+ if (!gda_meta_store_schema_add_custom_object (mstore, QUERY_BUFFERS_TABLE_DESC, NULL)) {
+ g_set_error (error, 0, 0,
+ _("Can't initialize dictionary to store query buffers"));
+ return NULL;
+ }
+
+ /* actual list retreival */
+ static GdaStatement *sel_stmt = NULL;
+ GdaDataModel *model;
+ if (!sel_stmt) {
+ sel_stmt = gda_sql_parser_parse_string (data->current->parser,
+ QUERY_BUFFERS_TABLE_SELECT, NULL, NULL);
+ g_assert (sel_stmt);
+ }
+
+ GdaConnection *store_cnc;
+ store_cnc = gda_meta_store_get_internal_connection (mstore);
+ model = gda_connection_statement_execute_select (store_cnc, sel_stmt, NULL, error);
+ if (!model)
+ return NULL;
+
+ gda_data_model_set_column_title (model, 0, _("Query buffer name"));
+ gda_data_model_set_column_title (model, 1, _("SQL"));
+ res = g_new0 (GdaInternalCommandResult, 1);
+ res->type = GDA_INTERNAL_COMMAND_RESULT_DATA_MODEL;
+ res->u.model = model;
+
+ return res;
}
static GdaInternalCommandResult *
@@ -2434,36 +2550,48 @@
if (!data->current->query_buffer)
data->current->query_buffer = g_string_new ("");
if (*data->current->query_buffer->str != 0) {
- GdaStatement *stmt;
+ /* find a suitable name */
gchar *qname;
-
- /* check SQL validity */
- const gchar *remain = NULL;
- stmt = gda_sql_parser_parse_string (data->current->parser, data->current->query_buffer->str, &remain, error);
- if (!stmt)
- return NULL;
- g_object_unref (stmt);
- if (remain) {
+ if (args[0] && *args[0])
+ qname = g_strdup ((gchar *) args[0]);
+ else {
g_set_error (error, 0, 0,
- _("Query buffer contains more than one SQL statement"));
+ _("Missing query buffer name"));
return NULL;
}
- /* find a suitable name */
- if (args[0] && *args[0])
- qname = g_strdup ((gchar *) args[0]);
- else {
- gint i;
- for (i = 0; ; i++) {
- qname = g_strdup_printf ("saved_stmt_%d", i);
- stmt = find_statement_in_connection_meta_store (data->current->cnc, qname);
- if (!stmt)
- break;
- }
+ /* Meta store's init */
+ GdaMetaStore *mstore;
+ mstore = gda_connection_get_meta_store (data->current->cnc);
+ if (!gda_meta_store_schema_add_custom_object (mstore, QUERY_BUFFERS_TABLE_DESC, NULL)) {
+ g_set_error (error, 0, 0,
+ _("Can't initialize dictionary to store query buffers"));
+ g_free (qname);
+ return NULL;
+ }
+
+ /* actual store of the statement */
+ static GdaStatement *ins_stmt = NULL;
+ static GdaSet *ins_params = NULL;
+ if (!ins_stmt) {
+ ins_stmt = gda_sql_parser_parse_string (data->current->parser,
+ QUERY_BUFFERS_TABLE_INSERT, NULL, NULL);
+ g_assert (ins_stmt);
+ g_assert (gda_statement_get_parameters (ins_stmt, &ins_params, NULL));
}
- TO_IMPLEMENT; /* add data->current->query_buffer->str as a new query in data->current->cnc's meta store */
+ if (! gda_set_set_holder_value (ins_params, error, "name", qname) ||
+ ! gda_set_set_holder_value (ins_params, error, "sql", data->current->query_buffer->str)) {
+ g_free (qname);
+ return NULL;
+ }
g_free (qname);
+
+ GdaConnection *store_cnc;
+ store_cnc = gda_meta_store_get_internal_connection (mstore);
+ if (gda_connection_statement_execute_non_select (store_cnc, ins_stmt, ins_params,
+ NULL, error) == -1)
+ return NULL;
res = g_new0 (GdaInternalCommandResult, 1);
res->type = GDA_INTERNAL_COMMAND_RESULT_EMPTY;
}
@@ -2489,26 +2617,102 @@
data->current->query_buffer = g_string_new ("");
if (args[0] && *args[0]) {
- GdaStatement *stmt = find_statement_in_connection_meta_store (data->current->cnc, args[0]);
- if (stmt) {
- gchar *str;
- str = gda_statement_to_sql_extended (stmt, data->current->cnc, NULL,
- GDA_STATEMENT_SQL_PARAMS_SHORT, NULL, error);
- if (!str)
- return NULL;
+ /* Meta store's init */
+ GdaMetaStore *mstore;
+ mstore = gda_connection_get_meta_store (data->current->cnc);
+ if (!gda_meta_store_schema_add_custom_object (mstore, QUERY_BUFFERS_TABLE_DESC, NULL)) {
+ g_set_error (error, 0, 0,
+ _("Can't initialize dictionary to store query buffers"));
+ return NULL;
+ }
+
+ /* query retreival */
+ static GdaStatement *sel_stmt = NULL;
+ static GdaSet *sel_params = NULL;
+ GdaDataModel *model;
+ const GValue *cvalue;
+ if (!sel_stmt) {
+ sel_stmt = gda_sql_parser_parse_string (data->current->parser,
+ QUERY_BUFFERS_TABLE_SELECT_ONE, NULL, NULL);
+ g_assert (sel_stmt);
+ g_assert (gda_statement_get_parameters (sel_stmt, &sel_params, NULL));
+ }
- g_string_assign (data->current->query_buffer, str);
- g_free (str);
+ if (! gda_set_set_holder_value (sel_params, error, "name", args[0]))
+ return NULL;
+
+ GdaConnection *store_cnc;
+ store_cnc = gda_meta_store_get_internal_connection (mstore);
+ model = gda_connection_statement_execute_select (store_cnc, sel_stmt, sel_params, error);
+ if (!model)
+ return NULL;
+
+ if ((gda_data_model_get_n_rows (model) == 1) &&
+ (cvalue = gda_data_model_get_value_at (model, 0, 0, NULL))) {
+ g_string_assign (data->current->query_buffer, g_value_get_string (cvalue));
res = g_new0 (GdaInternalCommandResult, 1);
res->type = GDA_INTERNAL_COMMAND_RESULT_EMPTY;
}
- else
+ else
g_set_error (error, 0, 0,
- _("Could not find query named '%s'"), args[0]);
+ _("Could not find query buffer named '%s'"), args[0]);
+ g_object_unref (model);
+ }
+ else
+ g_set_error (error, 0, 0,
+ _("Missing query buffer name"));
+
+ return res;
+}
+
+static GdaInternalCommandResult *
+extra_command_query_buffer_delete_dict (GdaConnection *cnc, const gchar **args,
+ GError **error, MainData *data)
+{
+ GdaInternalCommandResult *res = NULL;
+
+ if (!data->current) {
+ g_set_error (error, 0, 0, _("No connection opened"));
+ return NULL;
+ }
+
+ if (!data->current->query_buffer)
+ data->current->query_buffer = g_string_new ("");
+
+ if (args[0] && *args[0]) {
+ /* Meta store's init */
+ GdaMetaStore *mstore;
+ mstore = gda_connection_get_meta_store (data->current->cnc);
+ if (!gda_meta_store_schema_add_custom_object (mstore, QUERY_BUFFERS_TABLE_DESC, NULL)) {
+ g_set_error (error, 0, 0,
+ _("Can't initialize dictionary to store query buffers"));
+ return NULL;
+ }
+
+ /* query retreival */
+ static GdaStatement *del_stmt = NULL;
+ static GdaSet *del_params = NULL;
+ if (!del_stmt) {
+ del_stmt = gda_sql_parser_parse_string (data->current->parser,
+ QUERY_BUFFERS_TABLE_DELETE, NULL, NULL);
+ g_assert (del_stmt);
+ g_assert (gda_statement_get_parameters (del_stmt, &del_params, NULL));
+ }
+
+ if (! gda_set_set_holder_value (del_params, error, "name", args[0]))
+ return NULL;
+
+ GdaConnection *store_cnc;
+ store_cnc = gda_meta_store_get_internal_connection (mstore);
+ if (gda_connection_statement_execute_non_select (store_cnc, del_stmt, del_params,
+ NULL, error) == -1)
+ return NULL;
+ res = g_new0 (GdaInternalCommandResult, 1);
+ res->type = GDA_INTERNAL_COMMAND_RESULT_EMPTY;
}
else
g_set_error (error, 0, 0,
- _("Missing query name"));
+ _("Missing query buffer name"));
return res;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]