libgda r3213 - in trunk: . doc/C libgda libgda/sqlite libgda/sqlite/sqlite-src providers/postgres tools



Author: vivien
Date: Sat Sep 20 12:35:00 2008
New Revision: 3213
URL: http://svn.gnome.org/viewvc/libgda?rev=3213&view=rev

Log:
2008-09-20  Vivien Malerba <malerba gnome-db org>

	* providers/postgres/gda-postgres-meta.c:
	* libgda/gda-meta-struct.c: bugs fixed
	* tools/Makefile.am: also distribute the gda-sql.ico file
	* tools/gda-sql.c:
	* tools/command-exec.[ch]:
	  - correctly handle non threading environment
	  - removed the non implemented "dq" internal command (use "qa" instead)
	  - correctly handle the "-C" command line flag
	  - when commands are executed from a file ("-f" argument), then don't quit when finished
	    executing the commands.
	* libgda/sqlite/gda-sqlite-meta.c: corrected a bug in the way "PRAGMA table_info" was used
	to list all the columns of a table when the schema was not "main".
	* libgda/sqlite/sqlite-src/sqlite3.c:
	* libgda/sqlite/sqlite-src/PragmasPatch: reimplemented the "proc_list" PRAGMA to make it
	work with the current version of SQLite
	* doc/C: vastly improved the "gda-sql" console tool manual


Modified:
   trunk/ChangeLog
   trunk/doc/C/gda-sql-manual.xml
   trunk/doc/C/libgda-4.0-docs.sgml
   trunk/libgda/gda-connection.c
   trunk/libgda/gda-meta-struct.c
   trunk/libgda/sqlite/gda-sqlite-meta.c
   trunk/libgda/sqlite/sqlite-src/PragmasPatch
   trunk/libgda/sqlite/sqlite-src/sqlite3.c
   trunk/providers/postgres/gda-postgres-meta.c
   trunk/tools/Makefile.am
   trunk/tools/command-exec.c
   trunk/tools/command-exec.h
   trunk/tools/gda-sql.c

Modified: trunk/doc/C/gda-sql-manual.xml
==============================================================================
--- trunk/doc/C/gda-sql-manual.xml	(original)
+++ trunk/doc/C/gda-sql-manual.xml	Sat Sep 20 12:35:00 2008
@@ -119,6 +119,56 @@
     </para>
   </sect1>
 
+  <sect1>
+    <title>Commands</title>
+    <para>
+      The console tool allows the user to enter SQL commands (which can span several lines and must be terminated with
+      a semi colon). The commands are executed synchronously and the results displayed right after execution, for example:
+      <programlisting>
+cnc1> select *
+    > from customers order by name;
+id | name            | last_update           | default_served_by | country | city
+---+-----------------+-----------------------+-------------------+---------+-----
+ 2 | Ed Lamton       | 2008-08-12 00:00:00+0 |                 4 | SP      | MDR 
+ 9 | Greg Popoff     | 2007-12-25 00:00:00+0 |                 2 | SP      | MDR 
+ 3 | Lew Bonito      | 2008-08-13 00:00:00+0 |                 1 | FR      | TLS 
+ 4 | Mark Lawrencep  | 2007-12-25 00:00:00+0 |                   | SP      | MDR 
+10 | Vladimir Zirkov | 2001-01-31 00:00:00+0 |                 4 |         |     
+(5 rows)
+
+cnc1>
+      </programlisting>
+      The SQL dialect to be used must be understood by the database to which the connection is opened, so
+      it is possible to use database's specific commands, for example with a PostgreSQL database:
+      <programlisting>
+cnc2> show search_path;
+search_path   
+--------------
+"$user",public
+(1 row)
+
+cnc2>
+      </programlisting>
+    </para>
+    <para>
+      There are also some internal commands which all start either with a dot or backslash and perform some
+      actions such as changing the default output mode (to HTML for example) or getting meta information
+      about the database structure. For example, use the <command>.?</command> to display a help message
+      about all internal commands (with truncated output here):
+      <programlisting>
+gda> .?
+Formatting
+  \H [HTML|XML|CSV|DEFAULT]
+                     Set output format
+
+General
+  \?                 List all available commands
+  \bind CNC_NAME CNC_NAME1 CNC_NAME2 [CNC_NAME ...]
+                     Bind several connections together into the CNC_NAME virtual connection
+      </programlisting>
+    </para>
+  </sect1>
+
 </chapter>
 
 <chapter id="gda-sql-manual-open">
@@ -157,6 +207,80 @@
   </para>
 
   <sect1>
+    <title>Virtual connections</title>
+    <para>
+      Multiple connections can be <emphasis>bound together</emphasis> into a single connection in which it is possible
+      to runs SQL statements. This effectively allows one to run SQL statements across multiple databases.
+    </para>
+    <para>
+      Binding connections together is done using the <command>.bind CNC_NAME CNC_NAME1 CNC_NAME2 [CNC_NAME ...]</command>
+      command which creates new connection named "CNC_NAME" which binds the connections names "CNC_NAME1" and "CNC_NAME2"
+      together (more connections can be bound); each connection to be bound into a virtual connection must of course
+      already have been opened. The tables of each bound connection will appear into the new virtual connection as named
+      "&lt;cnc name&gt;.&lt;table name&gt;".
+    </para>
+    <para>
+      In the following example, there are the "cnc1" and "cnc2" connections opened, and the "cnc3" connection is
+      a virtual connection binding "cnc1" and "cnc2":
+      <programlisting>
+cnc2> .bind cnc3 cnc1 cnc2
+Bound connections are as:
+   cnc1 in the 'cnc1' namespace
+   cnc2 in the 'cnc2' namespace
+cnc3> .c
+          List of opened connections
+Name | Provider | DSN or connection string | Username
+-----+----------+--------------------------+---------
+cnc1 | SQLite   | DB_DIR=.;DB_NAME=pmodel  |         
+cnc2 | SQLite   | SalesTest                |         
+cnc3 |          | namespace cnc1           |         
+                  namespace cnc2                     
+(3 rows)
+
+cnc3> 
+      </programlisting>
+      The contents of each "customers" table in each of the bound connection is accessible:
+      <programlisting>
+cnc3> select * from cnc1.customers;
+id | name            | last_update           | default_served_by | country | city
+---+-----------------+-----------------------+-------------------+---------+-----
+ 2 | Ed Lamton       | 2008-08-12 00:00:00+0 |                 4 | SP      | MDR 
+ 3 | Lew Bonito      | 2008-08-13 00:00:00+0 |                 1 | FR      | TLS 
+ 4 | Mark Lawrencep  | 2007-12-25 00:00:00+0 |                   | SP      | MDR 
+ 9 | Greg Popoff     | 2007-12-25 00:00:00+0 |                 2 | SP      | MDR 
+10 | Vladimir Zirkov | 2001-01-31 00:00:00+0 |                 4 |         |     
+(5 rows)
+
+cnc3>  select * from cnc2.customers;
+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 
+10 | Vladimir Zirkov |                 4 |         |     
+(5 rows)
+
+cnc3> 
+      </programlisting>
+      The list of customers present in both tables are available as:
+      <programlisting>
+cnc3> SELECT * FROM cnc1.customers WHERE name IN (SELECT name FROM cnc2.customers);
+id | name            | last_update           | default_served_by | country | city
+---+-----------------+-----------------------+-------------------+---------+-----
+ 2 | Ed Lamton       | 2008-08-12 00:00:00+0 |                 4 | SP      | MDR 
+ 3 | Lew Bonito      | 2008-08-13 00:00:00+0 |                 1 | FR      | TLS 
+ 4 | Mark Lawrencep  | 2007-12-25 00:00:00+0 |                   | SP      | MDR 
+ 9 | Greg Popoff     | 2007-12-25 00:00:00+0 |                 2 | SP      | MDR 
+10 | Vladimir Zirkov | 2001-01-31 00:00:00+0 |                 4 |         |     
+(5 rows)
+
+cnc3>
+      </programlisting>
+    </para>
+  </sect1>
+
+  <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
@@ -173,7 +297,8 @@
       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:
+      you want to access the meta data, and then use the <command>.c ~</command> command (note that the same command will
+      return to the "cnc1" connection):
       <programlisting>
 cnc1> .c ~
 Getting database schema information, this may take some time... Done.
@@ -224,7 +349,20 @@
 products_copied
 (11 rows)
 
-~cnc1>
+~cnc1> .c ~
+cnc1>
+      </programlisting>
+      Also note that the meta data's connections are listed among the opened connections, as shown:
+      <programlisting>
+cnc1> .c
+                       List of opened connections
+Name  | Provider | DSN or connection string                              | Username
+------+----------+-------------------------------------------------------+---------
+cnc1  | SQLite   | SalesTest                                             |         
+~cnc1 | SQLite   | DB_DIR=/home/vivien/.libgda;DB_NAME=gda-sql-SalesTest |         
+(2 rows)
+
+cnc1>
       </programlisting>
     </para>
     
@@ -307,30 +445,217 @@
     <sect2>
       <title>Information about views</title>
       <para>
+	The console tool can report information about views. Use the <command>.dv</command> command to list all the views
+	(or list only one view if the view name is specified as	an argument to the command):
+	<programlisting>
+cnc1> .dv
+              List of views
+Schema | Name         | Type | Owner | Description
+-------+--------------+------+-------+------------
+main   | cust_summary | VIEW |       |            
+(1 row)
+
+cnc1>
+	</programlisting>
+      </para>
+      <para>
+	One can also get more information for a single view using the <command>.d &lt;view name&gt;</command> command, 
+	for example:
+	<programlisting>
+cnc1> .d cust_summary 
+List of columns for view 'cust_summary'
+Column   | Type   | Nullable | Default | Extra
+---------+--------+----------+---------+------
+name     | string | yes      |         |      
+shortcut | string | yes      |         |      
+(2 rows)
+
+View definition: CREATE VIEW cust_summary as SELECT c.name, l.shortcut FROM customers c LEFT JOIN locations l ON (c.country=l.country AND c.city=l.city)
+cnc1>
+	</programlisting>
+      </para>
+    </sect2>
+
+    <sect2>
+      <title>Information about schemas</title>
+      <para>
+	Some databases feature the notion of <emphasis>schema</emphasis> which is a container for database objects such as
+	tables, views, etc. Use the <command>.dn</command> command to get a list of all the schemas in a database. For
+	example with a PostgreSQL database:
+	<programlisting>
+          List of schemas
+Schema             | Owner    | Internal
+-------------------+----------+---------
+information_schema | postgres | yes     
+pg_catalog         | postgres | yes     
+pg_temp_1          | postgres | yes     
+pg_toast           | postgres | yes     
+pg_toast_temp_1    | postgres | yes     
+public             | postgres | no      
+(6 rows)
+
+cnc1>
+	</programlisting>
       </para>
     </sect2>
 
     <sect2>
       <title>Information about other objects</title>
       <para>
+	The meta data database holds a lot of information about the many objects which exist in a database, but the
+	console tool does not provide internal commands to display all of them. The solution is to run SELECT commands
+	in the meta data connection associated to a connection. For example to get a list of triggers where the "cnc2"
+	is a connection opened to a PostgreSQL's database, one first needs to connection to the meta data connection
+	and lookup into the "_triggers" table:
+	<programlisting>
+cnc2> .c ~
+~cnc2> select trigger_name, event_manipulation, event_object_table from _triggers;
+trigger_name            | event_manipulation | event_object_table
+------------------------+--------------------+-------------------
+pg_sync_pg_database     | INSERT             | pg_database       
+pg_sync_pg_database     | DELETE             | pg_database       
+pg_sync_pg_database     | UPDATE             | pg_database       
+pg_sync_pg_authid       | INSERT             | pg_authid         
+pg_sync_pg_authid       | DELETE             | pg_authid         
+pg_sync_pg_authid       | UPDATE             | pg_authid         
+pg_sync_pg_auth_members | INSERT             | pg_auth_members   
+pg_sync_pg_auth_members | DELETE             | pg_auth_members   
+pg_sync_pg_auth_members | UPDATE             | pg_auth_members   
+(9 rows)
+
+~cnc2>
+	</programlisting>
+      </para>
+      <para>
+	The meta data's database structure is described in the <link linkend="information_schema">related section</link>.
       </para>
     </sect2>
   </sect1>
-
 </chapter>
 
-<chapter id="gda-sql-manual-commands">
-  <title>Executing commands</title>
+<chapter id="gda-sql-manual-icommands">
+  <title>Detailled features</title>
   <para>
-    Blah.
+    This section explains in depth various aspects of the console tool.
   </para>
 
   <sect1>
-    <title>SQL comands</title>
+    <title>Query buffer</title>
+    <para>
+      Everytime an SQL command is entered, it is stored in the query buffer associated to the current connection. 
+      The query buffer can be edited using an external editor (which can be usefull for multi line SQL statements) using
+      the <command>.e</command> command. The query buffer can also be saved to a file and loaded back later using the
+      <command>.qw</command> and <command>.qr</command> commands. To execute the SQL held in the current query byffer,
+      use the <command>.g</command> command.
+    </para>
+    <para>
+      Query buffers can be saved to the dictionary (along with the connection's meta data) for future usage using the
+      <command>.qs buffer_name</command> command, and loaded back later with the <command>.ql buffer_name</command>.
+      To list all the saved query buffers in the dictionary, use the <command>.qa</command> command. The following example
+      shows an example output of the <command>.qa</command> command where one query buffer has been saved:
+      <programlisting>
+SalesTest> .qa
+Query buffer name | SQL                                                                                   
+------------------+---------------------------------------------------------------------------------------
+orders_status     | select c.name, o.creation_date ,                                                      
+                    (select count (product_ref) from order_contents oc where oc.order_id=o.id) as '#items'
+                    from customers c                                                                      
+                    	inner join orders o on (o.customer = c.id)                                           
+                    order by o.creation_date;                                                             
+                                                                                                          
+(1 row)
+
+SalesTest>
+      </programlisting>
+    </para>
+    <para>
+      The <command>.g</command> command can also be used to load a query buffer and execute its contents simply
+      by passing the name of the query buffer to use as argument:
+      <programlisting>
+SalesTest> .g orders_status
+name           | creation_date | #items
+---------------+---------------+-------
+Lew Bonito     | 2003-06-28    |      1
+Lew Bonito     | 2004-02-02    |      2
+Mark Lawrencep | 2004-02-02    |      2
+Mark Lawrencep | 2004-02-02    |      0
+Greg Popoff    | 2004-02-02    |      1
+Ed Lamton      | 2006-02-04    |      0
+Ed Lamton      | 2006-02-05    |      0
+Ed Lamton      | 2006-02-05    |      0
+Ed Lamton      | 2006-03-29    |      0
+(9 rows)
+
+SalesTest>
+      </programlisting>
+    </para>
+  </sect1>
+
+  <sect1>
+    <title>Internal parameters</title>
+    <para>
+      Variables can be defined using the <command>.set</command> command. Variables are then automatically looked for
+      when executing SQL statements for which a variable is required; they are not typed and are converted to 
+      the correct type when needed. Note that variables are shared by all the opened connections.
+    </para>
+    <para>
+      Use the <command>.set &lt;variablename&gt; &lt;variable value&gt;</command> command to define a variable,
+      and the <command>.set</command> command to list all defined variables. The following example illustrates
+      variables usage:
+      <programlisting>
+SalesTest> select * from customers where id = ##theid::int;
+ERROR: No internal parameter named 'theid' required by query
+SalesTest> .set theid 3
+SalesTest> select * from customers where id = ##theid::int;
+id | name       | default_served_by | country | city
+---+------------+-------------------+---------+-----
+ 3 | Lew Bonito |                 1 | FR      | TLS 
+(1 row)
+
+SalesTest> .set theid 5
+SalesTest> select * from customers where id = ##theid::int;
+id | name | default_served_by | country | city
+---+------+-------------------+---------+-----
+(0 rows)
+
+SalesTest> .set
+List of defined parameters
+Name  | Value
+------+------
+theid | 5    
+(1 row)
+
+SalesTest>
+    </programlisting>
+    </para>
   </sect1>
 
   <sect1>
-    <title>Internal commands</title>
+    <title>Environment variables</title>
+    <para>
+      Several environment variables can be used to customize the behaviour of the console tool (added
+      to the <link linkend="libgda_env_variables">general &LIBGDA;'s environment variables</link>):
+      <itemizedlist>
+	<listitem><para>Upon starting, if the <envar>GDA_SQL_CNC</envar> environment variable is defined,
+	    the console tool will try to open a connection using its contents as connection string.
+	</para></listitem>
+	<listitem><para>The external editor used by the <command>.e</command> command is determined by the first value
+	    present in the <envar>GDA_SQL_EDITOR</envar>, <envar>EDITOR</envar> or <envar>VISUAL</envar>
+	    environment variables (in that order), and defaults to "vi" undex Unix and "notepad.exe" under Windows.
+	</para></listitem>
+	<listitem><para>The pager used when the data to display is more than one screen is determined by
+	    the value of the <envar>PAGER</envar> environment variable and defaults to "more" if none is defined.
+	    The paging feature can be completely disabled if the <envar>GDA_NO_PAGER</envar> is defined.</para></listitem>
+	<listitem><para>When the <command>.graph</command> is run, and if the GraphViz's <command>dot</command> is found,
+	    the console tool will convert the graph to a PNG file and display it using the external viewer 
+	    identified by the contents of the <envar>GDA_SQL_VIEWER_PNG</envar> variable if defined (or convert it to a PDF
+	    and display it using the external viewer 
+	    identified by the contents of the <envar>GDA_SQL_VIEWER_PDF</envar> variable if defined).
+	</para></listitem>
+	<listitem><para>The command line history file is defined by the contents of the <envar>GDA_SQL_HISTFILE</envar>
+	    environment variable. If its contents is set to "NO_HISTORY" then no history will be kept.</para></listitem>
+      </itemizedlist>
+    </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	Sat Sep 20 12:35:00 2008
@@ -451,8 +451,9 @@
 	      files are shared libraries)</para>
 	    </listitem>
 	    <listitem>
-              <para>LIBGDA_NO_THREADS: if set, then multi threading will be disabled (note that &LIBGDA; is not thread safe,
-	      but usually internally uses threads when possible to perform actions in a non blocking way)</para>
+              <para>LIBGDA_NO_THREADS: if set, then multi threading will be disabled (see the 
+		<link linkend="threads">section about multi threading</link> for more information about
+		&LIBGDA; threads' support).</para>
 	    </listitem>
 	    <listitem>
               <para>GDA_DATA_MODEL_DUMP_TITLE: if set, then <link linkend="gda-data-model-dump">gda_data_model_dump()</link>

Modified: trunk/libgda/gda-connection.c
==============================================================================
--- trunk/libgda/gda-connection.c	(original)
+++ trunk/libgda/gda-connection.c	Sat Sep 20 12:35:00 2008
@@ -3042,7 +3042,8 @@
 					g_print ("TH %p CNC %p ERROR, prov=%p (%s)\n", g_thread_self(), cnc,
 						 gda_connection_get_provider (cnc),
 						 gda_connection_get_provider_name (cnc));
-					g_warning ("//");
+					if (error && *error)
+						g_warning ("// %s\n", (*error)->message);
 
 					WARN_META_UPDATE_FAILURE (FALSE, rmeta [i].func_name);
 					goto onerror;

Modified: trunk/libgda/gda-meta-struct.c
==============================================================================
--- trunk/libgda/gda-meta-struct.c	(original)
+++ trunk/libgda/gda-meta-struct.c	Sat Sep 20 12:35:00 2008
@@ -563,7 +563,8 @@
 		if (!dbo->obj_owner) {
 			cvalue = gda_data_model_get_value_at (model, 4, 0, error);
 			if (!cvalue) goto onerror;
-			dbo->obj_owner = g_value_dup_string (cvalue);
+			if (!gda_value_is_null (cvalue))
+				dbo->obj_owner = g_value_dup_string (cvalue);
 		}
 
 		mv = GDA_META_VIEW (dbo);

Modified: trunk/libgda/sqlite/gda-sqlite-meta.c
==============================================================================
--- trunk/libgda/sqlite/gda-sqlite-meta.c	(original)
+++ trunk/libgda/sqlite/gda-sqlite-meta.c	Sat Sep 20 12:35:00 2008
@@ -137,6 +137,56 @@
 	g_static_mutex_unlock (&init_mutex);
 }
 
+static GdaStatement *
+get_statement (InternalStatementItem type, const gchar *schema_name, const gchar *obj_name, GError **error)
+{
+	GdaStatement *stmt;
+	if (strcmp (schema_name, "main")) {
+		gchar *str;
+		
+		switch (type) {
+		case I_PRAGMA_TABLE_INFO:
+			str = g_strdup_printf ("PRAGMA %s.table_info (%s)", schema_name, obj_name);
+			break;
+		case I_PRAGMA_INDEX_LIST:
+			str = g_strdup_printf ("PRAGMA %s.index_list (%s)", schema_name, obj_name);
+			break;
+		case I_PRAGMA_INDEX_INFO:
+			str = g_strdup_printf ("PRAGMA %s.index_info (%s)", schema_name, obj_name);
+			break;
+		case I_PRAGMA_FK_LIST:
+			str = g_strdup_printf ("PRAGMA %s.foreign_key_list (%s)", schema_name, obj_name);
+			break;
+		default:
+			g_assert_not_reached ();
+		}
+		
+		stmt = gda_sql_parser_parse_string (internal_parser, str, NULL, NULL);
+		g_free (str);
+		g_assert (stmt);
+	}
+	else {
+		switch (type) {
+		case I_PRAGMA_TABLE_INFO:
+		case I_PRAGMA_INDEX_LIST:
+		case I_PRAGMA_FK_LIST:
+			if (! gda_set_set_holder_value (pragma_set, error, "tblname", obj_name))
+				return NULL;
+			break;
+		case I_PRAGMA_INDEX_INFO:
+			if (! gda_set_set_holder_value (pragma_set, error, "idxname", obj_name))
+				return NULL;
+			break;
+		default:
+			g_assert_not_reached ();
+		}
+
+		stmt = g_object_ref (internal_stmt [type]);
+	}
+
+	return stmt;
+}
+
 gboolean
 _gda_sqlite_meta__info (GdaServerProvider *prov, GdaConnection *cnc, 
 			GdaMetaStore *store, GdaMetaContext *context, GError **error)
@@ -278,7 +328,7 @@
 		gint fields_status;
 
 		if (strcmp (cstr, "main")) 
-			sql = g_strdup_printf ("PRAGMA table_info('%s.%s');", cstr, sqlite3_column_text (tables_stmt, 0));
+			sql = g_strdup_printf ("PRAGMA %s.table_info(%s);", cstr, sqlite3_column_text (tables_stmt, 0));
 		else
 			sql = g_strdup_printf ("PRAGMA table_info('%s');", sqlite3_column_text (tables_stmt, 0));
 		fields_status = sqlite3_prepare_v2 (cdata->connection, sql, -1, &fields_stmt, NULL);
@@ -808,25 +858,14 @@
 	gint i;
 	GType col_types[] = {G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, 
 			     G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_NONE};
+	GdaStatement *stmt;
 	
 	schema_name = g_value_get_string (p_table_schema);
-	if (strcmp (schema_name, "main")) {
-		gchar *str;
-		str = g_strdup_printf ("%s.%s", schema_name, g_value_get_string (p_table_name));
-		if (! gda_set_set_holder_value (pragma_set, error, "tblname", str)) {
-			g_free (str);
-			return FALSE;
-		}
-		g_free (str);
-	}
-	else {
-		if (! gda_set_set_holder_value (pragma_set, error, "tblname", g_value_get_string (p_table_name)))
-			return FALSE;
-	}
-
-	tmpmodel = gda_connection_statement_execute_select_full (cnc, internal_stmt[I_PRAGMA_TABLE_INFO], pragma_set, 
+	stmt = get_statement (I_PRAGMA_TABLE_INFO, schema_name, g_value_get_string (p_table_name), error);
+	tmpmodel = gda_connection_statement_execute_select_full (cnc, stmt, pragma_set, 
 								 GDA_STATEMENT_MODEL_RANDOM_ACCESS, 
 								 col_types, error);
+	g_object_unref (stmt);
 	if (!tmpmodel)
 		return FALSE;
 		
@@ -1078,24 +1117,9 @@
 	gint nrows;
 	const gchar *schema_name;
 	gint i;
+	GdaStatement *stmt;
 
-	/*
-	 * Setup pragma_set
-	 */
 	schema_name = g_value_get_string (p_table_schema);
-	if (strcmp (schema_name, "main")) {
-		gchar *str;
-		str = g_strdup_printf ("%s.%s", schema_name, g_value_get_string (p_table_name));
-		if (! gda_set_set_holder_value (pragma_set, error, "tblname", str)) {
-			g_free (str);
-			return FALSE;
-		}
-		g_free (str);
-	}
-	else {
-		if (!gda_set_set_holder_value (pragma_set, error, "tblname", g_value_get_string (p_table_name)))
-			return FALSE;
-	}	
 
 	/* 
 	 * PRIMARY KEY
@@ -1106,9 +1130,11 @@
 				G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_NONE};
 	gboolean has_pk = FALSE;
 
-	tmpmodel = gda_connection_statement_execute_select_full (cnc, internal_stmt[I_PRAGMA_TABLE_INFO], pragma_set, 
+	stmt = get_statement (I_PRAGMA_TABLE_INFO, schema_name, g_value_get_string (p_table_name), error);
+	tmpmodel = gda_connection_statement_execute_select_full (cnc, stmt, pragma_set, 
 								 GDA_STATEMENT_MODEL_RANDOM_ACCESS, 
 								 pk_col_types, error);
+	g_object_unref (stmt);
 	if (!tmpmodel)
 		return FALSE;
 		
@@ -1183,9 +1209,11 @@
 	 */
 	GType unique_col_types[] = {G_TYPE_INT, G_TYPE_STRING, G_TYPE_INT, G_TYPE_NONE};
 	
-	tmpmodel = gda_connection_statement_execute_select_full (cnc, internal_stmt[I_PRAGMA_INDEX_LIST], pragma_set, 
+	stmt = get_statement (I_PRAGMA_INDEX_LIST, schema_name, g_value_get_string (p_table_name), error);
+	tmpmodel = gda_connection_statement_execute_select_full (cnc, stmt, pragma_set, 
 								 GDA_STATEMENT_MODEL_RANDOM_ACCESS, 
 								 unique_col_types, error);
+	g_object_unref (stmt);
 	if (!tmpmodel)
 		return FALSE;
 		
@@ -1234,9 +1262,11 @@
 	 */
 	GType fk_col_types[] = {G_TYPE_INT, G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_NONE};
 	gchar *ref_table = NULL;
-	tmpmodel = gda_connection_statement_execute_select_full (cnc, internal_stmt[I_PRAGMA_FK_LIST], pragma_set, 
+	stmt = get_statement (I_PRAGMA_FK_LIST, schema_name, g_value_get_string (p_table_name), error);
+	tmpmodel = gda_connection_statement_execute_select_full (cnc, stmt, pragma_set, 
 								 GDA_STATEMENT_MODEL_RANDOM_ACCESS, 
 								 fk_col_types, error);
+	g_object_unref (stmt);
 	if (!tmpmodel)
 		return FALSE;
 		
@@ -1403,30 +1433,20 @@
 	gint nrows;
 	const gchar *schema_name;
 	gint i;
+	GdaStatement *stmt;
 
 	/*
-	 * Setup pragma_set
+	 * Setup stmt to execute
 	 */
 	schema_name = g_value_get_string (p_table_schema);
-	if (strcmp (schema_name, "main")) {
-		gchar *str;
-		str = g_strdup_printf ("%s.%s", schema_name, g_value_get_string (p_table_name));
-		if (! gda_set_set_holder_value (pragma_set, error, "tblname", str)) {
-			g_free (str);
-			return FALSE;
-		}
-		g_free (str);
-	}
-	else {
-		if (! gda_set_set_holder_value (pragma_set, error, "tblname", g_value_get_string (p_table_name)))
-			return FALSE;
-	}
 
 	GType fk_col_types[] = {G_TYPE_INT, G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_NONE};
 	gchar *ref_table = NULL;
-	tmpmodel = gda_connection_statement_execute_select_full (cnc, internal_stmt[I_PRAGMA_FK_LIST], pragma_set, 
+	stmt = get_statement (I_PRAGMA_FK_LIST, schema_name, g_value_get_string (p_table_name), error);
+	tmpmodel = gda_connection_statement_execute_select_full (cnc, stmt, pragma_set, 
 								 GDA_STATEMENT_MODEL_RANDOM_ACCESS, 
 								 fk_col_types, error);
+	g_object_unref (stmt);
 	if (!tmpmodel)
 		return FALSE;
 		
@@ -1595,25 +1615,9 @@
 	gint nrows;
 	const gchar *schema_name, *const_name;
 	gint i;
+	GdaStatement *stmt;
 
-	/*
-	 * Setup pragma_set
-	 */
 	schema_name = g_value_get_string (p_table_schema);
-	if (strcmp (schema_name, "main")) {
-		gchar *str;
-		str = g_strdup_printf ("%s.%s", schema_name, g_value_get_string (p_table_name));
-		if (! gda_set_set_holder_value (pragma_set, error, "tblname", str)) {
-			g_free (str);
-			return FALSE;
-		}
-		g_free (str);
-	}
-	else {
-		if (! gda_set_set_holder_value (pragma_set, error, "tblname", g_value_get_string (p_table_name)))
-			return FALSE;
-	}
-
 	const_name = g_value_get_string (constraint_name);
 	if (!strcmp (const_name, "primary_key")) {
 		/* 
@@ -1622,9 +1626,11 @@
 		GType pk_col_types[] = {G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, 
 					G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_NONE};
 		gint ord_pos = 1;
-		tmpmodel = gda_connection_statement_execute_select_full (cnc, internal_stmt[I_PRAGMA_TABLE_INFO], pragma_set, 
+		stmt = get_statement (I_PRAGMA_TABLE_INFO, schema_name, g_value_get_string (p_table_name), error);
+		tmpmodel = gda_connection_statement_execute_select_full (cnc, stmt, pragma_set, 
 									 GDA_STATEMENT_MODEL_RANDOM_ACCESS, 
 									 pk_col_types, error);
+		g_object_unref (stmt);
 		if (!tmpmodel)
 			return FALSE;
 		
@@ -1691,9 +1697,11 @@
 		GType fk_col_types[] = {G_TYPE_INT, G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_NONE};
 		gchar *ref_table = NULL;
 		gint ord_pos;
-		tmpmodel = gda_connection_statement_execute_select_full (cnc, internal_stmt[I_PRAGMA_FK_LIST], pragma_set, 
+		stmt = get_statement (I_PRAGMA_FK_LIST, schema_name, g_value_get_string (p_table_name), error);
+		tmpmodel = gda_connection_statement_execute_select_full (cnc, stmt, pragma_set, 
 									 GDA_STATEMENT_MODEL_RANDOM_ACCESS, 
 									 fk_col_types, error);
+		g_object_unref (stmt);
 		if (!tmpmodel)
 			return FALSE;
 		
@@ -1747,11 +1755,12 @@
 		 */
 		GType unique_col_types[] = {G_TYPE_INT, G_TYPE_INT, G_TYPE_STRING, G_TYPE_NONE};
 		
-		if (! gda_set_set_holder_value (pragma_set, error, "idxname", g_value_get_string (constraint_name)))
-			return FALSE;
-		tmpmodel = gda_connection_statement_execute_select_full (cnc, internal_stmt[I_PRAGMA_INDEX_INFO], pragma_set, 
+		stmt = get_statement (I_PRAGMA_INDEX_INFO, schema_name, g_value_get_string (constraint_name),
+				      error);
+		tmpmodel = gda_connection_statement_execute_select_full (cnc, stmt, pragma_set, 
 									 GDA_STATEMENT_MODEL_RANDOM_ACCESS, 
 									 unique_col_types, error);
+		g_object_unref (stmt);
 		if (!tmpmodel)
 			return FALSE;
 		

Modified: trunk/libgda/sqlite/sqlite-src/PragmasPatch
==============================================================================
--- trunk/libgda/sqlite/sqlite-src/PragmasPatch	(original)
+++ trunk/libgda/sqlite/sqlite-src/PragmasPatch	Sat Sep 20 12:35:00 2008
@@ -1,6 +1,6 @@
 --- sqlite3.c.orig	2008-08-30 18:23:34.000000000 +0200
-+++ sqlite3.c	2008-09-15 12:03:08.000000000 +0200
-@@ -66756,6 +66756,48 @@
++++ sqlite3.c	2008-09-19 21:52:35.000000000 +0200
+@@ -66756,6 +66756,64 @@
  
  #ifndef SQLITE_OMIT_SCHEMA_PRAGMAS
    /*
@@ -26,22 +26,38 @@
 +    sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "is_aggregate", P4_STATIC);
 +    sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "nargs", P4_STATIC);
 +    sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "spe_name", P4_STATIC);
-+
-+    for (func_elem = sqliteHashFirst (func_hash); func_elem ; func_elem = sqliteHashNext (func_elem)) {
++    int j;
++    for(j=0; j<ArraySize(db->aFunc.a); j++){
 +      FuncDef *func;
-+      char *sname;
-+      int size;
-+      func = sqliteHashData (func_elem);
-+
-+      size = strlen (func->zName) + 25;
-+      sname = sqlite3_malloc (sizeof (char) * size);
-+      snprintf (sname, size-1, "%s_%d_%d", func->zName, func->nArg, func->iPrefEnc);
-+      sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, func->zName, 0);
-+      sqlite3VdbeAddOp2(v, OP_Integer, func->xFinalize ? 1 : 0, 2);
-+      sqlite3VdbeAddOp2(v, OP_Integer, func->nArg, 3);
-+      sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, sname, 0);
-+      sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
-+      sqlite3_free (sname);
++      for (func =db->aFunc.a[j]; func; func = func->pNext) {
++	char *sname;
++	int size;
++	size = strlen (func->zName) + 25;
++	sname = sqlite3_malloc (sizeof (char) * size);
++	snprintf (sname, size-1, "%s_%d_%d", func->zName, func->nArg, func->iPrefEnc);
++	sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, func->zName, 0);
++	sqlite3VdbeAddOp2(v, OP_Integer, func->xFinalize ? 1 : 0, 2);
++	sqlite3VdbeAddOp2(v, OP_Integer, func->nArg, 3);
++	sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, sname, 0);
++	sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
++	sqlite3_free (sname);
++      }
++    }
++    for(j=0; j<ArraySize(sqlite3GlobalFunctions.a); j++){
++      FuncDef *func;
++      for (func =sqlite3GlobalFunctions.a[j]; func; func = func->pNext) {
++	char *sname;
++	int size;
++	size = strlen (func->zName) + 25;
++	sname = sqlite3_malloc (sizeof (char) * size);
++	snprintf (sname, size-1, "%s_%d_%d", func->zName, func->nArg, func->iPrefEnc);
++	sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, func->zName, 0);
++	sqlite3VdbeAddOp2(v, OP_Integer, func->xFinalize ? 1 : 0, 2);
++	sqlite3VdbeAddOp2(v, OP_Integer, func->nArg, 3);
++	sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, sname, 0);
++	sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
++	sqlite3_free (sname);
++      }
 +    }
 +  }else
 +

Modified: trunk/libgda/sqlite/sqlite-src/sqlite3.c
==============================================================================
--- trunk/libgda/sqlite/sqlite-src/sqlite3.c	(original)
+++ trunk/libgda/sqlite/sqlite-src/sqlite3.c	Sat Sep 20 12:35:00 2008
@@ -66778,22 +66778,38 @@
     sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "is_aggregate", P4_STATIC);
     sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "nargs", P4_STATIC);
     sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "spe_name", P4_STATIC);
-
-    for (func_elem = sqliteHashFirst (func_hash); func_elem ; func_elem = sqliteHashNext (func_elem)) {
+    int j;
+    for(j=0; j<ArraySize(db->aFunc.a); j++){
+      FuncDef *func;
+      for (func =db->aFunc.a[j]; func; func = func->pNext) {
+	char *sname;
+	int size;
+	size = strlen (func->zName) + 25;
+	sname = sqlite3_malloc (sizeof (char) * size);
+	snprintf (sname, size-1, "%s_%d_%d", func->zName, func->nArg, func->iPrefEnc);
+	sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, func->zName, 0);
+	sqlite3VdbeAddOp2(v, OP_Integer, func->xFinalize ? 1 : 0, 2);
+	sqlite3VdbeAddOp2(v, OP_Integer, func->nArg, 3);
+	sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, sname, 0);
+	sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
+	sqlite3_free (sname);
+      }
+    }
+    for(j=0; j<ArraySize(sqlite3GlobalFunctions.a); j++){
       FuncDef *func;
-      char *sname;
-      int size;
-      func = sqliteHashData (func_elem);
-
-      size = strlen (func->zName) + 25;
-      sname = sqlite3_malloc (sizeof (char) * size);
-      snprintf (sname, size-1, "%s_%d_%d", func->zName, func->nArg, func->iPrefEnc);
-      sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, func->zName, 0);
-      sqlite3VdbeAddOp2(v, OP_Integer, func->xFinalize ? 1 : 0, 2);
-      sqlite3VdbeAddOp2(v, OP_Integer, func->nArg, 3);
-      sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, sname, 0);
-      sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
-      sqlite3_free (sname);
+      for (func =sqlite3GlobalFunctions.a[j]; func; func = func->pNext) {
+	char *sname;
+	int size;
+	size = strlen (func->zName) + 25;
+	sname = sqlite3_malloc (sizeof (char) * size);
+	snprintf (sname, size-1, "%s_%d_%d", func->zName, func->nArg, func->iPrefEnc);
+	sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, func->zName, 0);
+	sqlite3VdbeAddOp2(v, OP_Integer, func->xFinalize ? 1 : 0, 2);
+	sqlite3VdbeAddOp2(v, OP_Integer, func->nArg, 3);
+	sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, sname, 0);
+	sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
+	sqlite3_free (sname);
+      }
     }
   }else
 

Modified: trunk/providers/postgres/gda-postgres-meta.c
==============================================================================
--- trunk/providers/postgres/gda-postgres-meta.c	(original)
+++ trunk/providers/postgres/gda-postgres-meta.c	Sat Sep 20 12:35:00 2008
@@ -174,10 +174,10 @@
 	"select pg_catalog.current_database(), n.nspname, udt.typname, a.attname, a.attnum, CASE WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN NULL ELSE coalesce (nt.nspname || '.', '') || t.typname END, CASE WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN 'UDT' || current_database() || '.' || n.nspname || '.' || udt.typname || '.' || a.attnum ELSE NULL END, information_schema._pg_char_max_length(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_char_octet_length(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_numeric_precision(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_numeric_scale(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_datetime_precision(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truety
 pmod(a.*, t.*)), NULL, NULL , NULL, NULL, NULL, NULL FROM pg_type udt INNER JOIN pg_namespace n ON (udt.typnamespace=n.oid) INNER JOIN pg_attribute a ON (a.attrelid=udt.typrelid) INNER JOIN pg_type t ON (a.atttypid=t.oid) INNER JOIN pg_namespace nt ON (t.typnamespace = nt.oid) WHERE udt.typrelid != 0 AND (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = udt.typrelid)",
 
 	/* I_STMT_DOMAINS */
-	"SELECT pg_catalog.current_database(), nt.nspname, t.typname, CASE WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN NULL ELSE coalesce (nbt.nspname || '.', '') || bt.typname END, CASE WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN 'DOM' || current_database() || '.' || nt.nspname || '.' || t.typname ELSE NULL END, 'gchararray', information_schema._pg_char_max_length(t.typbasetype, t.typtypmod), information_schema._pg_char_octet_length(t.typbasetype, t.typtypmod),  NULL, NULL, NULL, NULL, NULL, NULL,  information_schema._pg_numeric_precision(t.typbasetype, t.typtypmod), information_schema._pg_numeric_scale(t.typbasetype, t.typtypmod), t.typdefault, pg_catalog.obj_description(t.oid), CASE WHEN pg_catalog.pg_type_is_visible(t.oid) IS TRUE THEN t.typname ELSE coalesce (nt.nspname || '.', '') || t.typname END, coalesce (nt.nspname || '.', '') || t.typname, o.rolname FROM pg_type t, pg_namespace nt, pg_type bt, pg_namespace nbt, pg_authid o WHERE t.typnamespace = nt.oid AND t.typb
 asetype = bt.oid AND bt.typnamespace = nbt.oid AND t.typtype = 'd' AND o.oid=t.typowner AND pg_catalog.current_database() = ##cat::string AND nt.nspname = ##schema::string", 
+	"SELECT pg_catalog.current_database(), nt.nspname, t.typname, CASE WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN NULL ELSE coalesce (nbt.nspname || '.', '') || bt.typname END, CASE WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN 'DOM' || current_database() || '.' || nt.nspname || '.' || t.typname ELSE NULL END, 'gchararray', information_schema._pg_char_max_length(t.typbasetype, t.typtypmod), information_schema._pg_char_octet_length(t.typbasetype, t.typtypmod),  NULL, NULL, NULL, NULL, NULL, NULL,  information_schema._pg_numeric_precision(t.typbasetype, t.typtypmod), information_schema._pg_numeric_scale(t.typbasetype, t.typtypmod), t.typdefault, pg_catalog.obj_description(t.oid), CASE WHEN pg_catalog.pg_type_is_visible(t.oid) IS TRUE THEN t.typname ELSE coalesce (nt.nspname || '.', '') || t.typname END, coalesce (nt.nspname || '.', '') || t.typname, FALSE, o.rolname FROM pg_type t, pg_namespace nt, pg_type bt, pg_namespace nbt, pg_authid o WHERE t.typnamespace = nt.oid AND
  t.typbasetype = bt.oid AND bt.typnamespace = nbt.oid AND t.typtype = 'd' AND o.oid=t.typowner AND pg_catalog.current_database() = ##cat::string AND nt.nspname = ##schema::string", 
 
 	/* I_STMT_DOMAINS_ALL */
-	"SELECT pg_catalog.current_database(), nt.nspname, t.typname, CASE WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN NULL ELSE coalesce (nbt.nspname || '.', '') || bt.typname END, CASE WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN 'DOM' || current_database() || '.' || nt.nspname || '.' || t.typname ELSE NULL END, 'gchararray', information_schema._pg_char_max_length(t.typbasetype, t.typtypmod), information_schema._pg_char_octet_length(t.typbasetype, t.typtypmod),  NULL, NULL, NULL, NULL, NULL, NULL,  information_schema._pg_numeric_precision(t.typbasetype, t.typtypmod), information_schema._pg_numeric_scale(t.typbasetype, t.typtypmod), t.typdefault, pg_catalog.obj_description(t.oid), CASE WHEN pg_catalog.pg_type_is_visible(t.oid) IS TRUE THEN t.typname ELSE coalesce (nt.nspname || '.', '') || t.typname END, coalesce (nt.nspname || '.', '') || t.typname, o.rolname FROM pg_type t, pg_namespace nt, pg_type bt, pg_namespace nbt, pg_authid o WHERE t.typnamespace = nt.oid AND t.typb
 asetype = bt.oid AND bt.typnamespace = nbt.oid AND t.typtype = 'd' AND o.oid=t.typowner",
+	"SELECT pg_catalog.current_database(), nt.nspname, t.typname, CASE WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN NULL ELSE coalesce (nbt.nspname || '.', '') || bt.typname END, CASE WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN 'DOM' || current_database() || '.' || nt.nspname || '.' || t.typname ELSE NULL END, 'gchararray', information_schema._pg_char_max_length(t.typbasetype, t.typtypmod), information_schema._pg_char_octet_length(t.typbasetype, t.typtypmod),  NULL, NULL, NULL, NULL, NULL, NULL,  information_schema._pg_numeric_precision(t.typbasetype, t.typtypmod), information_schema._pg_numeric_scale(t.typbasetype, t.typtypmod), t.typdefault, pg_catalog.obj_description(t.oid), CASE WHEN pg_catalog.pg_type_is_visible(t.oid) IS TRUE THEN t.typname ELSE coalesce (nt.nspname || '.', '') || t.typname END, coalesce (nt.nspname || '.', '') || t.typname, FALSE, o.rolname FROM pg_type t, pg_namespace nt, pg_type bt, pg_namespace nbt, pg_authid o WHERE t.typnamespace = nt.oid AND
  t.typbasetype = bt.oid AND bt.typnamespace = nbt.oid AND t.typtype = 'd' AND o.oid=t.typowner",
 
 	/* I_STMT_DOMAINS_CONSTRAINTS */
 	"SELECT constraint_catalog, constraint_schema, constraint_name, domain_catalog, domain_schema, domain_name, NULL, CASE WHEN is_deferrable = 'YES' THEN TRUE ELSE FALSE END, CASE WHEN initially_deferred = 'YES' THEN TRUE ELSE FALSE END FROM information_schema.domain_constraints WHERE domain_catalog = ##cat::string AND domain_schema = ##schema::string AND domain_name = ##name::string",
@@ -220,10 +220,10 @@
 	"UNION SELECT 'ROUC' || current_database() || '.' || ss.n_nspname || '.' || ((ss.proname::text || '_'::text) || ss.p_oid::text) || '.' || (ss.x).n, current_database(), ss.n_nspname, ((ss.proname::text || '_'::text) || ss.p_oid::text), 'ROUTINE_COL', CASE WHEN at.typelem <> 0::oid AND at.typlen = -1 THEN 'array_spec' ELSE coalesce (ant.nspname || '.', '') || at.typname END, CASE WHEN at.typelem <> 0::oid AND at.typlen = -1 THEN 'ARR' || at.typelem ELSE NULL END, NULL, NULL FROM pg_type t, pg_namespace nt, ( SELECT n.nspname AS n_nspname, p.proname, p.oid AS p_oid, p.proargnames, p.proargmodes, information_schema._pg_expandarray(COALESCE(p.proallargtypes, p.proargtypes::oid[])) AS x FROM pg_namespace n, pg_proc p WHERE n.oid = p.pronamespace AND (pg_has_role(p.proowner, 'USAGE'::text) OR has_function_privilege(p.oid, 'EXECUTE'::text))) ss, pg_type at, pg_namespace ant WHERE t.oid = (ss.x).x AND t.typnamespace = nt.oid AND at.oid = t.typelem AND at.typnamespace = ant.oid AND (
 ss.proargmodes[(ss.x).n] = 'o' OR ss.proargmodes[(ss.x).n] = 'b')",
 
 	/* I_STMT_ROUTINES_ALL */
-	"SELECT current_database()::information_schema.sql_identifier, n.nspname::information_schema.sql_identifier, ((p.proname::text || '_'::text) || p.oid::text)::information_schema.sql_identifier, current_database()::information_schema.sql_identifier, n.nspname::information_schema.sql_identifier, p.proname::information_schema.sql_identifier, CASE WHEN p.proisagg THEN 'AGGREGATE' ELSE 'FUNCTION' END, CASE WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN 'ROUC' || current_database() || '.' || n.nspname || '.' || p.proname || '.' || p.oid ELSE coalesce (nt.nspname || '.', '') || t.typname END AS rettype, p.proretset, p.pronargs, CASE WHEN l.lanname = 'sql'::name THEN 'SQL'::text ELSE 'EXTERNAL'::text END, CASE WHEN pg_has_role(p.proowner, 'USAGE'::text) THEN p.prosrc ELSE NULL::text END, CASE WHEN l.lanname = 'c'::name THEN p.prosrc ELSE NULL::text END, upper(l.lanname::text)::information_schema.character_data AS external_language, 'GENERAL'::character varying::information_schema.c
 haracter_data AS parameter_style, CASE WHEN p.provolatile = 'i' THEN TRUE ELSE FALSE END, 'MODIFIES'::character varying::information_schema.character_data AS sql_data_access, CASE WHEN p.proisstrict THEN TRUE ELSE FALSE END, pg_catalog.obj_description(p.oid), CASE WHEN pg_catalog.pg_function_is_visible(p.oid) IS TRUE THEN p.proname ELSE coalesce (n.nspname || '.', '') || p.proname END, coalesce (n.nspname || '.', '') || p.proname, o.rolname FROM pg_namespace n, pg_proc p, pg_language l, pg_type t, pg_namespace nt, pg_authid o WHERE n.oid = p.pronamespace AND p.prolang = l.oid AND p.prorettype = t.oid AND t.typnamespace = nt.oid AND (pg_has_role(p.proowner, 'USAGE'::text) OR has_function_privilege(p.oid, 'EXECUTE'::text)) AND o.oid=p.proowner",
+	"SELECT current_database()::information_schema.sql_identifier, n.nspname::information_schema.sql_identifier, ((p.proname::text || '_'::text) || p.oid::text)::information_schema.sql_identifier, current_database()::information_schema.sql_identifier, n.nspname::information_schema.sql_identifier, p.proname::information_schema.sql_identifier, CASE WHEN p.proisagg THEN 'AGGREGATE' ELSE 'FUNCTION' END, CASE WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN 'ROUC' || current_database() || '.' || n.nspname || '.' || p.proname || '.' || p.oid ELSE coalesce (nt.nspname || '.', '') || t.typname END AS rettype, p.proretset, p.pronargs::int, CASE WHEN l.lanname = 'sql'::name THEN 'SQL'::text ELSE 'EXTERNAL'::text END, CASE WHEN pg_has_role(p.proowner, 'USAGE'::text) THEN p.prosrc ELSE NULL::text END, CASE WHEN l.lanname = 'c'::name THEN p.prosrc ELSE NULL::text END, upper(l.lanname::text)::information_schema.character_data AS external_language, 'GENERAL'::character varying::information_sch
 ema.character_data AS parameter_style, CASE WHEN p.provolatile = 'i' THEN TRUE ELSE FALSE END, 'MODIFIES'::character varying::information_schema.character_data AS sql_data_access, CASE WHEN p.proisstrict THEN TRUE ELSE FALSE END, pg_catalog.obj_description(p.oid), CASE WHEN pg_catalog.pg_function_is_visible(p.oid) IS TRUE THEN p.proname ELSE coalesce (n.nspname || '.', '') || p.proname END, coalesce (n.nspname || '.', '') || p.proname, o.rolname FROM pg_namespace n, pg_proc p, pg_language l, pg_type t, pg_namespace nt, pg_authid o WHERE n.oid = p.pronamespace AND p.prolang = l.oid AND p.prorettype = t.oid AND t.typnamespace = nt.oid AND (pg_has_role(p.proowner, 'USAGE'::text) OR has_function_privilege(p.oid, 'EXECUTE'::text)) AND o.oid=p.proowner",
 
 	/* I_STMT_ROUTINES */
-	"SELECT current_database()::information_schema.sql_identifier, n.nspname::information_schema.sql_identifier, ((p.proname::text || '_'::text) || p.oid::text)::information_schema.sql_identifier, current_database()::information_schema.sql_identifier, n.nspname::information_schema.sql_identifier, p.proname::information_schema.sql_identifier, CASE WHEN p.proisagg THEN 'AGGREGATE' ELSE 'FUNCTION' END, CASE WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN 'ROUC' || current_database() || '.' || n.nspname || '.' || p.proname || '.' || p.oid ELSE coalesce (nt.nspname || '.', '') || t.typname END AS rettype, p.proretset, p.pronargs, CASE WHEN l.lanname = 'sql'::name THEN 'SQL'::text ELSE 'EXTERNAL'::text END, CASE WHEN pg_has_role(p.proowner, 'USAGE'::text) THEN p.prosrc ELSE NULL::text END, CASE WHEN l.lanname = 'c'::name THEN p.prosrc ELSE NULL::text END, upper(l.lanname::text)::information_schema.character_data AS external_language, 'GENERAL'::character varying::information_schema.c
 haracter_data AS parameter_style, CASE WHEN p.provolatile = 'i' THEN TRUE ELSE FALSE END, 'MODIFIES'::character varying::information_schema.character_data AS sql_data_access, CASE WHEN p.proisstrict THEN TRUE ELSE FALSE END, pg_catalog.obj_description(p.oid), CASE WHEN pg_catalog.pg_function_is_visible(p.oid) IS TRUE THEN p.proname ELSE coalesce (n.nspname || '.', '') || p.proname END, coalesce (n.nspname || '.', '') || p.proname, o.rolname FROM pg_namespace n, pg_proc p, pg_language l, pg_type t, pg_namespace nt, pg_authid o WHERE current_database()::information_schema.sql_identifier = ##cat::string AND n.nspname::information_schema.sql_identifier = ##schema::string AND n.oid = p.pronamespace AND p.prolang = l.oid AND p.prorettype = t.oid AND t.typnamespace = nt.oid AND (pg_has_role(p.proowner, 'USAGE'::text) OR has_function_privilege(p.oid, 'EXECUTE'::text)) AND o.oid=p.proowner",
+	"SELECT current_database()::information_schema.sql_identifier, n.nspname::information_schema.sql_identifier, ((p.proname::text || '_'::text) || p.oid::text)::information_schema.sql_identifier, current_database()::information_schema.sql_identifier, n.nspname::information_schema.sql_identifier, p.proname::information_schema.sql_identifier, CASE WHEN p.proisagg THEN 'AGGREGATE' ELSE 'FUNCTION' END, CASE WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN 'ROUC' || current_database() || '.' || n.nspname || '.' || p.proname || '.' || p.oid ELSE coalesce (nt.nspname || '.', '') || t.typname END AS rettype, p.proretset, p.pronargs::int, CASE WHEN l.lanname = 'sql'::name THEN 'SQL'::text ELSE 'EXTERNAL'::text END, CASE WHEN pg_has_role(p.proowner, 'USAGE'::text) THEN p.prosrc ELSE NULL::text END, CASE WHEN l.lanname = 'c'::name THEN p.prosrc ELSE NULL::text END, upper(l.lanname::text)::information_schema.character_data AS external_language, 'GENERAL'::character varying::information_sch
 ema.character_data AS parameter_style, CASE WHEN p.provolatile = 'i' THEN TRUE ELSE FALSE END, 'MODIFIES'::character varying::information_schema.character_data AS sql_data_access, CASE WHEN p.proisstrict THEN TRUE ELSE FALSE END, pg_catalog.obj_description(p.oid), CASE WHEN pg_catalog.pg_function_is_visible(p.oid) IS TRUE THEN p.proname ELSE coalesce (n.nspname || '.', '') || p.proname END, coalesce (n.nspname || '.', '') || p.proname, o.rolname FROM pg_namespace n, pg_proc p, pg_language l, pg_type t, pg_namespace nt, pg_authid o WHERE current_database()::information_schema.sql_identifier = ##cat::string AND n.nspname::information_schema.sql_identifier = ##schema::string AND n.oid = p.pronamespace AND p.prolang = l.oid AND p.prorettype = t.oid AND t.typnamespace = nt.oid AND (pg_has_role(p.proowner, 'USAGE'::text) OR has_function_privilege(p.oid, 'EXECUTE'::text)) AND o.oid=p.proowner",
 
 	/* I_STMT_ROUTINES_ONE */
 	"SELECT current_database()::information_schema.sql_identifier, n.nspname::information_schema.sql_identifier, ((p.proname::text || '_'::text) || p.oid::text)::information_schema.sql_identifier, current_database()::information_schema.sql_identifier, n.nspname::information_schema.sql_identifier, p.proname::information_schema.sql_identifier, CASE WHEN p.proisagg THEN 'AGGREGATE' ELSE 'FUNCTION' END, CASE WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN 'ROUC' || current_database() || '.' || n.nspname || '.' || p.proname || '.' || p.oid ELSE coalesce (nt.nspname || '.', '') || t.typname END AS rettype, p.proretset, p.pronargs, CASE WHEN l.lanname = 'sql'::name THEN 'SQL'::text ELSE 'EXTERNAL'::text END, CASE WHEN pg_has_role(p.proowner, 'USAGE'::text) THEN p.prosrc ELSE NULL::text END, CASE WHEN l.lanname = 'c'::name THEN p.prosrc ELSE NULL::text END, upper(l.lanname::text)::information_schema.character_data AS external_language, 'GENERAL'::character varying::information_schema.c
 haracter_data AS parameter_style, CASE WHEN p.provolatile = 'i' THEN TRUE ELSE FALSE END, 'MODIFIES'::character varying::information_schema.character_data AS sql_data_access, CASE WHEN p.proisstrict THEN TRUE ELSE FALSE END, pg_catalog.obj_description(p.oid), CASE WHEN pg_catalog.pg_function_is_visible(p.oid) IS TRUE THEN p.proname ELSE coalesce (n.nspname || '.', '') || p.proname END, coalesce (n.nspname || '.', '') || p.proname, o.rolname FROM pg_namespace n, pg_proc p, pg_language l, pg_type t, pg_namespace nt, pg_authid o WHERE current_database()::information_schema.sql_identifier = ##cat::string AND n.nspname::information_schema.sql_identifier = ##schema::string AND ((p.proname::text || '_'::text) || p.oid::text)::information_schema.sql_identifier = ##name::string AND n.oid = p.pronamespace AND p.prolang = l.oid AND p.prorettype = t.oid AND t.typnamespace = nt.oid AND (pg_has_role(p.proowner, 'USAGE'::text) OR has_function_privilege(p.oid, 'EXECUTE'::text)) AND o.oid=p.
 proowner",
@@ -824,7 +824,7 @@
 		if (type != G_TYPE_STRING) {
 			GValue *v;
 			g_value_set_string (v = gda_value_new (G_TYPE_STRING), g_type_name (type));
-			retval = gda_data_model_set_value_at (proxy, 10, i, v, error);
+			retval = gda_data_model_set_value_at (proxy, 7, i, v, error);
 			gda_value_free (v);
 			if (!retval)
 				break;
@@ -883,7 +883,7 @@
 	for (i = 0; i < nrows; i++) {
 		const GValue *value;
 		GType type;
-		value = gda_data_model_get_value_at (model, 25, i, error);
+		value = gda_data_model_get_value_at (model, 24, i, error);
 		if (!value) {
 			retval = FALSE;
 			break;
@@ -893,7 +893,7 @@
 		if (type != G_TYPE_STRING) {
 			GValue *v;
 			g_value_set_string (v = gda_value_new (G_TYPE_STRING), g_type_name (type));
-			retval = gda_data_model_set_value_at (proxy, 10, i, v, error);
+			retval = gda_data_model_set_value_at (proxy, 7, i, v, error);
 			gda_value_free (v);
 			if (!retval)
 				break;

Modified: trunk/tools/Makefile.am
==============================================================================
--- trunk/tools/Makefile.am	(original)
+++ trunk/tools/Makefile.am	Sat Sep 20 12:35:00 2008
@@ -62,3 +62,5 @@
 information_schema_doc_LDADD = \
         $(top_builddir)/libgda/libgda-4.0.la \
         $(LIBGDA_LIBS)
+
+EXTRA_DIST = gda-sql.ico

Modified: trunk/tools/command-exec.c
==============================================================================
--- trunk/tools/command-exec.c	(original)
+++ trunk/tools/command-exec.c	Sat Sep 20 12:35:00 2008
@@ -538,67 +538,6 @@
 	return res;
 }
 
-GdaInternalCommandResult *
-gda_internal_command_list_queries (GdaConnection *cnc, const gchar **args,
-				   GError **error, gpointer data)
-{
-	GdaInternalCommandResult *res = NULL;
-	GdaDataModel *model;
-	const gchar *qname = NULL;
-	gboolean with_sql_def = FALSE;
-
-	if (!cnc) {
-		g_set_error (error, 0, 0, _("No current connection"));
-		return NULL;
-	}
-
-	if (args[0] && *args[0]) {
-		if (!strcmp (args[0], "+"))
-			with_sql_def = TRUE;
-		else {
-			qname = args[0];
-			if (args[1] && (*args[1] == '+'))
-				with_sql_def = TRUE;
-		}
-	}
-
-	if (with_sql_def)
-		model = gda_data_model_array_new_with_g_types (5,
-							       G_TYPE_STRING,
-							       G_TYPE_STRING,
-							       G_TYPE_STRING,
-							       G_TYPE_STRING,
-							       G_TYPE_STRING);
-	else
-		model = gda_data_model_array_new_with_g_types (4,
-							       G_TYPE_STRING,
-							       G_TYPE_STRING,
-							       G_TYPE_STRING,
-							       G_TYPE_STRING);
-	gda_data_model_set_column_title (model, 0, _("Name"));
-	gda_data_model_set_column_title (model, 1, _("Type"));
-	gda_data_model_set_column_title (model, 2, _("Description"));
-	gda_data_model_set_column_title (model, 3, _("Parameters"));
-	if (with_sql_def)
-		gda_data_model_set_column_title (model, 4, _("SQL"));
-	g_object_set_data (G_OBJECT (model), "name", _("List of queries"));
-
-	if (qname) {
-		TO_IMPLEMENT;
-	}
-	else {
-		
-
-		TO_IMPLEMENT;
-	}
-
-	res = g_new0 (GdaInternalCommandResult, 1);
-	res->type = GDA_INTERNAL_COMMAND_RESULT_DATA_MODEL;
-	res->u.model = model;
-
-	return res;
-}
-
 GdaMetaStruct *
 gda_internal_command_build_meta_struct (GdaConnection *cnc, const gchar **args, GError **error)
 {

Modified: trunk/tools/command-exec.h
==============================================================================
--- trunk/tools/command-exec.h	(original)
+++ trunk/tools/command-exec.h	Sat Sep 20 12:35:00 2008
@@ -95,8 +95,6 @@
 							   GError **error, gpointer data);
 GdaInternalCommandResult *gda_internal_command_list_schemas (GdaConnection *cnc, const gchar **args,
 							     GError **error, gpointer data);
-GdaInternalCommandResult *gda_internal_command_list_queries (GdaConnection *cnc, const gchar **args,
-							     GError **error, gpointer data);
 GdaInternalCommandResult *gda_internal_command_detail (GdaConnection *cnc, const gchar **args,
 						       GError **error, gpointer data);
 

Modified: trunk/tools/gda-sql.c
==============================================================================
--- trunk/tools/gda-sql.c	(original)
+++ trunk/tools/gda-sql.c	Sat Sep 20 12:35:00 2008
@@ -58,6 +58,7 @@
 gboolean list_providers = FALSE;
 
 gchar *outfile = NULL;
+gboolean has_threads;
 
 static GOptionEntry entries[] = {
         { "no-password-ask", 'p', 0, G_OPTION_ARG_NONE, &ask_pass, "Don't ask for a password when it is empty", NULL },
@@ -151,12 +152,12 @@
 	context = g_option_context_new (_("[DSN|connection string]..."));        
 	g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
         if (!g_option_context_parse (context, &argc, &argv, &error)) {
-                g_print ("Can't parse arguments: %s\n", error->message);
-		exit_status = EXIT_FAILURE;
-		goto cleanup;
+                g_fprintf  (stderr, "Can't parse arguments: %s\n", error->message);
+		return EXIT_FAILURE;
         }
         g_option_context_free (context);
         gda_init ();
+	has_threads = g_thread_supported ();
 	data = g_new0 (MainData, 1);
 	data->parameters = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
 	main_data = data;
@@ -544,10 +545,19 @@
 {
 	gchar *cmde;
 
+	if (single_command) {
+		if (*single_command) {
+			cmde = single_command;
+			single_command = "";
+			return cmde;
+		}
+		else
+			return NULL;
+	}
 	compute_prompt (data, prompt, data->partial_command == NULL ? FALSE : TRUE);
 	if (data->input_stream) {
 		cmde = input_from_stream (data->input_stream);
-		if (!cmde && !commandsfile && isatty (fileno (stdin))) {
+		if (!cmde && isatty (fileno (stdin))) {
 			/* go back to console after file is over */
 			set_input_file (data, NULL, NULL);
 			cmde = input_from_console (prompt->str);
@@ -1034,28 +1044,47 @@
 		g_object_set (G_OBJECT (cs->cnc), "meta-store", store, NULL);
 		if (update_store) {
 			GError *lerror = NULL;
-			MetaUpdateData *thdata;
 			
-			cs->threader = (GdaThreader*) gda_threader_new ();
-			thdata = g_new0 (MetaUpdateData, 1);
-			thdata->data = data;
-			thdata->cs = cs;
-			thdata->cannot_lock = FALSE;
-			cs->meta_job_id = gda_threader_start_thread (cs->threader, 
-								     (GThreadFunc) thread_start_update_meta_store,
-								     thdata,
-								     (GdaThreaderFunc) thread_ok_cb_update_meta_store,
-								     (GdaThreaderFunc) thread_cancelled_cb_update_meta_store, 
-								     &lerror);
-			if (cs->meta_job_id == 0) {
-				if (!data->output_stream) 
-					g_print (_("Error getting meta data in background: %s\n"), 
-						 lerror && lerror->message ? lerror->message : _("No detail"));
-				if (lerror)
-					g_error_free (lerror);
+			if (has_threads) {
+				MetaUpdateData *thdata;
+				cs->threader = (GdaThreader*) gda_threader_new ();
+				thdata = g_new0 (MetaUpdateData, 1);
+				thdata->data = data;
+				thdata->cs = cs;
+				thdata->cannot_lock = FALSE;
+				cs->meta_job_id = gda_threader_start_thread (cs->threader, 
+									     (GThreadFunc) thread_start_update_meta_store,
+									     thdata,
+									     (GdaThreaderFunc) thread_ok_cb_update_meta_store,
+									     (GdaThreaderFunc) thread_cancelled_cb_update_meta_store, 
+									     &lerror);
+				if (cs->meta_job_id == 0) {
+					if (!data->output_stream) 
+						g_print (_("Error getting meta data in background: %s\n"), 
+							 lerror && lerror->message ? lerror->message : _("No detail"));
+					if (lerror)
+						g_error_free (lerror);
+				}
+			}
+			else {
+				if (!data->output_stream) {
+					g_print (_("Getting database schema information for connection '%s', this may take some time... "),
+						 cs->name);
+					fflush (stdout);
+				}
+				
+				if (!gda_connection_update_meta_store (cs->cnc, NULL, &lerror)) {
+					if (!data->output_stream) 
+						g_print (_("error: %s\n"), 
+							 lerror && lerror->message ? lerror->message : _("No detail"));
+					if (lerror)
+						g_error_free (lerror);
+				}
+				else
+					if (!data->output_stream) 
+						g_print (_("Done.\n"));
 			}
 		}
-
 		g_object_unref (store);
 	}
 
@@ -1082,22 +1111,23 @@
 {
 	data->cs->meta_job_id = 0;
 	if (data->cannot_lock) {
+		GError *lerror = NULL;
 		if (!data->data->output_stream) {
-			GError *lerror = NULL;
 			g_print (_("Getting database schema information for connection '%s', this may take some time... "),
 				 data->cs->name);
 			fflush (stdout);
-			if (!gda_connection_update_meta_store (data->cs->cnc, NULL, &lerror)) {
-				if (!data->data->output_stream) 
-					g_print (_("error: %s\n"), 
-						 lerror && lerror->message ? lerror->message : _("No detail"));
-				if (lerror)
-					g_error_free (lerror);
-			}
-			else
-				if (!data->data->output_stream) 
-					g_print (_("Done.\n"));
 		}
+
+		if (!gda_connection_update_meta_store (data->cs->cnc, NULL, &lerror)) {
+			if (!data->data->output_stream) 
+				g_print (_("error: %s\n"), 
+					 lerror && lerror->message ? lerror->message : _("No detail"));
+			if (lerror)
+				g_error_free (lerror);
+		}
+		else
+			if (!data->data->output_stream) 
+				g_print (_("Done.\n"));
 	}
 	if (data->error)
 		g_error_free (data->error);
@@ -1444,16 +1474,6 @@
 	c->arguments_delimiter_func = NULL;
 	commands->commands = g_slist_prepend (commands->commands, c);
 
-	c = g_new0 (GdaInternalCommand, 1);
-	c->group = _("Information");
-	c->name = g_strdup_printf (_("%s [QUERY] [+]"), "dq");
-	c->description = _("List all queries (or named query) in dictionary");
-	c->args = NULL;
-	c->command_func = gda_internal_command_list_queries;
-	c->user_data = NULL;
-	c->arguments_delimiter_func = NULL;
-	commands->commands = g_slist_prepend (commands->commands, c);
-
 	/* specific commands */
 	c = g_new0 (GdaInternalCommand, 1);
 	c->group = _("General");



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