// -*- c++ -*-
// Generated by gmmproc 2.46.1 -- DO NOT MODIFY!
#ifndef _LIBGDAMM_CONNECTION_H
#define _LIBGDAMM_CONNECTION_H


#include <glibmm/ustring.h>
#include <sigc++/sigc++.h>

/* $Id: connection.hg,v 1.35 2006/11/30 06:58:55 murrayc Exp $ */
// -*- C++ -*- //

/* connection.h
 *
 * Copyright 2003 libgdamm Development Team
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <libgdamm/transactionstatus.h>
#include <libgdamm/connectionevent.h>
#include <libgdamm/datamodel.h>
#include <libgdamm/statement.h>
#include <libgdamm/sqlbuilder.h>
#include <libgdamm/sqlparser.h>
#include <libgdamm/serveroperation.h>
#include <libgdamm/serverprovider.h> //For ServerProviderError, sometimes thrown by *execute*().
#include <libgdamm/value.h>


#ifndef DOXYGEN_SHOULD_SKIP_THIS
typedef struct _GdaConnection GdaConnection;
typedef struct _GdaConnectionClass GdaConnectionClass;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Gnome
{

namespace Gda
{ class Connection_Class; } // namespace Gda

} // namespace Gnome
#endif //DOXYGEN_SHOULD_SKIP_THIS

namespace Gnome
{

namespace Gda
{

class ServerProvider;
class MetaStore;
typedef GdaServerProviderInfo ServerProviderInfo;

/** Exception class for Gda connection errors.
 */
class ConnectionError : public Glib::Error
{
public:
  /** 
   */
  enum Code
  {
    CONNECTION_DSN_NOT_FOUND_ERROR,
    CONNECTION_PROVIDER_NOT_FOUND_ERROR,
    CONNECTION_PROVIDER_ERROR,
    CONNECTION_NO_CNC_SPEC_ERROR,
    CONNECTION_NO_PROVIDER_SPEC_ERROR,
    CONNECTION_OPEN_ERROR,
    CONNECTION_STATEMENT_TYPE_ERROR,
    CONNECTION_CANT_LOCK_ERROR,
    CONNECTION_TASK_NOT_FOUND_ERROR,
    CONNECTION_UNSUPPORTED_THREADS_ERROR,
    CONNECTION_CLOSED_ERROR,
    CONNECTION_META_DATA_CONTEXT_ERROR
  };

  ConnectionError(Code error_code, const Glib::ustring& error_message);
  explicit ConnectionError(GError* gobject);
  Code code() const;

#ifndef DOXYGEN_SHOULD_SKIP_THIS
private:

  static void throw_func(GError* gobject);

  friend void wrap_init(); // uses throw_func()

  #endif //DOXYGEN_SHOULD_SKIP_THIS
};

} // namespace Gda

} // namespace Gnome

#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

template <>
class Value<Gnome::Gda::ConnectionError::Code> : public Glib::Value_Enum<Gnome::Gda::ConnectionError::Code>
{
public:
  static GType value_type() G_GNUC_CONST;
};

} // namespace Glib
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


namespace Gnome
{

namespace Gda
{


/** @addtogroup libgdammEnums libgdamm Enums and Flags */

/** 
 *
 * @ingroup libgdammEnums
 * @par Bitwise operators:
 * <tt>%ConnectionOptions operator|(ConnectionOptions, ConnectionOptions)</tt><br>
 * <tt>%ConnectionOptions operator&(ConnectionOptions, ConnectionOptions)</tt><br>
 * <tt>%ConnectionOptions operator^(ConnectionOptions, ConnectionOptions)</tt><br>
 * <tt>%ConnectionOptions operator~(ConnectionOptions)</tt><br>
 * <tt>%ConnectionOptions& operator|=(ConnectionOptions&, ConnectionOptions)</tt><br>
 * <tt>%ConnectionOptions& operator&=(ConnectionOptions&, ConnectionOptions)</tt><br>
 * <tt>%ConnectionOptions& operator^=(ConnectionOptions&, ConnectionOptions)</tt><br>
 */
enum ConnectionOptions
{
  CONNECTION_OPTIONS_NONE = 0x0,
  CONNECTION_OPTIONS_READ_ONLY = 1 << 0,
  CONNECTION_OPTIONS_SQL_IDENTIFIERS_CASE_SENSITIVE = 1 << 1,
  CONNECTION_OPTIONS_THREAD_SAFE = 1 << 2,
  CONNECTION_OPTIONS_THREAD_ISOLATED = 1 << 3,
  CONNECTION_OPTIONS_AUTO_META_DATA = 1 << 4
};

/** @ingroup libgdammEnums */
inline ConnectionOptions operator|(ConnectionOptions lhs, ConnectionOptions rhs)
  { return static_cast<ConnectionOptions>(static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs)); }

/** @ingroup libgdammEnums */
inline ConnectionOptions operator&(ConnectionOptions lhs, ConnectionOptions rhs)
  { return static_cast<ConnectionOptions>(static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs)); }

/** @ingroup libgdammEnums */
inline ConnectionOptions operator^(ConnectionOptions lhs, ConnectionOptions rhs)
  { return static_cast<ConnectionOptions>(static_cast<unsigned>(lhs) ^ static_cast<unsigned>(rhs)); }

/** @ingroup libgdammEnums */
inline ConnectionOptions operator~(ConnectionOptions flags)
  { return static_cast<ConnectionOptions>(~static_cast<unsigned>(flags)); }

/** @ingroup libgdammEnums */
inline ConnectionOptions& operator|=(ConnectionOptions& lhs, ConnectionOptions rhs)
  { return (lhs = static_cast<ConnectionOptions>(static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs))); }

/** @ingroup libgdammEnums */
inline ConnectionOptions& operator&=(ConnectionOptions& lhs, ConnectionOptions rhs)
  { return (lhs = static_cast<ConnectionOptions>(static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs))); }

/** @ingroup libgdammEnums */
inline ConnectionOptions& operator^=(ConnectionOptions& lhs, ConnectionOptions rhs)
  { return (lhs = static_cast<ConnectionOptions>(static_cast<unsigned>(lhs) ^ static_cast<unsigned>(rhs))); }

} // namespace Gda

} // namespace Gnome


#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

template <>
class Value<Gnome::Gda::ConnectionOptions> : public Glib::Value_Flags<Gnome::Gda::ConnectionOptions>
{
public:
  static GType value_type() G_GNUC_CONST;
};

} // namespace Glib
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


namespace Gnome
{

namespace Gda
{

/** 
 *
 * @ingroup libgdammEnums
 */
enum ConnectionMetaType
{
  CONNECTION_META_NAMESPACES,
  CONNECTION_META_TYPES,
  CONNECTION_META_TABLES,
  CONNECTION_META_VIEWS,
  CONNECTION_META_FIELDS,
  CONNECTION_META_INDEXES
};

} // namespace Gda

} // namespace Gnome


#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

template <>
class Value<Gnome::Gda::ConnectionMetaType> : public Glib::Value_Enum<Gnome::Gda::ConnectionMetaType>
{
public:
  static GType value_type() G_GNUC_CONST;
};

} // namespace Glib
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


namespace Gnome
{

namespace Gda
{


/** Manages a connection to a data source.
 * This class offers access to all operations involving an opened connection to a database.
 * Connection objects are obtained via the Client class.
 *
 * Once obtained, applications can use a Connection to execute commands, run transactions, and get information about all
 * objects stored in the underlying database.
 *
 * @ingroup Connections
 */

class Connection : public Glib::Object
{
  
#ifndef DOXYGEN_SHOULD_SKIP_THIS

public:
  typedef Connection CppObjectType;
  typedef Connection_Class CppClassType;
  typedef GdaConnection BaseObjectType;
  typedef GdaConnectionClass BaseClassType;

  // noncopyable
  Connection(const Connection&) = delete;
  Connection& operator=(const Connection&) = delete;

private:  friend class Connection_Class;
  static CppClassType connection_class_;

protected:
  explicit Connection(const Glib::ConstructParams& construct_params);
  explicit Connection(GdaConnection* castitem);

#endif /* DOXYGEN_SHOULD_SKIP_THIS */

public:

  Connection(Connection&& src) noexcept;
  Connection& operator=(Connection&& src) noexcept;

  virtual ~Connection() noexcept;

  /** Get the GType for this class, for use with the underlying GObject type system.
   */
  static GType get_type()      G_GNUC_CONST;

#ifndef DOXYGEN_SHOULD_SKIP_THIS


  static GType get_base_type() G_GNUC_CONST;
#endif

  ///Provides access to the underlying C GObject.
  GdaConnection*       gobj()       { return reinterpret_cast<GdaConnection*>(gobject_); }

  ///Provides access to the underlying C GObject.
  const GdaConnection* gobj() const { return reinterpret_cast<GdaConnection*>(gobject_); }

  ///Provides access to the underlying C instance. The caller is responsible for unrefing it. Use when directly setting fields in structs.
  GdaConnection* gobj_copy();

private:

protected:

  Connection();
  

public:
  
  static Glib::RefPtr<Connection> create();


  static Glib::RefPtr<Connection> create_from_string(const Glib::ustring& provider_name, const Glib::ustring& cnc_string, const Glib::ustring& auth_string =  Glib::ustring(), ConnectionOptions options =  CONNECTION_OPTIONS_NONE);

  /* This throws an error which we don't want to do in a constructor */
  
  /** Opens a connection given a provider ID and a connection string. This
   * allows applications to open connections without having to create
   * a data source (DSN) in the configuration. The format of @a cnc_string is
   * similar to PostgreSQL and MySQL connection strings. It is a semicolumn-separated
   * series of <key>=<value> pairs, where each key and value are encoded as per RFC 1738, 
   * see gda_rfc1738_encode() for more information.
   * 
   * The possible keys depend on the provider, the "gda-sql-4.0 -L" command
   * can be used to list the actual keys for each installed database provider.
   * 
   * For example the connection string to open an SQLite connection to a database
   * file named "my_data.db" in the current directory would be <tt>"DB_DIR=.;DB_NAME=my_data"</tt>.
   * 
   * The @a cnc_string string must have the following format: 
   * "[<provider>://][<username>[:<password>]@]<connection_params>"
   * (if <username> and/or <password> are provided, and @a auth_string is <tt>0</tt>, then these username
   * and passwords will be used, and if <provider> is provided and @a provider_name is <tt>0</tt> then this
   * provider will be used). Note that if provided, <username>, <password> and  <provider>
   * must be encoded as per RFC 1738, see gda_rfc1738_encode() for more information.
   * 
   * The @a auth_string must contain the authentication information for the server
   * to accept the connection. It is a string containing semi-colon seperated named values, usually 
   * like "USERNAME=...;PASSWORD=..." where the ... are replaced by actual values. Note that each
   * name and value must be encoded as per RFC 1738, see gda_rfc1738_encode() for more information.
   * 
   * The actual named parameters required depend on the provider being used, and that list is available
   * as the <parameter>auth_params</parameter> member of the Gda::ProviderInfo structure for each installed
   * provider (use Gda::Config::get_provider_info() to get it). Similarly to the format of the connection
   * string, use the "gda-sql-4.0 -L" command to list the possible named parameters.
   * 
   * Additionally, it is possible to have the connection string
   * respect the "<provider_name>://<real cnc string>" format, in which case the provider name
   * and the real connection string will be extracted from that string (note that if @a provider_name
   * is not <tt>0</tt> then it will still be used as the provider ID).\\
   * 
   * This method may fail with a GDA_CONNECTION_ERROR domain error (see the Gda::ConnectionError error codes) 
   * or a Gda::CONFIG_ERROR domain error (see the Gda::ConfigError error codes).
   * 
   * @param provider_name Provider ID to connect to, or <tt>0</tt>.
   * @param cnc_string Connection string.
   * @param auth_string Authentication string, or <tt>0</tt>.
   * @param options Options for the connection (see Gda::ConnectionOptions).
   * @return A new Gda::Connection if connection opening was sucessfull or <tt>0</tt> if there was an error.
   */

  static Glib::RefPtr<Connection> open_from_string(const Glib::ustring& provider_name,
                                                    const Glib::ustring& cnc_string,
                                                    const Glib::ustring& auth_string = Glib::ustring(),
                                                    ConnectionOptions options = CONNECTION_OPTIONS_NONE);

  
  /** Tries to open the connection.
   * 
   * @return <tt>true</tt> if the connection is opened, and <tt>false</tt> otherwise.
   */
  bool open();

  /** Closes the connection to the underlying data source, but first emits the "conn_to_close" signal.
   */
  void close();
  

  //gtkmmproc error: gda_connection_internal_treat_sql : ignored method defs lookup failed//gtkmmproc error: gda_connection_execute_command : ignored method defs lookup failed//gtkmmproc error: gda_connection_internal_sql_executed : ignored method defs lookup failed

  
  /** Checks whether a connection is open or not.
   * 
   * @return <tt>true</tt> if the connection is open, <tt>false</tt> if it's not.
   */
  bool is_opened() const;

  
  /** Gets the Gda::ConnectionOptions used to open this connection.
   * 
   * @return The connection options.
   */
  ConnectionOptions get_options() const;

  
  /** @return The data source name the connection object is connected
   * to.
   */
  Glib::ustring get_dsn() const;
  
  /** Gets the connection string used to open this connection.
   * 
   * The connection string is the string sent over to the underlying
   * database provider, which describes the parameters to be used
   * to open a connection on the underlying data source.
   * 
   * @return The connection string used when opening the connection.
   */
  Glib::ustring get_cnc_string() const;

  
  /** This function lets you clear the list of Gda::ConnectionEvent's of the
   * given connection.
   */
  void clear_events_list();

  
  /** Executes @a stmt. 
   * 
   * As @a stmt can, by desing (and if not abused), contain only one SQL statement, the
   * return object will either be:
   * - a Gda::DataSelect object (which is also a Gda::DataModel) if @a stmt is a SELECT statement 
   * (usually a GDA_SQL_STATEMENT_SELECT, see Gda::SqlStatementType)
   * containing the results of the SELECT. The resulting data model is by default read only, but
   * modifications can be enabled, see the Gda::DataSelect's documentation for more information.
   * - a Gda::Set for any other SQL statement which correctly executed. In this case
   * (if the provider supports it), then the Gda::Set may contain value holders named:
   * <itemizedlist>
   * <listitem>a (<tt>int</tt>) Gda::Holder named "IMPACTED_ROWS"
   * - a (GObject) Gda::Holder named "EVENT" which contains a Gda::ConnectionEvent
   * </listitem>
   * </itemizedlist>
   * 
   * If @a last_insert_row is not <tt>0</tt> and @a stmt is an INSERT statement, then it will contain (if the
   * provider used by @a cnc supports it) a new Gda::Set object composed of value holders named "+<column number>"
   * starting at column 0 which contain the actual inserted values. For example if a table is composed of an 'id' column
   * which is auto incremented and a 'name' column then the execution of a "INSERT INTO mytable (name) VALUES ('joe')"
   * query will return a Gda::Set with two holders:
   * - one with the '+0' ID which may for example contain 1 (note that its "name" property should be "id")
   * - one with the '+1' ID which will contain 'joe' (note that its "name" property should be "name")
   * 
   * This method may fail with a Gda::SERVER_PROVIDER_ERROR domain error (see the Gda::ServerProviderError error codes).
   * 
   * @note If @a stmt is a SELECT statement which has some parameters and  if @a params is <tt>0</tt>, then the statement can't
   * be executed and this method will return <tt>0</tt>.
   * 
   * @note If @a stmt is a SELECT statement which has some parameters and  if @a params is not <tt>0</tt> but contains some
   * invalid parameters, then the statement can't be executed and this method will return <tt>0</tt>, unless the
   *  @a model_usage has the GDA_STATEMENT_MODEL_ALLOW_NOPARAM flag.
   * 
   * @note If @a stmt is a SELECT statement which has some parameters and  if @a params is not <tt>0</tt> but contains some
   * invalid parameters and if @a model_usage has the GDA_STATEMENT_MODEL_ALLOW_NOPARAM flag, then the returned
   * data model will contain no row but will have all the correct columns (even though some of the columns might
   * report as GDA_TYPE_NULL). In this case, if (after this method call) any of @a params' parameters change
   * then the resulting data model will re-run itself, see the GdaDataSelect's 
   * auto-reset property for more information.
   * 
   * @note if @a model_usage does not contain the GDA_STATEMENT_MODEL_RANDOM_ACCESS or
   * GDA_STATEMENT_MODEL_CURSOR_FORWARD flags, then the default will be to return a random access data model
   * 
   * @note If @a stmt is a SELECT statement which returns blob values (of type Gda::TYPE_BLOB), then an implicit
   * transaction will have been started by the database provider, and it's up to the caller to close the transaction
   * (which will then be locked) once all the blob ressources have been
   * liberated (when the returned data model is destroyed). See the section about
   * Binary large objects (BLOBs) for more information.
   * 
   * Also see the provider's limitations, and the
   * Advanced GdaDataSelect usage sections.
   * 
   * @param stmt A Gda::Statement object.
   * @param params A Gda::Set object (which can be obtained using Gda::Statement::get_parameters()), or <tt>0</tt>.
   * @param model_usage In the case where @a stmt is a SELECT statement, specifies how the returned data model will be used.
   * @param last_insert_row A place to store a new Gda::Set object which contains the values of the last inserted row, or <tt>0</tt>.
   * @return A Object, or <tt>0</tt> if an error occurred.
   */

  Glib::RefPtr<Glib::Object> statement_execute(const Glib::RefPtr<const Statement>& stmt, const Glib::RefPtr<const Set>& params, StatementModelUsage model_usage, Glib::RefPtr<const Set>& last_insert_row);

//TODO: Documentation:
  Glib::RefPtr<Glib::Object> statement_execute(const Glib::RefPtr<const Statement>& stmt, StatementModelUsage model_usage = STATEMENT_MODEL_RANDOM_ACCESS);


  Glib::RefPtr<Glib::Object> statement_execute(const Glib::ustring& sql, StatementModelUsage model_usage = STATEMENT_MODEL_RANDOM_ACCESS);

  //_WRAP_METHOD(Glib::RefPtr<DataModel> statement_execute_select(const Glib::RefPtr<const Statement>& stmt, const Glib::RefPtr<const Set>& params), gda_connection_statement_execute_select, errthrow)
   //We instead create a version that can take an optional usage parameter too.

 
  /** Executes a selection command on the given connection.
   * 
   * This function returns a Gda::DataModel resulting from the SELECT statement, or <tt>0</tt>
   * if an error occurred.
   * 
   * This function is just a convenience function around the statement_execute()
   * function.
   * 
   * See the documentation of the statement_execute() for information
   * about the @a params list of parameters.
   * 
   * @param stmt A Gda::Statement object.
   * @param params A Gda::Set object (which can be obtained using Gda::Statement::get_parameters()), or <tt>0</tt>.
   * @param model_usage Specifies how the returned data model will be used as a Gda::StatementModelUsage enum.
   * @param col_types An array of GType to request each returned Gda::DataModel's column's GType, terminated with the G_TYPE_NONE
   * value. Any value left to 0 will make the database provider determine the real GType. @a col_types can also be <tt>0</tt> if no
   * column type is specified.
   * @return A Gda::DataModel containing the data returned by the
   * data source, or <tt>0</tt> if an error occurred.
   */
  Glib::RefPtr<DataModel> statement_execute_select(const Glib::RefPtr<const Statement>& stmt, const Glib::RefPtr<const Set>& params, StatementModelUsage model_usage, const std::vector<GType>& col_types);
  

//This custom-written method has more optional methods than gda_connection_execute_select_command().
//TODO: Documentation:
  Glib::RefPtr<DataModel> statement_execute_select(const Glib::RefPtr<const Statement>& stmt, StatementModelUsage model_usage = STATEMENT_MODEL_RANDOM_ACCESS);
  Glib::RefPtr<DataModel> statement_execute_select(const Glib::ustring& sql, StatementModelUsage model_usage = STATEMENT_MODEL_RANDOM_ACCESS);

//This custom-written method has more optional methods than gda_connection_execute_select_command().
//TODO: Documentation:
  Glib::RefPtr<DataModel> statement_execute_select(const Glib::RefPtr<const Statement>& stmt, const Glib::RefPtr<const Set>& params, StatementModelUsage model_usage = STATEMENT_MODEL_RANDOM_ACCESS);
  Glib::RefPtr<DataModel> statement_execute_select(const Glib::ustring& sql, const Glib::RefPtr<const Set>& params, StatementModelUsage model_usage = STATEMENT_MODEL_RANDOM_ACCESS);
  

//TODO: Documentation:
//Note that we add the prefix _builder() because overloading on different RefPtr<> types seems to be ambiguous.
  Glib::RefPtr<DataModel> statement_execute_select_builder(const Glib::RefPtr<const SqlBuilder>& stmt, StatementModelUsage model_usage = STATEMENT_MODEL_RANDOM_ACCESS);

//TODO: Documentation:
//Note that we add the prefix _builder() because overloading on different RefPtr<> types seems to be ambiguous.
  Glib::RefPtr<DataModel> statement_execute_select_builder(const Glib::RefPtr<const SqlBuilder>& stmt, const Glib::RefPtr<const Set>& params, StatementModelUsage model_usage = STATEMENT_MODEL_RANDOM_ACCESS);


  /** Executes a non-selection statement on the given connection. The gda_execute_non_select_command() method can be easier
   * to use if one prefers to use some SQL directly.
   * 
   * This function returns the number of rows affected by the execution of @a stmt, or -1
   * if an error occurred, or -2 if the connection's provider does not return the number of rows affected.
   * 
   * This function is just a convenience function around the statement_execute()
   * function. 
   * See the documentation of the statement_execute() for information
   * about the @a params list of parameters.
   * 
   * See statement_execute() form more information about @a last_insert_row.
   * 
   * @param stmt A Gda::Statement object.
   * @param params A Gda::Set object (which can be obtained using Gda::Statement::get_parameters()), or <tt>0</tt>.
   * @param last_insert_row A place to store a new Gda::Set object which contains the values of the last inserted row, or <tt>0</tt>.
   * @return The number of rows affected (>=0) or -1 or -2.
   */

//TODO: Documentation:
//TODO: It's not nice that these two method overloads differ only by the constness of the set.
  int statement_execute_non_select(const Glib::RefPtr<const Statement>& stmt, const Glib::RefPtr<const Set>& params, Glib::RefPtr<const Set>& last_insert_row);

//TODO: Documentation:
  int statement_execute_non_select(const Glib::RefPtr<const Statement>& stmt, const Glib::RefPtr<const Set>& params);

//TODO: Documentation:
  int statement_execute_non_select(const Glib::RefPtr<const Statement>& stmt);

  
  int statement_execute_non_select(const Glib::ustring& sql);

//TODO: Documentation:
  int statement_execute_non_select_builder(const Glib::RefPtr<const SqlBuilder>& builder);

//TODO: Documentation:
  int statement_execute_non_select_builder(const Glib::RefPtr<const SqlBuilder>& builder, const Glib::RefPtr<const Set>& params);

  
  /** This method is similar to statement_execute() but is asynchronous as it method returns
   * immediately with a task ID. It's up to the caller to use async_fetch_result() regularly to check
   * if the statement's execution is finished.
   * 
   * It is possible to call the method several times to request several statements to be executed asynchronously, the
   * statements will be executed in the order in which they were requested.
   * 
   * The parameters, if present, are copied and can be discarded or modified before the statement is actually executed.
   * The @a stmt object is not copied but simply referenced (for performance reasons), and if it is modified before
   * it is actually executed, then its execution will not occur. It is however safe to call Glib::object_unref() on it if
   * it's not needed anymore.
   * 
   * The execution failure of any statement has no impact on the execution of other statements except for example if
   * the connection has a transaction started and the failure invalidates the transaction (as decided by the database
   * server).
   * 
   * @newin{4,2}
   * 
   * @param stmt A Gda::Statement object.
   * @param params A Gda::Set object (which can be obtained using Gda::Statement::get_parameters()), or <tt>0</tt>.
   * @param model_usage In the case where @a stmt is a SELECT statement, specifies how the returned data model will be used.
   * @param col_types An array of GType to request each returned Gda::DataModel's column's GType, terminated with the G_TYPE_NONE.
   * @param need_last_insert_row <tt>true</tt> if the values of the last interted row must be computed.
   * @return A task ID, or 0 if an error occurred (not an error regarding @a stmt itself as its execution has not yet started
   * but any other error).
   */
  guint async_statement_execute(const Glib::RefPtr<const Statement>& stmt, const Glib::RefPtr<const Set>& params, StatementModelUsage model_usage, const std::vector<GType>& col_types, bool need_last_insert_row =  false);

  //TODO: Wrap the last_insert_row parameter properly and add an overload without it:
  
  /** Use this method to obtain the result of the execution of a statement which has been executed asynchronously by
   * calling async_statement_execute(). This function is non locking and will return <tt>0</tt> (and no
   * error will be set) if the statement has not been executed yet.
   * 
   * If the statement has been executed, this method returns the same value as statement_execute()
   * would have if the statement had been
   * executed synchronously.
   * 
   * @newin{4,2}
   * 
   * @param task_id A task ID returned by async_statement_execute().
   * @param last_insert_row A place to store a new Gda::Set object which contains the values of the last inserted row, or <tt>0</tt>.
   * @return A Object, or <tt>0</tt> if an error occurred.
   */
  Glib::RefPtr<Glib::Object> async_fetch_result(guint task_id, GdaSet ** last_insert_row);
  
  /** Requests that a task be cancelled. This operation may of may not have any effect
   * depending on the task's status, even if it returns <tt>true</tt>. If it returns <tt>false</tt>,
   * then the task has not been cancelled.
   * 
   * @newin{4,2}
   * 
   * @param task_id A task ID returned by async_statement_execute().
   * @return <tt>true</tt> if no error occurred.
   */
  bool async_cancel(guint task_id);

//TODO: #m4 __CONVERSION(`GSList*',`std::vector<Glib::Object>',`$2(Glib::SListHandler<Glib::RefPtr<const Statement> >::slist_to_vector((GSList*)$3, Glib::OWNERSHIP_DEEP))')
//  _WRAP_METHOD(std::vector<Glib::Object> repetitive_statement_execute(GdaRepetitiveStatement *rstmt, StatementModelUsage model_usage, const std::vector<GType>& col_types, gboolean stop_on_error = true), gda_connection_repetitive_statement_execute, errthrow)

  //Note that we do not add a non-const version of this because the documentation says that it should not be modified:
  
  /** Get the status of @a cnc regarding transactions. The returned object should not be modified
   * or destroyed; however it may be modified or destroyed by the connection itself.
   * 
   * If <tt>0</tt> is returned, then no transaction has been associated with @a cnc
   * 
   * @return A Gda::TransactionStatus object, or <tt>0</tt>.
   */
  Glib::RefPtr<const TransactionStatus> get_transaction_status() const;

  
  /** Starts a transaction on the data source, identified by the
   *  @a name parameter.
   * 
   * Before starting a transaction, you can check whether the underlying
   * provider does support transactions or not by using the
   * supports_feature() function.
   * 
   * @param name The name of the transation to start, or <tt>0</tt>.
   * @param level The requested transaction level (Gda::TRANSACTION_ISOLATION_UNKNOWN if not specified).
   * @return <tt>true</tt> if the transaction was started successfully, <tt>false</tt>
   * otherwise.
   */
  bool begin_transaction(const Glib::ustring& name, TransactionIsolation level);
  
  /** Commits the given transaction to the backend database. You need to call
   * begin_transaction() first.
   * 
   * @param name The name of the transation to commit, or <tt>0</tt>.
   * @return <tt>true</tt> if the transaction was finished successfully,
   * <tt>false</tt> otherwise.
   */
  bool commit_transaction(const Glib::ustring& name);
  
  /** Rollbacks the given transaction. This means that all changes
   * made to the underlying data source since the last call to
   * #begin_transaction() or #commit_transaction()
   * will be discarded.
   * 
   * @param name The name of the transation to commit, or <tt>0</tt>.
   * @return <tt>true</tt> if the operation was successful, <tt>false</tt> otherwise.
   */
  bool rollback_transaction(const Glib::ustring& name);

  
  /** Adds a SAVEPOINT named @a name.
   * 
   * @param name Name of the savepoint to add.
   * @return <tt>true</tt> if no error occurred.
   */
  bool add_savepoint(const Glib::ustring& name);
  
  /** Rollback all the modifications made after the SAVEPOINT named @a name.
   * 
   * @param name Name of the savepoint to rollback to.
   * @return <tt>true</tt> if no error occurred.
   */
  bool rollback_savepoint(const Glib::ustring& name);
  
  /** Delete the SAVEPOINT named @a name when not used anymore.
   * 
   * @param name Name of the savepoint to delete.
   * @return <tt>true</tt> if no error occurred.
   */
  bool delete_savepoint(const Glib::ustring& name);


   //Use a special conversion here, because we should not own any part of the returned GList,
   //according to the documentation for gda_connection_get_events(),
   //and because we need to unconst the GList.:
    

  /** Retrieves a list of the last errors occurred during the connection. The returned list is
   * chronologically ordered such as that the most recent event is the Gda::ConnectionEvent of the first node.
   * 
   * Warning: the @a cnc object may change the list if connection events occur
   * 
   * @return A List of Gda::ConnectionEvent objects (the list should not be modified).
   */
  std::vector< Glib::RefPtr<ConnectionEvent> > get_events();
  
  /** Retrieves a list of the last errors occurred during the connection. The returned list is
   * chronologically ordered such as that the most recent event is the Gda::ConnectionEvent of the first node.
   * 
   * Warning: the @a cnc object may change the list if connection events occur
   * 
   * @return A List of Gda::ConnectionEvent objects (the list should not be modified).
   */
  std::vector< Glib::RefPtr<const ConnectionEvent> > get_events() const;

 
  bool insert_row_into_table(const Glib::ustring& table, const std::vector<Glib::ustring>& col_names, const std::vector<Value>& values);
  

  bool update_row_in_table(const Glib::ustring& table, const Glib::ustring& condition_column_name, const Value& condition_value, const std::vector<Glib::ustring>& col_names, const std::vector<Value>& values);

  
  bool delete_row_from_table(const Glib::ustring& table, const Glib::ustring& condition_column_name, const Value& condition_value);
  

  /** Produces a fully quoted and escaped string from a GValue
   * 
   * @param from Value to convert from.
   * @return Escaped and quoted value or <tt>0</tt> if not supported.
   */
  Glib::ustring value_to_sql_string(const Value& from) const;

  
  /** Asks the underlying provider for if a specific feature is supported.
   * 
   * @param feature Feature to ask for.
   * @return <tt>true</tt> if the provider supports it, <tt>false</tt> if not.
   */
  bool supports_feature(ConnectionFeature feature) const;

  
  /** Gets the user name used to open this connection.
   * 
   * @return The user name.
   */
  Glib::ustring get_authentication() const;

  //TODO: Wrap the GdaSet** output parameter:
  //_WRAP_METHOD(Glib::RefPtr<Statement> parse_sql_string(const Glib::ustring& sql, GdaSet** params), gda_connection_parse_sql_string, errthrow)

  /** This helps to parse a SQL string.
   *
   * @param sql An SQL command to parse.
   * @result A Statement representing the SQL command or an empty RefPtr if an error occurred.
   */
  Glib::RefPtr<Statement> parse_sql_string(const Glib::ustring& sql);
  

  /** Creates a new parser object able to parse the SQL dialect understood by @a cnc. 
   * If the Gda::ServerProvider object internally used by @a cnc does not have its own parser, 
   * then <tt>0</tt> is returned, and a general SQL parser can be obtained
   * using Gda::SqlParser::new().
   * 
   * @return A new Gda::SqlParser object, or <tt>0</tt>.
   */
  Glib::RefPtr<SqlParser> create_parser();

  
  /** Gets the name (identifier) of the database provider used by @a cnc
   * 
   * @return A non modifiable string.
   */
  Glib::ustring get_provider_name() const;

  /** Update the full meta store information.
   *
   * Note that this may take some time for big databases
   * @return <tt>true</tt> if no error occurred.
   */
  bool update_meta_store();

  /** Update the meta store information @a id
   *
   * This can speed up the update of the meta store if you only need a
   * specific information
   * @param id An id for the information to update (see http://library.gnome.org/devel/libgda/unstable/information_schema.html)
   * @return <tt>true</tt> if no error occurred.
   */
  bool update_meta_store(const Glib::ustring& id);
  

  /** Update the meta store information for the table named @a table_name
   *
   * This can speed up the update of the meta store if you only need the information
   * for a specific table
   * @param table_name Name of the table where the information is needed
   * @param schema_name Name of the schema @table_name is in, or "" to update
   * all tables with the given name. As with update_meta_store_table_names(),
   * specifying a non-empty schema_name speeds up the operation, just not as
   * significantly as with update_meta_store_table_names() because the
   * operation itself is already pretty quick.
   * @return <tt>true</tt> if no error occurred.
   */
  bool update_meta_store_table(const Glib::ustring& table_name, const Glib::ustring& schema_name = Glib::ustring());

  /** Update the meta store information for the table names.
   *
   * This can speed up the update of the meta store if you only need the list of table names.
   *
   * @param schema_name Name of the schema whose tables to update, or "" to
   * update all tables. For example, for postgresql this function takes a
   * considerable amount of time when doing this. If you don't need
   * information about internal postgresql tables, then you can speed up the
   * process by only updating the tables for the "public" schema.
   * Unfortunately, schema names are not common between different database
   * systems.
   * @return <tt>true</tt> if no error occurred.
   */
  bool update_meta_store_table_names(const Glib::ustring& schema_name = Glib::ustring());

  /** Update the meta store information for the data types.
   *
   * This can speed up the update of the meta store if you only need the data types.
   *
   * @return <tt>true</tt> if no error occurred.
   */
  bool update_meta_store_data_types();

  
  /** Ask the database accessed through the @a cnc connection to prepare the usage of @a stmt. This is only useful
   * if @a stmt will be used more than once (however some database providers may always prepare statements 
   * before executing them).
   * 
   * This function is also useful to make sure @a stmt is fully understood by the database before actually executing it.
   * 
   * Note however that it is also possible that statement_prepare() fails when
   * statement_execute() does not fail (this will usually be the case with statements such as
   * <![CDATA["SELECT * FROM ##tablename::string"]]> because database usually don't allow variables to be used in place of a 
   * table name).
   * 
   * @param stmt A Gda::Statement object.
   * @return <tt>true</tt> if no error occurred.
   */
  bool statement_prepare(const Glib::RefPtr<const Statement>& stmt);


  /** see #gda_connection_get_meta_store_data
   * 
   * @param meta_type Describes which data to get.
   * @param  A place to store errors, or <tt>0</tt>.
   * @param filters A List of Gda::Holder objects.
   * @return A Gda::DataModel containing the data required. The caller is responsible
   * for freeing the returned model using Glib::object_unref().
   */
  Glib::RefPtr<DataModel> get_meta_store_data(ConnectionMetaType meta_type, const std::vector< Glib::RefPtr<Holder> >& filters);
  

  Glib::RefPtr<DataModel> get_meta_store_data(ConnectionMetaType meta_type);

  
  /** Get or initializes the Gda::MetaStore associated to @a cnc
   * 
   * @return A Gda::MetaStore object.
   */
  Glib::RefPtr<MetaStore> get_meta_store();
  
  /** Get or initializes the Gda::MetaStore associated to @a cnc
   * 
   * @return A Gda::MetaStore object.
   */
  Glib::RefPtr<const MetaStore> get_meta_store() const;

   
  /** Executes all the statements contained in @a batch (in the order in which they were added to @a batch), and
   * returns a list of Object objects, at most one Object for each statement; see statement_execute()
   * for details about the returned objects.
   * 
   * If one of the statement fails, then none of the subsequent statement will be executed, and the method returns
   * the list of Object created by the correct execution of the previous statements. If a transaction is required,
   * then it should be started before calling this method.
   * 
   * @param batch A Gda::Batch object which contains all the statements to execute.
   * @param params A Gda::Set object (which can be obtained using Gda::Batch::get_parameters()), or <tt>0</tt>.
   * @param model_usage Specifies how the returned data model(s) will be used, as a Gda::StatementModelUsage enum.
   * @return A new list of Object objects.
   */
  std::vector< Glib::RefPtr<Glib::Object> > batch_execute(const Glib::RefPtr<Batch>& batch, const Glib::RefPtr<const Set>& params, StatementModelUsage model_usage);

  
  /** Creates a new Gda::ServerOperation object which can be modified in order 
   * to perform the type type of action. It is a wrapper around the Gda::ServerProvider::create_operation()
   * method.
   * 
   * @param type The type of operation requested.
   * @param options An optional list of parameters.
   * @return A new Gda::ServerOperation object, or <tt>0</tt> in the connection's provider does not support the @a type type
   * of operation or if an error occurred.
   */
  Glib::RefPtr<ServerOperation> create_operation(ServerOperationType type, const Glib::RefPtr<const Set>& options);
  
  /** Performs the operation described by @a op (which should have been created using
   * create_operation()). It is a wrapper around the Gda::ServerProvider::perform_operation()
   * method.
   * 
   * @param op A Gda::ServerOperation object.
   * @return <tt>true</tt> if no error occurred.
   */
  bool perform_operation(const Glib::RefPtr<ServerOperation>& op);

  
  /** Gets a pointer to the Gda::ServerProvider object used to access the database
   * 
   * @return The Gda::ServerProvider (NEVER <tt>0</tt>).
   */
  Glib::RefPtr<ServerProvider> get_provider();
  
  /** Gets a pointer to the Gda::ServerProvider object used to access the database
   * 
   * @return The Gda::ServerProvider (NEVER <tt>0</tt>).
   */
  Glib::RefPtr<const ServerProvider> get_provider() const;

  
  /** Use this method to get a correctly quoted (if necessary) SQL identifier which can be used
   * in SQL statements, from @a id. If @a id is already correctly quoted for @a cnc, then a copy of @a id
   * may be returned.
   * 
   * This method may add double quotes (or other characters) around @a id:
   * - if @a id is a reserved SQL keyword (such as SELECT, INSERT, ...)
   * - if @a id contains non allowed characters such as spaces, or if it starts with a digit
   * - in any other event as necessary for @a cnc, depending on the the options passed when opening the @a cnc
   * connection, and specifically the 
   * GDA_CONNECTION_OPTIONS_SQL_IDENTIFIERS_CASE_SENSITIVE option.
   * 
   * One can safely pass an already quoted @a id to this method, either with quoting characters allowed by @a cnc or using the
   * double quote (") character.
   * 
   * @newin{4,0,3}
   * 
   * @param id An SQL identifier.
   * @return A new string, to free with Glib::free() once not needed anymore.
   */
  Glib::ustring quote_sql_identifier(const Glib::ustring& id) const;

  
  /** Renders @a stmt as an SQL statement, adapted to the SQL dialect used by @a cnc
   * 
   * @param stmt A Gda::Statement object.
   * @param params A Gda::Set object (which can be obtained using Gda::Statement::get_parameters()), or <tt>0</tt>.
   * @param flags SQL rendering flags, as Gda::StatementSqlFlag OR'ed values.
   * @param params_used A place to store the list of individual Gda::Holder objects within @a params which have been used.
   * @return A new string, or <tt>0</tt> if an error occurred.
   */


  //TODO: What errors does this really throw? Document that in libgda.
  //TODO: Add an overload without the params_used.
  /** Renders a Statement as a SQL statement string, adapted to the SQL dialect used by the connection.
   *
   * @param stmt A Statement object.
   * @param A Set object (which can be obtained using Statement::get_parameters()).
   * @param flags SQL rendering flags, as StatementSqlFlag OR'ed values
   * @param params_used A place to store the list of individual Holder objects within @a params which have been used.
   * @throws ConnectionError
   */
  Glib::ustring statement_to_sql(const Glib::RefPtr<const Statement>& stmt, const Glib::RefPtr<const Set>& params, StatementSqlFlag flags, std::vector< Glib::RefPtr<Holder> >& params_used) const;

  /** Renders a Statement as a SQL statement string, adapted to the SQL dialect used by the connection.
   *
   * @param stmt A Statement object.
   * @param A Set object (which can be obtained using Statement::get_parameters()).
   * @param flags SQL rendering flags, as StatementSqlFlag OR'ed values
   * @throws ConnectionError
   */
  Glib::ustring statement_to_sql(const Glib::RefPtr<const Statement>& stmt, const Glib::RefPtr<const Set>& params, StatementSqlFlag flags = STATEMENT_SQL_PARAMS_AS_VALUES) const;
  
  /** Renders a Statement as a SQL statement string, adapted to the SQL dialect used by the connection.
   *
   * @param stmt A Statement object..
   * @param flags SQL rendering flags, as StatementSqlFlag OR'ed values
   * @throws ConnectionError
   */
  Glib::ustring statement_to_sql(const Glib::RefPtr<const Statement>& stmt, StatementSqlFlag flags = STATEMENT_SQL_PARAMS_AS_VALUES) const;


  /**
   * @par Slot Prototype:
   * <tt>void on_my_%error(const Glib::RefPtr<ConnectionEvent>& error)</tt>
   *
   */

  Glib::SignalProxy1< void,const Glib::RefPtr<ConnectionEvent>& > signal_error();


  /**
   * @par Slot Prototype:
   * <tt>void on_my_%conn_opened()</tt>
   *
   */

  Glib::SignalProxy0< void > signal_conn_opened();

  
  /**
   * @par Slot Prototype:
   * <tt>void on_my_%conn_to_close()</tt>
   *
   */

  Glib::SignalProxy0< void > signal_conn_to_close();

  
  /**
   * @par Slot Prototype:
   * <tt>void on_my_%conn_closed()</tt>
   *
   */

  Glib::SignalProxy0< void > signal_conn_closed();

  
  /**
   * @par Slot Prototype:
   * <tt>void on_my_%dsn_changed()</tt>
   *
   */

  Glib::SignalProxy0< void > signal_dsn_changed();

  
  /**
   * @par Slot Prototype:
   * <tt>void on_my_%transaction_status_changed()</tt>
   *
   */

  Glib::SignalProxy0< void > signal_transaction_status_changed();


  /** Provider to use.
   *
   * @return A PropertyProxy that allows you to get or set the value of the property,
   * or receive notification when the value of the property changes.
   */
  Glib::PropertyProxy< Glib::RefPtr<ServerProvider> > property_provider() ;

/** Provider to use.
   *
   * @return A PropertyProxy_ReadOnly that allows you to get the value of the property,
   * or receive notification when the value of the property changes.
   */
  Glib::PropertyProxy_ReadOnly< Glib::RefPtr<ServerProvider> > property_provider() const;

  /** Authentication string to use.
   *
   * @return A PropertyProxy that allows you to get or set the value of the property,
   * or receive notification when the value of the property changes.
   */
  Glib::PropertyProxy< Glib::ustring > property_auth_string() ;

/** Authentication string to use.
   *
   * @return A PropertyProxy_ReadOnly that allows you to get the value of the property,
   * or receive notification when the value of the property changes.
   */
  Glib::PropertyProxy_ReadOnly< Glib::ustring > property_auth_string() const;

  /** Connection string to use.
   *
   * @return A PropertyProxy that allows you to get or set the value of the property,
   * or receive notification when the value of the property changes.
   */
  Glib::PropertyProxy< Glib::ustring > property_cnc_string() ;

/** Connection string to use.
   *
   * @return A PropertyProxy_ReadOnly that allows you to get the value of the property,
   * or receive notification when the value of the property changes.
   */
  Glib::PropertyProxy_ReadOnly< Glib::ustring > property_cnc_string() const;

  /** DSN to use.
   *
   * @return A PropertyProxy that allows you to get or set the value of the property,
   * or receive notification when the value of the property changes.
   */
  Glib::PropertyProxy< Glib::ustring > property_dsn() ;

/** DSN to use.
   *
   * @return A PropertyProxy_ReadOnly that allows you to get the value of the property,
   * or receive notification when the value of the property changes.
   */
  Glib::PropertyProxy_ReadOnly< Glib::ustring > property_dsn() const;

  /** GdaMetaStore used by the connection.
   *
   * @return A PropertyProxy that allows you to get or set the value of the property,
   * or receive notification when the value of the property changes.
   */
  Glib::PropertyProxy< Glib::RefPtr<MetaStore> > property_meta_store() ;

/** GdaMetaStore used by the connection.
   *
   * @return A PropertyProxy_ReadOnly that allows you to get the value of the property,
   * or receive notification when the value of the property changes.
   */
  Glib::PropertyProxy_ReadOnly< Glib::RefPtr<MetaStore> > property_meta_store() const;

  /** Options.
   *
   * @return A PropertyProxy that allows you to get or set the value of the property,
   * or receive notification when the value of the property changes.
   */
  Glib::PropertyProxy< ConnectionOptions > property_options() ;

/** Options.
   *
   * @return A PropertyProxy_ReadOnly that allows you to get the value of the property,
   * or receive notification when the value of the property changes.
   */
  Glib::PropertyProxy_ReadOnly< ConnectionOptions > property_options() const;

  /** Tells if the connection acts as a thread wrapper around another connection, making it completely thread safe.
   *
   * @return A PropertyProxy_ReadOnly that allows you to get the value of the property,
   * or receive notification when the value of the property changes.
   */
  Glib::PropertyProxy_ReadOnly< bool > property_is_wrapper() const;


  /** Make the connection set up a monitoring function in the mainloop to monitor the wrapped connection.
   *
   * @return A PropertyProxy that allows you to get or set the value of the property,
   * or receive notification when the value of the property changes.
   */
  Glib::PropertyProxy< bool > property_monitor_wrapped_in_mainloop() ;

/** Make the connection set up a monitoring function in the mainloop to monitor the wrapped connection.
   *
   * @return A PropertyProxy_ReadOnly that allows you to get the value of the property,
   * or receive notification when the value of the property changes.
   */
  Glib::PropertyProxy_ReadOnly< bool > property_monitor_wrapped_in_mainloop() const;

  //We ignore the thread-owner property because it is strange and should only be used (well, modified) by provider implementations.
  /** 
   *
   * @return A PropertyProxy that allows you to get or set the value of the property,
   * or receive notification when the value of the property changes.
   */
  Glib::PropertyProxy< int > property_events_history_size() ;

/** 
   *
   * @return A PropertyProxy_ReadOnly that allows you to get the value of the property,
   * or receive notification when the value of the property changes.
   */
  Glib::PropertyProxy_ReadOnly< int > property_events_history_size() const;


public:

public:
  //C++ methods used to invoke GTK+ virtual functions:

protected:
  //GTK+ Virtual Functions (override these to change behaviour):

  //Default Signal Handlers::
  /// This is a default handler for the signal signal_error().
  virtual void on_error(const Glib::RefPtr<ConnectionEvent>& error);
  /// This is a default handler for the signal signal_conn_opened().
  virtual void on_conn_opened();
  /// This is a default handler for the signal signal_conn_to_close().
  virtual void on_conn_to_close();
  /// This is a default handler for the signal signal_conn_closed().
  virtual void on_conn_closed();
  /// This is a default handler for the signal signal_dsn_changed().
  virtual void on_dsn_changed();
  /// This is a default handler for the signal signal_transaction_status_changed().
  virtual void on_transaction_status_changed();


};

} // namespace Gda
} // namespace Gnome


namespace Glib
{
  /** A Glib::wrap() method for this object.
   * 
   * @param object The C instance.
   * @param take_copy False if the result should take ownership of the C instance. True if it should take a new copy or ref.
   * @result A C++ instance that wraps this C instance.
   *
   * @relates Gnome::Gda::Connection
   */
  Glib::RefPtr<Gnome::Gda::Connection> wrap(GdaConnection* object, bool take_copy = false);
}


#endif /* _LIBGDAMM_CONNECTION_H */

