// -*- c++ -*-
// Generated by gtkmmproc -- DO NOT MODIFY!
#ifndef _LIBGDAMM_SERVERPROVIDER_H
#define _LIBGDAMM_SERVERPROVIDER_H


#include <glibmm.h>

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

/* serverprovider.h
 *
 * Copyright 2001      Free Software Foundation
 *
 * 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/statement.h>
//#include <libgdamm/connection.h>
#include <libgdamm/serveroperation.h>
#include <libgdamm/datahandler.h>


#ifndef DOXYGEN_SHOULD_SKIP_THIS
typedef struct _GdaServerProvider GdaServerProvider;
typedef struct _GdaServerProviderClass GdaServerProviderClass;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


namespace Gnome
{

namespace Gda
{ class ServerProvider_Class; } // namespace Gda

} // namespace Gnome
namespace Gnome
{

namespace Gda
{

class ServerProviderError : public Glib::Error
{
public:
  enum Code
  {
    SERVER_PROVIDER_METHOD_NON_IMPLEMENTED_ERROR,
    SERVER_PROVIDER_PREPARE_STMT_ERROR,
    SERVER_PROVIDER_EMPTY_STMT_ERROR,
    SERVER_PROVIDER_MISSING_PARAM_ERROR,
    SERVER_PROVIDER_STATEMENT_EXEC_ERROR,
    SERVER_PROVIDER_OPERATION_ERROR,
    SERVER_PROVIDER_INTERNAL_ERROR,
    SERVER_PROVIDER_BUSY_ERROR,
    SERVER_PROVIDER_NON_SUPPORTED_ERROR,
    SERVER_PROVIDER_SERVER_VERSION_ERROR,
    SERVER_PROVIDER_DATA_ERROR
  };

  ServerProviderError(Code error_code, const Glib::ustring& error_message);
  explicit ServerProviderError(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::ServerProviderError::Code> : public Glib::Value_Enum<Gnome::Gda::ServerProviderError::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
 */
enum ConnectionFeature
{
  CONNECTION_FEATURE_AGGREGATES,
  CONNECTION_FEATURE_BLOBS,
  CONNECTION_FEATURE_INDEXES,
  CONNECTION_FEATURE_INHERITANCE,
  CONNECTION_FEATURE_NAMESPACES,
  CONNECTION_FEATURE_PROCEDURES,
  CONNECTION_FEATURE_SEQUENCES,
  CONNECTION_FEATURE_SQL,
  CONNECTION_FEATURE_TRANSACTIONS,
  CONNECTION_FEATURE_SAVEPOINTS,
  CONNECTION_FEATURE_SAVEPOINTS_REMOVE,
  CONNECTION_FEATURE_TRIGGERS,
  CONNECTION_FEATURE_UPDATABLE_CURSOR,
  CONNECTION_FEATURE_USERS,
  CONNECTION_FEATURE_VIEWS,
  CONNECTION_FEATURE_XA_TRANSACTIONS,
  CONNECTION_FEATURE_MULTI_THREADING,
  CONNECTION_FEATURE_LAST
};

} // namespace Gda

} // namespace Gnome


#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

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

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


namespace Gnome
{

namespace Gda
{


class Connection;
class SqlParser;

/* TODO: Is this appropriate. Investigate how it is used. */
typedef GdaServerProviderInfo ServerProviderInfo;


/** Base class for all the DBMS providers.
  *
  * The ServerProvider class is an abstract class which all the DBMS providers
  * must inherit, and implement its virtual methods.
  *
  * @ingroup Connections
  */


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

public:
  typedef ServerProvider CppObjectType;
  typedef ServerProvider_Class CppClassType;
  typedef GdaServerProvider BaseObjectType;
  typedef GdaServerProviderClass BaseClassType;

private:  friend class ServerProvider_Class;
  static CppClassType serverprovider_class_;

private:
  // noncopyable
  ServerProvider(const ServerProvider&);
  ServerProvider& operator=(const ServerProvider&);

protected:
  explicit ServerProvider(const Glib::ConstructParams& construct_params);
  explicit ServerProvider(GdaServerProvider* castitem);

#endif /* DOXYGEN_SHOULD_SKIP_THIS */

public:
  virtual ~ServerProvider();

#ifndef DOXYGEN_SHOULD_SKIP_THIS
  static GType get_type()      G_GNUC_CONST;


  static GType get_base_type() G_GNUC_CONST;
#endif

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

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

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

private:


public:
  
  /** Get the version of the provider.
   * @return A string containing the version identification.
   */
  Glib::ustring get_version() const;

  
  /** Get the version of the database to which the connection is opened.
   * @param cnc A Gda::Connection object.
   * @return A (read only) string, or <tt>0</tt> if an error occurred.
   */
  Glib::ustring get_server_version(const Glib::RefPtr<Connection>& cnc) const;

  //TODO: options may be NULL: Add a method overload.
  
  /** Tells if @a provider supports the @a type of operation on the @a cnc connection, using the
   * (optional) @a options parameters.
   * @param cnc A Gda::Connection object which would be used to perform an action, or <tt>0</tt>.
   * @param type The type of operation requested.
   * @param options A list of named parameters, or <tt>0</tt>.
   * @return <tt>true</tt> if the operation is supported.
   */
  bool supports_operation(const Glib::RefPtr<Connection>& cnc, ServerOperationType type, const Glib::RefPtr<Set>& options) const;

  
  /** Creates a new Gda::ServerOperation object which can be modified in order to perform the @a type type of
   * action. The @a options can contain:
   * <itemizedlist>
   * <listitem>named values which ID is a path in the resulting GdaServerOperation object, to initialize some value</listitem>
   * <listitem>named values which may change the contents of the GdaServerOperation, see this section for more information</listitem>
   * </itemizedlist>
   * @param cnc A Gda::Connection object which will be used to perform an action, or <tt>0</tt>.
   * @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 provider does not support the @a type type of operation or if an error occurred.
   */
  Glib::RefPtr<ServerOperation> create_operation(const Glib::RefPtr<Connection>& cnc, ServerOperationType type, const Glib::RefPtr<Set>& options);
  
  /** Creates a new Gda::ServerOperation object which can be modified in order to perform the @a type type of
   * action. The @a options can contain:
   * &lt;itemizedlist&gt;
   * &lt;listitem&gt;named values which ID is a path in the resulting GdaServerOperation object, to initialize some value&lt;/listitem&gt;
   * &lt;listitem&gt;named values which may change the contents of the GdaServerOperation, see this section for more information&lt;/listitem&gt;
   * &lt;/itemizedlist&gt;
   * @param cnc A Gda::Connection object which will be used to perform an action, or <tt>0</tt>.
   * @param type The type of operation requested.
   * @return A new Gda::ServerOperation object, or <tt>0</tt> in the provider does not support the @a type type
   * of operation or if an error occurred.
   */
#ifdef GLIBMM_EXCEPTIONS_ENABLED
  Glib::RefPtr<ServerOperation> create_operation(const Glib::RefPtr<Connection>& cnc, ServerOperationType type);
#else
  Glib::RefPtr<ServerOperation> create_operation(const Glib::RefPtr<Connection>& cnc, ServerOperationType type, std::auto_ptr<Glib::Error>& error);
#endif //GLIBMM_EXCEPTIONS_ENABLED


  /** Creates an SQL statement (possibly using some specific extensions of the DBMS) corresponding to the
   *  @a op operation. Note that the returned string may actually contain more than one SQL statement.
   * 
   * This function's purpose is mainly informative to get the actual SQL code which would be executed to perform
   * the operation; to actually perform the operation, use perform_operation().
   * @param cnc A Gda::Connection object which will be used to render the action, or <tt>0</tt>.
   * @param op A Gda::ServerOperation object.
   * @return A new string, or <tt>0</tt> if an error occurred or operation cannot be rendered as SQL.
   */
  Glib::ustring render_operation(const Glib::RefPtr<Connection>& cnc, const Glib::RefPtr<ServerOperation>& op);
  
  /** Performs the operation described by @a op. Note that @a op is not destroyed by this method
   * and can be reused.
   * @param cnc A Gda::Connection object which will be used to perform the action, or <tt>0</tt>.
   * @param op A Gda::ServerOperation object.
   * @return <tt>true</tt> if no error occurred.
   */
  bool perform_operation(const Glib::RefPtr<Connection>& cnc, const Glib::RefPtr<ServerOperation>& op);

  
  /** Tests if a feature is supported
   * @param cnc A Gda::Connection object, or <tt>0</tt>.
   * @param feature Gda::ConnectionFeature feature to test.
   * @return <tt>true</tt> if @a feature is supported.
   */
  bool supports_feature(const Glib::RefPtr<Connection>& cnc, ConnectionFeature feature) const;


  /** Produces a fully quoted and escaped string from a GValue
   * @param cnc A Gda::Connection object, or <tt>0</tt>.
   * @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 Glib::RefPtr<Connection>& cnc, const Value& from) const;

  
  /** Escapes @a str for use within an SQL command (to avoid SQL injection attacks). Note that the returned value still needs
   * to be enclosed in single quotes before being used in an SQL statement.
   * @param cnc A Gda::Connection object, or <tt>0</tt>.
   * @param str A string to escape.
   * @return A new string suitable to use in SQL statements.
   */
  Glib::ustring escape_string(const Glib::RefPtr<Connection>& cnc, const Glib::ustring& str) const;
  
  /** Unescapes @a str for use within an SQL command. This is the exact opposite of escape_string().
   * @param cnc A Gda::Connection object, or <tt>0</tt>.
   * @param str A string to escape.
   * @return A new string.
   */
  Glib::ustring unescape_string(const Glib::RefPtr<Connection>& cnc, const Glib::ustring& str) const;

  
  /** Find a Gda::DataHandler object to manipulate data of type @a for_type.
   * @param cnc A Gda::Connection object, or <tt>0</tt>.
   * @param for_type A DBMS type definition.
   * @return A Gda::DataHandler, or <tt>0</tt> if the provider does not know about the @a for_type type.
   */
  Glib::RefPtr<DataHandler> get_data_handler_dbms(const Glib::RefPtr<Connection>& cnc, const Glib::ustring& for_type);
  
  /** Find a Gda::DataHandler object to manipulate data of type @a for_type.
   * @param cnc A Gda::Connection object, or <tt>0</tt>.
   * @param for_type A DBMS type definition.
   * @return A Gda::DataHandler, or <tt>0</tt> if the provider does not know about the @a for_type type.
   */
  Glib::RefPtr<const DataHandler> get_data_handler_dbms(const Glib::RefPtr<Connection>& cnc, const Glib::ustring& for_type) const;

  
  /** Find a Gda::DataHandler object to manipulate data of type @a for_type. The returned object must not be modified.
   * @param cnc A Gda::Connection object, or <tt>0</tt>.
   * @param for_type A Type.
   * @return A Gda::DataHandler, or <tt>0</tt> if the provider does not support the requested @a for_type data type.
   */
  Glib::RefPtr<DataHandler> get_data_handler_g_type(const Glib::RefPtr<Connection>& cnc, GType for_type);
  
  /** Find a Gda::DataHandler object to manipulate data of type @a for_type. The returned object must not be modified.
   * @param cnc A Gda::Connection object, or <tt>0</tt>.
   * @param for_type A Type.
   * @return A Gda::DataHandler, or <tt>0</tt> if the provider does not support the requested @a for_type data type.
   */
  Glib::RefPtr<const DataHandler> get_data_handler_g_type(const Glib::RefPtr<Connection>& cnc, GType for_type) const;

  
  /** Get the name of the most common data type which has @a type type.
   * 
   * The returned value may be <tt>0</tt> either if the provider does not implement that method, or if
   * there is no DBMS data type which could contain data of the @a g_type type (for example <tt>0</tt> may be
   * returned if a DBMS has integers only up to 4 bytes and a G_TYPE_INT64 is requested).
   * @param cnc A Gda::Connection object or <tt>0</tt>.
   * @param type A Type value type.
   * @return The name of the DBMS type, or <tt>0</tt>.
   */
  Glib::ustring get_default_dbms_type(const Glib::RefPtr<Connection>& cnc, GType type) const;

  
  /** Get the name (identifier) of the provider
   * @return A string containing the provider's name.
   */
  Glib::ustring get_name() const;
  
  /** Creates a new Gda::SqlParser object which is adapted to @a provider (and possibly depending on
   *  @a cnc for the actual database version).
   * 
   * If @a prov does not have its own parser, then <tt>0</tt> is returned, and a general SQL parser can be obtained
   * using Gda::SqlParser::new().
   * @param cnc A Gda::Connection, or <tt>0</tt>.
   * @return A new Gda::SqlParser object, or <tt>0</tt>.
   */
  Glib::RefPtr<SqlParser> create_parser(const Glib::RefPtr<Connection>& cnc);
  
  
  /** Use @a provider to create a new Value from a single string representation. 
   * 
   * The @a preferred_type can optionally ask @a provider to return a Value of the requested type 
   * (but if such a value can't be created from @a string, then <tt>0</tt> is returned); 
   * pass G_TYPE_INVALID if any returned type is acceptable.
   * 
   * The returned value is either a new Value or <tt>0</tt> in the following cases:
   * - @a string cannot be converted to @a preferred_type type
   * - the provider does not handle @a preferred_type
   * - the provider could not make a Value from @a string
   * 
   * If @a dbms_type is not <tt>0</tt>, then if will contain a constant string representing
   * the database type used for the conversion if the conversion was successfull, or <tt>0</tt>
   * otherwise.
   * @param cnc A Gda::Connection object, or <tt>0</tt>.
   * @param string The SQL string to convert to a value.
   * @param preferred_type A Type, or G_TYPE_INVALID.
   * @param dbms_type Place to get the actual database type used if the conversion succeeded, or <tt>0</tt>.
   * @return A new Value, or <tt>0</tt>.
   */


  //TODO: ValueBase can't be used as a return type.
  Value string_to_value(const Glib::RefPtr<Connection>& cnc, const Glib::ustring& string, GType prefered_type, Glib::ustring& dbms_type) const;

  
  /** Provides the implementation when the default Libgda's data handlers must be used
   * @param cnc A Gda::Connection object, or <tt>0</tt>.
   * @param type A Type.
   * @param dbms_type A DBMS type definition.
   * @return A Gda::DataHandler, or <tt>0</tt>.
   */
  Glib::RefPtr<DataHandler> get_data_handler_default(const Glib::RefPtr<Connection>& cnc, GType type, const Glib::ustring& dbms_type);

  //TODO: Should this be const?
  
  /** Finds the location of a @a filename. This function should only be used by database provider's
   * implementations
   * @param inst_dir Directory where @a prov is installed.
   * @param filename Name of the file to find.
   * @return The complete path to @a filename, or <tt>0</tt> if not found.
   */
  std::string find_file(const std::string& inst_dir, const std::string& filename);

  
  /** Performs the operation described by @a op, using the SQL from the rendering of the operation
   * @param cnc A Gda::Connection object which will be used to perform an action, or <tt>0</tt>.
   * @param op A Gda::ServerOperation object.
   * @return <tt>true</tt> if no error occurred.
   */
  bool perform_operation_default(const Glib::RefPtr<Connection>& cnc, const Glib::RefPtr<ServerOperation>& op);
    
  // These are in a private header, so ignore them
  

protected:
 //TODO: vfuncs.


public:

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

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

  //Default Signal Handlers::


};

} // 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::ServerProvider
   */
  Glib::RefPtr<Gnome::Gda::ServerProvider> wrap(GdaServerProvider* object, bool take_copy = false);
}


#endif /* _LIBGDAMM_SERVERPROVIDER_H */

