[gnome-db] Documentation



I send the patch with the changes to the documentation and some files
that must be included in libgda/doc/C .
? parche.diff
? doc/C/tutorial01.sgml
? doc/C/tutorial02.sgml
? doc/C/tutorial04.sgml
? doc/C/tutorial06.sgml
? doc/C/tutorial08.sgml
? doc/C/tutorial10.sgml
Index: doc/C/Makefile.am
===================================================================
RCS file: /cvs/gnome/libgda/doc/C/Makefile.am,v
retrieving revision 1.12
diff -u -r1.12 Makefile.am
--- doc/C/Makefile.am	21 May 2002 23:41:32 -0000	1.12
+++ doc/C/Makefile.am	6 Aug 2002 15:16:21 -0000
@@ -35,7 +35,7 @@
 HTML_IMAGES =
 
 # Extra SGML files that are included by $(DOC_MAIN_SGML_FILE).
-content_files =
+content_files = tutorial01.sgml tutorial02.sgml tutorial04.sgml tutorial06.sgml tutorial08.sgml tutorial10.sgml 
 
 # Other files to distribute.
 extra_files =
Index: doc/C/libgda-docs.sgml
===================================================================
RCS file: /cvs/gnome/libgda/doc/C/libgda-docs.sgml,v
retrieving revision 1.30
diff -u -r1.30 libgda-docs.sgml
--- doc/C/libgda-docs.sgml	4 Aug 2002 17:14:09 -0000	1.30
+++ doc/C/libgda-docs.sgml	6 Aug 2002 15:16:22 -0000
@@ -2,6 +2,7 @@
 
 <!ENTITY LIBGDA          "<application>libgda</application>">
 <!ENTITY GNOMEDB         "<application>GNOME-DB</application>">
+<!ENTITY igalia          '<ulink url="http://www.igalia.com";>Igalia, S.L.</ulink>'>
 <!ENTITY API             "<acronym>API</acronym>">
 <!ENTITY DBMS            "<acronym>DBMS</acronym>">
 <!ENTITY DSN             "<acronym>DSN</acronym>">
@@ -25,6 +26,12 @@
 <!ENTITY GDADATAMODEL    "<xref linkend='libgda-GdaDataModel'>">
 <!ENTITY GDADATAMODELARRAY "<xref linkend='libgda-GdaDataModelArray'>">
 <!ENTITY GDADATAMODELHASH "<xref linkend='libgda-GdaDataModelHash'>">
+<!entity tutorial02.sgml system "tutorial02.sgml">
+<!entity tutorial04.sgml system "tutorial04.sgml">
+<!entity tutorial06.sgml system "tutorial06.sgml">
+<!entity tutorial08.sgml system "tutorial08.sgml">
+<!entity tutorial10.sgml system "tutorial10.sgml">
+<!entity tutorial01.sgml system "tutorial01.sgml">
 <!ENTITY libgda-batch SYSTEM "sgml/gda-batch.sgml">
 <!ENTITY libgda-client SYSTEM "sgml/gda-client.sgml">
 <!ENTITY libgda-command SYSTEM "sgml/gda-command.sgml">
@@ -111,6 +118,26 @@
 	<contrib>GDP compliancy, FDL, added markup, English and syntax
         </contrib>
       </author>
+      <author>
+	<firstname>Xabier</firstname>
+	<surname>Rodríguez Calvar</surname>
+	<affiliation>
+          <orgname>&igalia;</orgname>
+	  <address><email>xrcalvar igalia com</email></address>
+	</affiliation>
+	<contrib>How to begin
+        </contrib>
+      </author>
+      <author>
+	<firstname>José</firstname>
+	<surname>Dapena Paz</surname>
+	<affiliation>
+          <orgname>&igalia;</orgname>
+	  <address><email>jdapena igalia com</email></address>
+	</affiliation>
+	<contrib>Some examples
+        </contrib>
+      </author>
     </authorgroup>
     <date>1999 February</date>
     <copyright>
@@ -347,7 +374,53 @@
         send an email to <email>gnome-db-list-request gnome org</email> with 
         the subject SUBSCRIBE, if you are not already subscribed).
       </para>
+      <sect2 ID="installation-debian">
+        <title>Debian installation</title>
+          <para>
+            If you are using <ULINK URL="http://www.debian.org";>Debian</ULINK> you
+	    will need to install a few packages in the following way:
+	  </para>
+          <PROGRAMLISTING>
+            <SYSTEMITEM CLASS="prompt">$</SYSTEMITEM> <USERINPUT> apt-get install <EMPHASIS>package-names</EMPHASIS></USERINPUT>
+          </PROGRAMLISTING>
+          <para>
+            These are the packages you will need for this:
+          </para>
+          <ITEMIZEDLIST>
+            <LISTITEM>libgda2-1</LISTITEM>
+            <LISTITEM>libgda2-common</LISTITEM>
+            <LISTITEM>libgda2-dev</LISTITEM>
+            <LISTITEM>libgda2-doc</LISTITEM>
+            <LISTITEM>libgda2-dbg</LISTITEM>
+          </ITEMIZEDLIST>
+          <para>
+            You can obtain information about any packages with:
+          </para>
+          <PROGRAMLISTING>
+            <SYSTEMITEM CLASS="prompt">$</SYSTEMITEM> <USERINPUT> apt-cache show <EMPHASIS>package-names</EMPHASIS></USERINPUT>
+          </PROGRAMLISTING>
+          <para>
+            If you cannot find this packages, you must include in
+            <filename class="directory">/etc/apt/sources.list</filename>
+            a line like this:
+          </para>
+          <PROGRAMLISTING>
+            deb http://gluck.debian.org/~kov/debian woody gnome2
+          </PROGRAMLISTING>
+      </sect2>
+    </sect1>
+    
+    <sect1 ID="compiling">
+      <title>Compiling with the library</title>
+        <para>
+          To compile you will need to set the C flags and to link the library, so we recommend
+          to use the <EMPHASIS>pkg-config</EMPHASIS> command.
+        </para>
+        <PROGRAMLISTING>
+          <SYSTEMITEM CLASS="prompt">$</SYSTEMITEM> <USERINPUT> gcc -o main `pkg-config --cflags --libs libgda` main.c</USERINPUT>
+        </PROGRAMLISTING>
     </sect1>
+
     <sect1 id="installation-configuring">
       <title>Configuring</title>
       <para>
@@ -359,7 +432,8 @@
         <title>Configuration for development</title>
         <para>
           If you want to develop applications using &LIBGDA;, you should 
-          install the libgda-dev[el] package if you do a &RPM; or Debian-based
+          install the libgda-dev[el] package if you do a &RPM; or <LINK
+	  LINKEND="installation-debian">Debian-based</LINK>
           installation. If you compiled the source code, development files are
           installed in your system.
         </para>
@@ -373,6 +447,12 @@
           <envar>LD_LIBRARY_PATH</envar> (or 
           <filename>/etc/ld.so.conf</filename> file).
         </para>
+        <para>
+          You have to include a headers file, and it is:
+        </para>
+        <programlisting>
+#include &lt;libgda/libgda.h&gt;
+        </programlisting>
       </sect2>
       <sect2 id="installation-client">
         <title>Configuration for accessing a database</title>
@@ -499,6 +579,25 @@
 	    </calloutlist>
 	  </programlistingco>
 	</para>
+        <para>
+          The &XML; configuration file (<filename
+	  class="directory">~/.libgda/config</filename>) is not
+	  recommended to be modificated by hand and, about our example, it is
+	  something like this:
+        </para>
+	<programlisting>
+&lt;?xml version="1.0"?&gt;
+&lt;libgda-config&gt;
+  &lt;section path="/apps/libgda/Datasources/sales"&gt;
+    &lt;entry name="DSN" type="string" value="PORT=1111;DATABASE=test;HOST=localhost"/&gt;
+    &lt;entry name="Description" type="string" value="MySQL Test Database in native mode"/&gt;
+    &lt;entry name="Password" type="string" value="password"/&gt;
+    &lt;entry name="Provider" type="string" value="MySQL"/&gt;
+    &lt;entry name="Username" type="string" value="username"/&gt;
+  &lt;/section&gt;
+&lt;/libgda-config&gt;
+        </programlisting>
+        &tutorial02.sgml;
       </sect2>
       <sect2 id="installation-provider">
         <title>Provider's specific information</title>
@@ -710,7 +809,26 @@
       </sect2>
     </sect1>
   </chapter>
-  
+  <chapter ID="connecting">
+    <title>Beginning</title>
+    &tutorial04.sgml;
+  </chapter>
+  <chapter ID="processing-queries">
+    <title>Processing queries</title>
+    &tutorial06.sgml;
+  </chapter>
+  <chapter>
+    <title>Transactions and batch processes</title>
+    &tutorial08.sgml;
+  </chapter>
+  <chapter ID="managing-errors">
+  <title>Managing errors</title>
+    &tutorial10.sgml;
+  </chapter>
+  <chapter ID="main_example">
+  <title>Full example</title>
+    &tutorial01.sgml;
+  </chapter>
   <chapter id="libgda-api">
     <title>&LIBGDA; API Reference</title>
     <para>
@@ -772,179 +890,91 @@
 	a new provider. This class is just a typical GObject-based class,
 	with a set of virtual methods, that are the ones that you must
 	implement. These virtual methods are declared in the class structure,
-	in the <filename>gda-server-provider.h</filename> file. They are
-	explained in detail in the following subsections.
-      </para>
-      <sect2 id="libgda-provider-open-connection">
-	<title>open_connection</title>
+	in the <filename>gda-server-provider.h</filename> file. They are:
+       </para>
+       <itemizedlist>
+	<listitem>
+	   <para>open_connection</para>
 	   <para>
 	   Sets up the connection to the database backend using the parameters
 	   received as arguments and returns a boolean TRUE if the connection
 	   is successfully established, otherwise FALSE.
-	</para>
-      </sect2>
-	<sect2 id="libgda-provider-close-connection">
-	<title>close_connection</title>
-	<para>
-	  Frees the resources allocated for the connection and returns TRUE
-	  if everything is ok
-	</para>
-      </sect2>
-      <sect2 id="libgda-provider-get-database">
-	<title>get_database</title>
-	<para>
-	  Returns the name of the currently open database for a given
-	  connection.
-	</para>
-      </sect2>
-      <sect2 id="libgda-provider-change-database">
-	<title>change_database</title>
-	<para>
-	  Change the database being used in the active connection.
-	</para>
-      </sect2>
-      <sect2 id="libgda-provider-create-database">
-	<title>create_database</title>
-	<para>
-	  Creates a new database whose name is received in a parameter.	
-	</para>
-      </sect2>
-      <sect2 id="libgda-provider-drop-database">
-	<title>drop_database</title>
-	<para>
-	  Drops an existing database whose name is received in a parameter.
-	</para>
-      </sect2>
-      <sect2 id="libgda-provider-execute-command">
-	<title>execute_command</title>
-	<para>
-	  Executes a command and returns a GList of &GDADATAMODEL; with the
-	  results.
-	</para>
-      </sect2>
-      <sect2 id="libgda-provider-begin-transaction">
-	<title>begin_transaction</title>
-	<para>
-	  Initiates a transaction if the DB backend supports transactions.
-	</para>
-      </sect2>
-      <sect2 id="libgda-provider-commit-transaction">
-	<title>commit_transaction</title>
-	<para>
-	  Commits a transaction if the DB backend supports transactions.
-	</para>
-      </sect2>
-      <sect2 id="libgda-provider-rollback-transaction">
-	<title>rollback_transaction</title>
-	<para>
-	  Rollback a transaction if the DB backend supports transactions.
-	</para>
-      </sect2>
-      <sect2 id="libgda-provider-supports">
-	<title>supports</title>
-	<para>
-	  Tests if a given feature is supported by the provider and the
-	  DB backend. You can view the list of features in <filename>
-	  gda-connection.h</filename>, enumeration GdaConnectionFeature.
-	</para>
-      </sect2>
-      <sect2 id="libgda-provider-get-schema">
-	<title>get_schema</title>
-	<para>
-	  Returns a &GDADATAMODEL; with the schema information requested.
-	  You can view the list of features in <filename>
-	  gda-connection.h</filename>, enumeration GdaConnectionSchema.
-	  This schema information is what describes the objects in the
-	  database, and is the way applications can manage the structure
-	  of several database systems without knowing anything about
-	  their specific way of retrieving this information.
-	</para>
-	<para>
-	  The <function>get_schema</function> virtual method gets a
-	  <type>GdaConnectionSchema</type> argument, which describes
-	  the kind of schema the client making the call is interested
-	  in, along with a <type>GdaParameterList</type> argument,
-	  which contains the list of arguments sent by the user to
-	  explicitly provide more information for the search.
-	</para>
-	<para>
-	  The information to be returned for each schema, along with
-	  the supported parameters, is described in the following table.
-	</para>
-	<table frame="all">
-	  <title>Standard Schema and supported parameters</title>
-	  <tgroup cols="4" colsep="1" rowsep="1" align="justify">
-	    <colspec colname="c1">
-	    <colspec colname="c2">
-	    <colspec colname="c3">
-	    <colspec colname="c4">
-	    <thead>
-	      <row>
-		<entry>Object type</entry>
-		<entry>GDA identifier</entry>
-		<entry>Supported Parameters</entry>
-		<entry>Returned fields</entry>
-	      </row>
-	    </thead>
-	    <tbody>
-	      <row>
-		<entry>Tables</entry>
-		<entry><parameter>GDA_CONNECTION_SCHEMA_TABLES</parameter></entry>
-		<entry>"name" (name of table, optional)</entry>
-		<entry>name, owner, comments, SQL definition
-	      </row>
-	      <row>
-		<entry>Tables' parents</entry>
-		<entry><parameter>GDA_CONNECTION_SCHEMA_PARENT_TABLES</parameter></entry>
-		<entry>"name" (name of table, optional)</entry>
-		<entry>name, order of inheritance</entry>
-	      </row>
-	      <row>
-		<entry>Views</entry>
-		<entry><parameter>GDA_CONNECTION_SCHEMA_VIEWS</parameter></entry>
-		<entry>"name" (name of view, optional)</entry>
-		<entry>name, owner, comments, SQL definition</entry>
-	      </row>
-	      <row>
-		<entry>Table (or view) fields</entry>
-		<entry><parameter>GDA_CONNECTION_SCHEMA_FIELDS</parameter></entry>
-		<entry>"name" (name of table (or view), required)</entry>
-		<entry>name, type, size, scale, not null?, primary key?, unique index?, references</entry>
-	      </row>
-	      <row>
-		<entry>Sequences</entry>
-		<entry><parameter>GDA_CONNECTION_SCHEMA_SEQUENCES</parameter></entry>
-		<entry>"name" (name of sequence, optional)</entry>
-		<entry>name, owner, comments, SQL definition</entry>
-	      </row>
-	      <row>
-		<entry>Procedures</entry>
-		<entry><parameter>GDA_CONNECTION_SCHEMA_PROCEDURES</parameter></entry>
-		<entry>"name" (name of procedure, optional)</entry>
-		<entry>name, owner, comments, return type, number of arguments, SQL definition</entry>
-	      </row>
-	      <row>
-		<entry>Procedure parameters</entry>
-		<entry><parameter>GDA_CONNECTION_SCHEMA_PROCEDURE_PARAMS</parameter></entry>
-		<entry>"name" (name of procedure, required)</entry>
-		<entry>name, usage (in, out, inout), type</entry>
-	      </row>
-	      <row>
-		<entry>Aggregates</entry>
-		<entry><parameter>GDA_CONNECTION_SCHEMA_AGGREGATES</parameter></entry>
-		<entry>"name" (name of aggregate, optional)</entry>
-		<entry>name, owner, comments, return type, in type, SQL definition</entry>
-	      </row>
-	      <row>
-		<entry>Types</entry>
-		<entry><parameter>GDA_CONNECTION_SCHEMA_TYPES</parameter></entry>
-		<entry>"name" (name of type, optional)</entry>
-		<entry>name, owner, comments, GDA type</entry>
-	      </row>
-	    </tbody>
-	  </tgroup>
-	</table>
-      </sect2>
+	   </para>
+	</listitem>
+	<listitem>
+	   <para>close_connection</para>
+	   <para>
+	   Frees the resources allocated for the connection and returns TRUE
+	   if everything is ok
+	   </para>
+	</listitem>
+	<listitem>
+	  <para>get_database</para>
+	  <para>
+	    Returns the name of the currently open database for a given
+	    connection.
+	  </para>
+	</listitem>
+	<listitem>
+	  <para>change_database</para>
+	  <para>
+	    Change the database being used in the active connection.
+	  </para>
+	</listitem>
+	<listitem>
+	   <para>create_database</para>
+	   <para>
+	    Creates a new database whose name is received in a parameter.	
+	   </para>
+	</listitem>
+	<listitem>
+	  <para>drop_database</para>
+	  <para>
+	    Drops an existing database whose name is received in a parameter.
+	  </para>
+	</listitem>
+	<listitem>
+	   <para>execute_command</para>
+	   <para>
+	   Executes a command and returns a GList of &GDADATAMODEL; with the
+	   results.
+	   </para>
+	</listitem>
+	<listitem>
+	   <para>begin_transaction</para>
+	   <para>
+	   Initiates a transaction if the DB backend supports transactions.
+	   </para>
+	</listitem>
+	<listitem>
+	   <para>commit_transaction</para>
+	   <para>
+	   Commits a transaction if the DB backend supports transactions.
+	   </para>
+	</listitem>
+	<listitem>
+	   <para>rollback_transaction</para>
+	   <para>
+	   Rollback a transaction if the DB backend supports transactions.
+	   </para>
+	</listitem>
+	<listitem>
+	   <para>supports</para>
+	   <para>
+	   Tests if a given feature is supported by the provider and the
+	   DB backend. You can view the list of features in <filename>
+	   gda-connection.h</filename>, enumeration GdaConnectionFeature.
+	   </para>
+	</listitem>
+	<listitem>
+	   <para>get_schema</para>
+	   <para>
+	   Returns a &GDADATAMODEL; with the schema information requested.
+	   You can view the list of features in <filename>
+	   gda-connection.h</filename>, enumeration GdaConnectionSchema.
+	   </para>
+	</listitem>
+       </itemizedlist>
     </sect1>
     <sect1 id="libgda-provider-recordset">
       <title>The recordset class</title>
@@ -962,19 +992,19 @@
 	<listitem>
 	  <para>get_n_rows</para>
 	  <para>
-	    Returns the number of rows in the data model. If the provider
+	    Returns the number of rows in the data model.
+	  </para>
+	</listitem>
+	<listitem>
+	  <para>get_n_columns</para>
+	  <para>
+	    Returns the number of columns in the data model. If the provider
 	    can know in advance the number of rows the database server has
 	    returned, this function should just return that, and not
 	    retrieve any data. On the other hand, if it can't it should
 	    either retrieve all data, or move to the last record in the
 	    recordset and retrieve the row number, if the underlying
 	    data source allows it.
-	  </para>
-	</listitem>
-	<listitem>
-	  <para>get_n_columns</para>
-	  <para>
-	    Returns the number of columns in the data model.
 	  </para>
 	</listitem>
 	<listitem>
Index: doc/C/tmpl/gda-value.sgml
===================================================================
RCS file: /cvs/gnome/libgda/doc/C/tmpl/gda-value.sgml,v
retrieving revision 1.15
diff -u -r1.15 gda-value.sgml
--- doc/C/tmpl/gda-value.sgml	17 Jun 2002 08:35:49 -0000	1.15
+++ doc/C/tmpl/gda-value.sgml	6 Aug 2002 15:16:22 -0000
@@ -59,6 +59,7 @@
 @GDA_VALUE_TYPE_TIME: 
 @GDA_VALUE_TYPE_TIMESTAMP: 
 @GDA_VALUE_TYPE_TINYINT: 
+ GDA_VALUE_TYPE_TYPE: 
 @GDA_VALUE_TYPE_UNKNOWN: 
 
 <!-- ##### TYPEDEF GdaDate ##### -->
<PROGRAMLISTING>
#include &lt;libgda/libgda.h&gt;
#include &lt;stdio.h&gt;

#define DEFAULT_BUFFER_SIZE 1024


gboolean
get_errors (GdaConnection *connection)
{
  GList *list;
  GList *node;
  GdaError *error;

  list = (GList *) gda_connection_get_errors (connection);

  for (node = g_list_first (list); node != NULL; node = g_list_next (node))
    {
      error = (GdaError *) node->data;
      g_print ("Error no: %d\t", gda_error_get_number (error));
      g_print ("desc: %s\t", gda_error_get_description (error));
      g_print ("source: %s\t", gda_error_get_source (error));
      g_print ("sqlstate: %s\n", gda_error_get_sqlstate (error));
    }
}



void
show_table (GdaDataModel * dm)
{
  gint row_id;
  gint column_id;
  GdaValue *value;
  gchar *string;

  for (column_id = 0; column_id < gda_data_model_get_n_columns (dm);
       column_id++)
    g_print("%s\t",gda_data_model_get_column_title (dm, column_id));
  g_print("\n");

  for (row_id = 0; row_id < gda_data_model_get_n_rows (dm); row_id++)
    {
      for (column_id = 0; column_id < gda_data_model_get_n_columns (dm);
           column_id++)
        {
	  value =
	    (GdaValue *) gda_data_model_get_value_at (dm, column_id, row_id);
          string=gda_value_stringify (value);
	  g_print ("%s\t", string);
          g_free(string);
        }
      g_print("\n");
    }
}



void
show_table2 (GdaDataModel * dm)
{
  gint row_id;
  gint column_id;
  GdaValue *value;
  GdaRow *row;
  gchar *string;

  for (column_id = 0; column_id < gda_data_model_get_n_columns (dm);
       column_id++)
    g_print("%s\t",gda_data_model_get_column_title (dm, column_id));
  g_print("\n");

  for (row_id = 0; row_id < gda_data_model_get_n_rows (dm); row_id++)
    {
      row = (GdaRow *) gda_data_model_get_row (dm, row_id);
      for (column_id = 0; column_id < gda_data_model_get_n_columns (dm);
           column_id++)
        {
	  value = gda_row_get_value (row, column_id);
          string=gda_value_stringify (value);
	  g_print ("%s\t", string);
          gda_value_free(value);
          g_free(string);
        }
      g_print ("\n");
    }
}



void process_accounts(GdaConnection *connection)
{
  GdaTransaction *transaction_one, *transaction_two;
  GdaCommand *command;

  transaction_one=gda_transaction_new("accounts1");
  gda_connection_begin_transaction(connection,transaction_one);

  command=gda_command_new (
			   "UPDATE accounts SET balance=balance+50"
			   "WHERE account_code=456",
			   GDA_COMMAND_TYPE_SQL,
			   GDA_COMMAND_OPTION_STOP_ON_ERRORS);
  gda_command_set_transaction(command,transaction_one);
  gda_connection_execute_non_query(connection,command,NULL);
  gda_command_free(command);

  command=gda_command_new (
			   "UPDATE accounts SET balance=balance-50"
			   "WHERE account_code=12",
			   GDA_COMMAND_TYPE_SQL,
			   GDA_COMMAND_OPTION_STOP_ON_ERRORS);
  gda_command_set_transaction(command,transaction_one);
  gda_connection_execute_non_query(connection,command,NULL);
  gda_command_free(command);

  gda_connection_commit_transaction(connection,transaction_one);
  g_object_unref(transaction_one);

  transaction_two=gda_transaction_new("accounts2");
  gda_connection_begin_transaction(connection,transaction_two);

  command=gda_command_new (
			   "UPDATE accounts SET balance=balance+400"
			   "WHERE account_code=456",
			   GDA_COMMAND_TYPE_SQL,
			   GDA_COMMAND_OPTION_STOP_ON_ERRORS);
  gda_command_set_transaction(command,transaction_two);
  gda_connection_execute_non_query(connection,command,NULL);
  gda_command_free(command);

  command=gda_command_new (
			   "UPDATE accounts SET balance=balance-400"
			   "WHERE account_code=12",
			   GDA_COMMAND_TYPE_SQL,
			   GDA_COMMAND_OPTION_STOP_ON_ERRORS);
  gda_command_set_transaction(command,transaction_two);
  gda_connection_execute_non_query(connection,command,NULL);
  gda_command_free(command);

  gda_connection_rollback_transaction(connection,transaction_two);
  g_object_unref(transaction_two);

  execute_sql_command(connection,"SELECT * FROM accounts");
}


void process_accounts2(GdaConnection *connection)
{/*
  GdaBatch *batch;
  GdaCommand *command;

  batch=gda_batch_new();
  gda_batch_add_command(batch,
			"UPDATE accounts SET balance=balance+300"
			"WHERE account_code=456"
		       );
  gda_batch_add_command(batch,
			"UPDATE accounts SET balance=balance-300"
			"WHERE account_code=12",
		       );
  gda_batch_set_connection(batch,connection);
  gda_batch_set_transaction_mode(batch,TRUE);
  if (gda_batch_start(batch))
    g_print("BATCH OK\n");
  else
    g_print("BATCH failed\n");

  execute_sql_command(connection,"SELECT * FROM accounts");
*/}


gint
execute_sql_command (GdaConnection *connection, const gchar * buffer)
{
  GdaCommand *command;
  GList *list;
  GList *node;
  gboolean errors=FALSE;

  GdaDataModel *dm;


  command = gda_command_new (buffer, GDA_COMMAND_TYPE_SQL, GDA_COMMAND_OPTION_STOP_ON_ERRORS);
  list = gda_connection_execute_command (connection, command, NULL);
  if (list!=NULL)
    for (node=g_list_first(list); node != NULL; node=g_list_next(node))
      {
	dm=(GdaDataModel *) node->data;
	if (dm == NULL)
	  {
	    errors=TRUE;
	  }
	else
	  {
	    show_table (dm);
            g_object_unref(dm);
	  }
      }
  else
    {
      errors=TRUE;
    }
  gda_command_free (command);

  return (errors);
}



gint
execute_sql_non_query (GdaConnection *connection, const gchar * buffer)
{
  GdaCommand *command;
  gint number;

  command = gda_command_new (buffer, GDA_COMMAND_TYPE_SQL, GDA_COMMAND_OPTION_STOP_ON_ERRORS);
  number  = gda_connection_execute_non_query (connection, command, NULL);

  gda_command_free (command);

  return (number);
}



void
proving_errors (GdaConnection *connection)
{

  execute_sql_non_query (connection,
			 "DELETE FROM cliente"
			);
  execute_sql_non_query (connection,
			 "INSERT INTO cliente(cd_cli, dni, nombr, direc, telef) "
			 "VALUES ('1', '1234', 'Xabier',"
			 "'Rua Unha calquera', '123')"
			 "; INSERT INTO cliente(cd_cli, dni, nombr, direc, telef) "
			 "VALUES ('2', '2345', 'Rodriguez',"
			 "'Rua Outra calquera', '234')"
			);
  execute_sql_non_query (connection,
			 "INSERT INTO cliente(cd_cli, dni, nombr, direc, telef) "
			 "VALUES ('1', '1234', 'Xabier',"
			 "'Rua Unha calquera', '123')"
			 "; INSERT INTO cliente(cd_cli, dni, nombr, direc, telef) "
			 "VALUES ('2', '2345', 'Rodriguez',"
			 "'Rua Outra calquera', '234')"
			);
  execute_sql_command (connection, "SELECT * FROM cliente");


  execute_sql_non_query (connection,
			 "DELETE FROM accounts;"
			 "INSERT INTO accounts"
			 "(client_code, account_code, balance)"
			 "VALUES (123, 456, 1000);"
			 "INSERT INTO accounts"
			 "(client_code, account_code, balance)"
			 "VALUES (789, 012, 5000);"
			);

  execute_sql_command (connection, "SELECT * FROM accounts");

}



void
list_datasources (void)
{
  GList *ds_list;
  GList *node;
  GdaDataSourceInfo *info;

  ds_list = gda_config_get_data_source_list ();

  g_print ("\n");
  for (node = g_list_first (ds_list); node != NULL; node = g_list_next (node))
    {
      info = (GdaDataSourceInfo *) node->data;

      g_print
	("NAME: %s PROVIDER: %s CNC: %s DESC: %s USER: %s PASSWORD: %s\n",
	 info->name, info->provider, info->cnc_string, info->description,
	 info->username, info->password);

    }
  g_print ("\n");

  gda_config_free_data_source_list (ds_list);

}



void
list_providers (void)
{
  GList *prov_list;
  GList *node;
  GdaProviderInfo *info;

  prov_list = gda_config_get_provider_list ();

  for (node = g_list_first (prov_list); node != NULL;
       node = g_list_next (node))
    {
      info = (GdaProviderInfo *) node->data;

      g_print ("ID: %s\n", info->id);

    }

  gda_config_free_provider_list (prov_list);

}



void
do_stuff ()
{
  GdaClient *client;
  GdaConnection *connection;

  list_providers ();
  list_datasources ();

  client = gda_client_new ();

  g_print ("CONNECTING\n");
  connection = gda_client_open_connection (client, "calvaris", NULL, NULL);
  g_print ("CONNECTED\n");

  proving_errors (connection);

  process_accounts(connection);

  process_accounts2(connection);

  gda_client_close_all_connections (client);

  gda_main_quit();
}



void
save_ds ()
{
  gda_config_save_data_source ("calvaris", "PostgreSQL", "DATABASE=calvaris",
			       "cosa de calvaris", NULL, NULL);
}



void
remove_ds ()
{
  gda_config_remove_data_source("calvaris");
}



int
main (int argc, char **argv)
{

  g_print ("STARTING\n");
  gda_init ("TestGDA", "0.1", argc, argv);

  save_ds ();
  //  remove_ds();

  gda_main_run ((GdaInitFunc) do_stuff, (gpointer) NULL);
  //  do_stuff();

}
</PROGRAMLISTING>
Title: Managing data sources with API functions
Create data sources To create a data source you must use the function gda-config-save-data-source () Here you see how to create a data source named foo_ds. If you do not need to give an username or password to enter the database, you could put NULL. gda_config_save_data_source ("foo_ds", "PostgreSQL", "DATABASE=foo_db", "description of foo_ds", "foo_username, "foo_password"); gda_config_save_data_source ("other_foo_ds", "MySQL", "DATABASE=other_foo_db,HOST=db.foo.com", "description of other_foo_ds", "foo", NULL); For more details about provider specific information see in the section about providers specific information. Removing data sources To remove a data source you must use the function gda-config-remove-data-source () Here you see how to remove a data source named foo_ds. gda_config_remove_data_source("foo_ds"); Listing avaliable data sources To list avaliable data sources you must use the function gda_config_get_data_source_list () Here you see a function which lists the avaliable data sources. void list_datasources (void) { GList *ds_list; GList *node; GdaDataSourceInfo *info; ds_list = gda_config_get_data_source_list (); g_print ("\n"); for (node = g_list_first (ds_list); node != NULL; node = g_list_next (node)) { info = (GdaDataSourceInfo *) node->data; g_print ("NAME: %s PROVIDER: %s CNC: %s DESC: %s USER: %s PASSWORD: %s\n", info->name, info->provider, info->cnc_string, info->description, info->username, info->password); } g_print ("\n"); gda_config_free_data_source_list (ds_list); } Our function. Note that you must free the list when you finish using it. Listing avaliable providers To list the avaliable data sources you must use the function gda_config_get_provider_list () Here you see a function which lists avaliable providers. void list_providers (void) { GList *prov_list; GList *node; GdaProviderInfo *info; prov_list = gda_config_get_provider_list (); for (node = g_list_first (prov_list); node != NULL; node = g_list_next (node)) { info = (GdaProviderInfo *) node->data; g_print ("ID: %s\n", info->id); } gda_config_free_provider_list (prov_list); } Our function. Note that you must free the list when you finish using it.
Title: Initializing
First of all you have to initialize the gda library, i.e. to call the gda_init () function. gda_init ("TestGDA", "0.1", argc, argv); After initializing you can work as usual or make a function with the whole stuff, calling gda_main_run(). Note that if you use this way you will need to call gda_main_quit() in order to finish the program. void do_stuff () { GdaClient *client; GdaConnection *connection; list_providers (); list_datasources (); client = gda_client_new (); g_print ("CONNECTING\n"); connection = gda_client_open_connection (client, "calvaris", NULL, NULL); g_print ("CONNECTED\n"); proving_errors (connection); process_accounts(connection); process_accounts2(connection); gda_client_close_all_connections (client); gda_main_quit(); } int main (int argc, char **argv) { g_print ("STARTING\n"); gda_init ("TestGDA", "0.1", argc, argv); save_ds (); // remove_ds(); gda_main_run ((GdaInitFunc) do_stuff, (gpointer) NULL); // do_stuff(); } Connecting To connect you need to use two functions. We use gda_client_new () to create a connection pool and use gda_client_open_connection () to create the specific connections to the different data sources. void do_stuff () { GdaClient *client; GdaConnection *connection; list_providers (); list_datasources (); client = gda_client_new (); g_print ("CONNECTING\n"); connection = gda_client_open_connection (client, "calvaris", NULL, NULL); g_print ("CONNECTED\n"); proving_errors (connection); process_accounts(connection); gda_client_close_all_connections (client); } Creates the connection pool. Creates the connection to calvaris data source with the default username and password you have specify when creating the data source. However, you can specify them if you want. It's a good practice to close connections when you finish using them. It doesn't mean that you must close them each time you use them. It's better open the connections when program starts and use them during the whole execution.
Title: Executing sentences
Building commands Before invoking a query you have to build the structure containing the command and you can do this with gda_command_new (). The command type we most commonly use is GDA_COMMAND_TYPE_SQL because we will only focus on &SQL; queriesThere are other command types, as &XML; and so on. typedef enum { GDA_COMMAND_OPTION_IGNORE_ERRORS = 1, GDA_COMMAND_OPTION_STOP_ON_ERRORS = 1 << 1, GDA_COMMAND_OPTION_BAD_OPTION = 1 << 2 } GdaCommandOptions; Ignores all errors and executes all sentences returning data models. For failed sentences, it returns an empty data model. Stops when finding and error and doesn't return data models. Here you see an example of creating a command: gint execute_sql_non_query (GdaConnection *connection, const gchar * buffer) { GdaCommand *command; gint number; command = gda_command_new (buffer, GDA_COMMAND_TYPE_SQL, GDA_COMMAND_OPTION_STOP_ON_ERRORS); number = gda_connection_execute_non_query (connection, command, NULL); gda_command_free (command); return (number); } Our function. You can give it several comma-separated sentences. We will see it later. It is a good practice to free the commands. Making <EMPHASIS>non queries</EMPHASIS> Non queries are queries that does not return data, only the number of rows affected, as a DELETE or an UPDATE. We use gda_connection_execute_non_query() gint execute_sql_non_query (GdaConnection *connection, const gchar * buffer) { GdaCommand *command; gint number; command = gda_command_new (buffer, GDA_COMMAND_TYPE_SQL, GDA_COMMAND_OPTION_STOP_ON_ERRORS); number = gda_connection_execute_non_query (connection, command, NULL); gda_command_free (command); return (number); } Making normal queries Normal queries are queries that return data (data models). You have two ways to do this: gda_data_model_execute_single_command() gda_data_model_execute_command() You can use the first way when you want to invoke only a single command. Second way is used to execute several comma-separated sentences. It is recommended to use gda_connection_execute_single_command (). Here you see an example: gboolean execute_sql_command (GdaConnection *connection, const gchar * buffer) { GdaCommand *command; GList *list; GList *node; gboolean errors=FALSE; GdaDataModel *dm; command = gda_command_new (buffer, GDA_COMMAND_TYPE_SQL, GDA_COMMAND_OPTION_STOP_ON_ERRORS); list = gda_connection_execute_command (connection, command, NULL); if (list!=NULL) for (node=g_list_first(list); node != NULL; node=g_list_next(node)) { dm=(GdaDataModel *) node->data; if (dm == NULL) { errors=TRUE; } else { show_table (dm); g_object_unref(dm); } } else { errors=TRUE; } gda_command_free (command); return (errors); } Executes de query and obtains a list of data models Loop for moving through the list of data models. If you use gda_connection_execute_single_command(), you should not need to use a loop, because this function would return a data model. Managing <EMPHASIS>data models</EMPHASIS> Each time we execute a normal query, we will obtain a GdaDataModel object, which is the way to see what the query returned. As GdaDataModel is an object, we can manage it with GdaDataModel class. Before continuing, we must say that it is possible to modify a data model, but as we are accessing using &SQL;, it is not recommended to modify it, so modifications on the database must be done using &SQL;. Let's see the functions we need: gda_data_model_get_n_rows() gda_data_model_get_n_columns() gda_data_model_describe_column() gda_data_model_get_column_title() gda_data_model_get_column_position() gda_data_model_get_row() gda_data_model_get_value_at() gda_row_get_value() This functions are very easy to use, so let's see some clear examples: Example using direct cell access This function accesses the data model by directly accessing cells (using gda_data_model_get_value_at () ) void show_table (GdaDataModel * dm) { gint row_id; gint column_id; GdaValue *value; for (column_id = 0; column_id < gda_data_model_get_n_columns (dm); column_id++) g_print("%s\t",gda_data_model_get_column_title (dm, column_id)); g_print("\n"); for (row_id = 0; row_id < gda_data_model_get_n_rows (dm); row_id++) { for (column_id = 0; column_id < gda_data_model_get_n_columns (dm); column_id++) { value = (GdaValue *) gda_data_model_get_value_at (dm, column_id, row_id); g_print ("%s\t", gda_value_stringify (value)); } g_print("\n"); } } Loop for writing column names. Double loop accessing values using gda_data_model_get_value_at () Data returned is a GdaValue object. Example using row access This function accesses the data model by accessing rows (using gda_data_model_get_row () and gda_row_get_value () ) void show_table2 (GdaDataModel * dm) { gint row_id; gint column_id; GdaValue *value; GdaRow *row; for (column_id = 0; column_id < gda_data_model_get_n_columns (dm); column_id++) g_print("%s\t",gda_data_model_get_column_title (dm, column_id)); g_print("\n"); for (row_id = 0; row_id < gda_data_model_get_n_rows (dm); row_id++) { row = (GdaRow *) gda_data_model_get_row (dm, row_id); for (column_id = 0; column_id < gda_data_model_get_n_columns (dm); column_id++) { value = gda_row_get_value (row, column_id); string=gda_value_stringify (value); g_print ("%s\t", string); gda_value_free(value); g_free(string); } g_print ("\n"); } } Loop for writing column names. Outer loop obtaining rows using gda_data_model_get_row () Inner loop obtaining the value using gda_row_get_value () . Notice that gda_row_get_value () doesn't return a const GdaValue, so we have to free it. Freeing data models When you finish using data models you must free it, but GdaDataModel class does not have a function to do it, so you have to use g_object_unref (). Managing values Values returned by functions of managing data are GdaValue objects. GdaValue class has many functions to access data, so we show the most important ones of them: gda_value_free() gda_value_is_null() gda_value_copy() gda_value_compare() gda_value_stringify() There are many functions to know what is the type of a value and to manage values, that can be seen in GdaValue class. We will return to the examples about last section to notice some important details: void show_table2 (GdaDataModel * dm) { gint row_id; gint column_id; GdaValue *value; GdaRow *row; gchar *string; for (column_id = 0; column_id < gda_data_model_get_n_columns (dm); column_id++) g_print("%s\t",gda_data_model_get_column_title (dm, column_id)); g_print("\n"); for (row_id = 0; row_id < gda_data_model_get_n_rows (dm); row_id++) { row = (GdaRow *) gda_data_model_get_row (dm, row_id); for (column_id = 0; column_id < gda_data_model_get_n_columns (dm); column_id++) { value = gda_row_get_value (row, column_id); string=gda_value_stringify (value); g_print ("%s\t", string); gda_value_free(value); g_free(string); } g_print ("\n"); } } Loop for writing column names. Outer loop obtaining rows using gda_data_model_get_row () Inner loop obtaining the value using gda_row_get_value () . Notice that gda_row_get_value () doesn't return a const GdaValue, so we have to free it. We have the difference here. As you can see above, gda_value_stringify () does not return a const gchar *, so you have to free it. First way is quite attractive but it is not good.
Title: Managing transactions
The special functions we need to do this are defined in the GdaTransaction, GdaConnection and GdaCommand classes, and they are: gda_transaction_new () gda_connection_begin_transaction () gda_connection_commit_transaction () gda_connection_rollback_transaction () gda_command_set_transaction () Things you have to do to manage transactions are: Create transaction Link transaction to a connection For each command you want to execute: Create command Link transaction to command Execute command Free command Commit o rollback transaction Free transaction Here you can see an example: void process_accounts(GdaConnection *connection) { GdaTransaction *transaction_one, *transaction_two; GdaCommand *command; transaction_one=gda_transaction_new("accounts1"); gda_connection_begin_transaction(connection,transaction_one); command=gda_command_new ( "UPDATE accounts SET balance=balance+50" "WHERE account_code=456", GDA_COMMAND_TYPE_SQL, GDA_COMMAND_OPTION_STOP_ON_ERRORS); gda_command_set_transaction(command,transaction_one); gda_connection_execute_non_query(connection,command,NULL); gda_command_free(command); command=gda_command_new ( "UPDATE accounts SET balance=balance-50" "WHERE account_code=12", GDA_COMMAND_TYPE_SQL, GDA_COMMAND_OPTION_STOP_ON_ERRORS); gda_command_set_transaction(command,transaction_one); gda_connection_execute_non_query(connection,command,NULL); gda_command_free(command); gda_connection_commit_transaction(connection,transaction_one); g_object_unref(transaction_one); transaction_two=gda_transaction_new("accounts2"); gda_connection_begin_transaction(connection,transaction_two); command=gda_command_new ( "UPDATE accounts SET balance=balance+400" "WHERE account_code=456", GDA_COMMAND_TYPE_SQL, GDA_COMMAND_OPTION_STOP_ON_ERRORS); gda_command_set_transaction(command,transaction_two); gda_connection_execute_non_query(connection,command,NULL); gda_command_free(command); command=gda_command_new ( "UPDATE accounts SET balance=balance-400" "WHERE account_code=12", GDA_COMMAND_TYPE_SQL, GDA_COMMAND_OPTION_STOP_ON_ERRORS); gda_command_set_transaction(command,transaction_two); gda_connection_execute_non_query(connection,command,NULL); gda_command_free(command); gda_connection_rollback_transaction(connection,transaction_two); g_object_unref(transaction_one); execute_sql_command(connection,"SELECT * FROM accounts"); } Creates first transaction. Links it to connection. Links command to transaction. Makes commit on transaction. Frees transaction. Makes rollback on second transaction.
<para>
  You can manage errors with <LINK
  LINKEND="libgda-GdaError">GdaError</LINK> class and obtain them with
  function <LINK
  LINKEND="gda-connection-get-errors"><EMPHASIS>gda_connection_get_errors()
  </EMPHASIS></LINK><footnote>If you cannot see the link in <LINK
  LINKEND="gda-connection-get-errors">gda_connection_get_errors()</LINK>,
  it means that it is not included in the documentation yet.</footnote>
  so let's see them and an example: 
</para>
<para>
  Here you see the functions to manage errors:
</para>
<ITEMIZEDLIST>
  <LISTITEM>
    <LINK LINKEND="gda-error-get-description">gda_error_get_description()</LINK>
  </LISTITEM>
  <LISTITEM>
    <LINK LINKEND="gda-error-get-number">gda_error_get_number()</LINK>
  </LISTITEM>
  <LISTITEM>
    <LINK LINKEND="gda-error-get-source">gda_error_get_source()</LINK>
  </LISTITEM>
  <LISTITEM>
    <LINK LINKEND="gda-error-get-sqlstate">gda_error_get_sqlstate()</LINK>
  </LISTITEM>
</ITEMIZEDLIST>
<para>
  Here you can see an example of using this:
</para>
<PROGRAMLISTINGCO>
  <AREASPEC UNITS="LINECOLUMN">
    <AREA ID="errors-1" COORDS="8 1">
    <AREA ID="errors-2" COORDS="10 1">
  </AREASPEC>
  <programlisting>
  gboolean
  get_errors (GdaConnection *connection)
  {
    GList *list;
    GList *node;
    GdaError *error;
  
    list = (GList *) gda_connection_get_errors (connection);
  
    for (node = g_list_first (list); node != NULL; node = g_list_next (node))
      {
        error = (GdaError *) node->data;
        g_print ("Error no: %d\t", gda_error_get_number (error));
        g_print ("desc: %s\t", gda_error_get_description (error));
        g_print ("source: %s\t", gda_error_get_source (error));
        g_print ("sqlstate: %s\n", gda_error_get_sqlstate (error));
      }
  }
  </programlisting>
  <CALLOUTLIST>
    <CALLOUT AREAREFS="errors-1">
      <PARA>
        Obtains errors list.
      </PARA>
    </CALLOUT>
    <CALLOUT AREAREFS="errors-2">
      <PARA>
        Loop for getting error information.
      </PARA>
    </CALLOUT>
  </CALLOUTLIST>
</PROGRAMLISTINGCO>


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