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


#include <glibmm.h>

/* $Id: dict.hg,v 1.2 2006/11/30 06:58:55 murrayc Exp $ */
// -*- C++ -*- // this is for the .hg, I realize gensig puts one in

/* error.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 Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library 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/object.h>
#include <libgdamm/dictaggregate.h>
#include <libgdamm/dictdatabase.h>
#include <libgdamm/dicttype.h>
#include <libgdamm/datahandler.h>


#ifndef DOXYGEN_SHOULD_SKIP_THIS
typedef struct _GdaDict GdaDict;
typedef struct _GdaDictClass GdaDictClass;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


namespace Gnome
{

namespace Gda
{ class Dict_Class; } // namespace Gda

} // namespace Gnome
namespace Gnome
{

namespace Gda
{

class Object;

class Connection;

class DictError : public Glib::Error
{
public:
  enum Code
  {
    DICT_META_DATA_UPDATE_ERROR,
    DICT_META_DATA_UPDATE_USER_STOPPED,
    DICT_LOAD_FILE_NOT_EXIST_ERROR,
    DICT_FILE_LOAD_ERROR,
    DICT_FILE_SAVE_ERROR,
    DICT_DATATYPE_ERROR,
    DICT_FUNCTIONS_ERROR,
    DICT_AGGREGATES_ERROR
  };

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

#ifndef DOXYGEN_SHOULD_SKIP_THIS
private:

#ifdef GLIBMM_EXCEPTIONS_ENABLED
  static void throw_func(GError* gobject);
#else
  //When not using exceptions, we just pass the Exception object around without throwing it:
  static std::auto_ptr<Glib::Error> throw_func(GError* gobject);
#endif //GLIBMM_EXCEPTIONS_ENABLED

  friend void wrap_init(); // uses throw_func()
#endif
};

} // namespace Gda

} // namespace Gnome

#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

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

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


namespace Gnome
{

namespace Gda
{


/** defgroup Dictionaries Dictionaries
 */

/** This object is a "proxy repository" for objects in a database.
 * This is a proxy repository for
 * - object existing within a database such as data types (see the Gda::DictType object), functions (see the Gda::DictFunction object), aggregates (see the Gda::DictAggregate object), and the database structure (through the Gda::DictDatabase and associated object)
 * - pre-defined queries as Gda::Query objects
 * - graphs as Gda::Graph objects
 *
 * Each Dict object can be saved to an XML file and loaded back in an efficient way.
 * Any Dict object can be assigned a Gda::Connection object which tells it how to use a real connection to a data source.
 *
 * The Dict object is responsible for the lifetime management of all the objects it handles. See the Gda::Object class for more information. 
 *
 * @ingroup Dictionaries
 */

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

public:
  typedef Dict CppObjectType;
  typedef Dict_Class CppClassType;
  typedef GdaDict BaseObjectType;
  typedef GdaDictClass BaseClassType;

private:  friend class Dict_Class;
  static CppClassType dict_class_;

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

protected:
  explicit Dict(const Glib::ConstructParams& construct_params);
  explicit Dict(GdaDict* castitem);

#endif /* DOXYGEN_SHOULD_SKIP_THIS */

public:
  virtual ~Dict();

#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.
  GdaDict*       gobj()       { return reinterpret_cast<GdaDict*>(gobject_); }

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

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

private:

  
protected:

 Dict();

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


  /** Sets the associated connection to @a dict. This connection is then used when the dictionary
   * synchronises itself, and when manipulating data (the get_handler() method).
   * @param cnc A Gda::Connection object.
   */
  void set_connection(const Glib::RefPtr<Connection>& cnc);
  
  /** Fetch a pointer to the GdaConnection used by the GdaDict object.
   * @return A pointer to the GdaConnection, if one has been assigned to @a dict.
   */
  Glib::RefPtr<Connection> get_connection();
  
  /** Fetch a pointer to the GdaConnection used by the GdaDict object.
   * @return A pointer to the GdaConnection, if one has been assigned to @a dict.
   */
  Glib::RefPtr<const Connection> get_connection() const;

  
  /** Internal function, not to be used directly.
   */
  void declare_object_string_id_change(const Glib::RefPtr<Gda::Object>& obj, const Glib::ustring& oldid);
  
  /** Fetch a pointer to the Gda::Object which has the @a strid string ID.
   * @param strid A string.
   * @return The corresponding Gda::Object, or <tt>0</tt> if none found.
   */
  Glib::RefPtr<Gda::Object> get_object_by_string_id(const Glib::ustring& strid);
  
  /** Fetch a pointer to the Gda::Object which has the @a strid string ID.
   * @param strid A string.
   * @return The corresponding Gda::Object, or <tt>0</tt> if none found.
   */
  Glib::RefPtr<const Gda::Object> get_object_by_string_id(const Glib::ustring& strid) const;

  
  /** Updates the list of data types, functions, tables, etc from the database,
   * which means that the @a dict object uses an opened connection to the DBMS.
   * Use set_connection() to set a Gda::Connection to @a dict.
   * @param limit_to_type Limit the DBMS update to this type, or 0 for no limit.
   * @param limit_obj_name Limit the DBMS update to objects of this name, or <tt>0</tt> for no limit.
   * @return <tt>true</tt> if no error.
   */
#ifdef GLIBMM_EXCEPTIONS_ENABLED
  bool update_dbms_meta_data(GType limit_to_type, const Glib::ustring& limit_obj_name);
#else
  bool update_dbms_meta_data(GType limit_to_type, const Glib::ustring& limit_obj_name, std::auto_ptr<Glib::Error>& error);
#endif //GLIBMM_EXCEPTIONS_ENABLED


  /** Updates the list of data types, functions, tables, etc from the database, 
   * which means that the dict object uses an opened connection to the DBMS. 
   * Use set_connection() to set a Gda::Connection for the Dict.
   *
   * @param limit_to_type Limit the DBMS update to this type, or 0 for no limit.
   * @result True if there was no error.
   */
  #ifdef GLIBMM_EXCEPTIONS_ENABLED
  bool update_dbms_meta_data(GType limit_to_type);
  #else
  bool update_dbms_meta_data(GType limit_to_type, std::auto_ptr<Glib::Error>& error);
  #endif //GLIBMM_EXCEPTIONS_ENABLED
  
  /** Updates the list of data types, functions, tables, etc from the database, 
   * which means that the dict object uses an opened connection to the DBMS. 
   * Use set_connection() to set a Gda::Connection for the Dict.
   *
   * @result True if there was no error.
   */
  #ifdef GLIBMM_EXCEPTIONS_ENABLED
  bool update_dbms_meta_data();
  #else
  bool update_dbms_meta_data(std::auto_ptr<Glib::Error>& error);
  #endif //GLIBMM_EXCEPTIONS_ENABLED

  
  /** When the dictionary updates its internal lists of DBMS objects, a call to this function will 
   * stop that update process. It has no effect when the dictionary is not updating its DBMS data.
   */
  void stop_update_dbms_meta_data();

//TODO: What is datasource? is it UTF-8?
  
  /** Get the prefered filename which represents the data dictionary associated to the @a datasource data source.
   * Using the returned value in conjunction with load_xml_file() and save_xml_file() has
   * the advantage of letting the library handle file naming onventions.
   * 
   * if @a datasource is <tt>0</tt>, and a Gda::Connection object has been assigned to @a dict, then the returned
   * string will take into account the data source used by that connection.
   * 
   * The @a app_id argument allows to give an extra identification to the request, when some special features
   * must be saved but not interfere with the default dictionary.
   * @param datasource A data source, or <tt>0</tt>.
   * @param app_id An extra identification, or <tt>0</tt>.
   * @return A new string.
   */
#ifdef GLIBMM_EXCEPTIONS_ENABLED
  std::string compute_xml_filename(const Glib::ustring& datasource, const Glib::ustring& app_id);
#else
  std::string compute_xml_filename(const Glib::ustring& datasource, const Glib::ustring& app_id, std::auto_ptr<Glib::Error>& error);
#endif //GLIBMM_EXCEPTIONS_ENABLED

  
  /** Sets the filename @a dict will use when gda_dict_save_xml() and gda_dict_load_xml() are called.
   * @param xmlfile A file name.
   */
  void set_xml_filename(const std::string& xmlfile);
  
  /** Get the filename @a dict will use when gda_dict_save_xml() and gda_dict_load_xml() are called.
   * @return The filename, or <tt>0</tt> if none have been set.
   */
  std::string get_xml_filename() const;
  
  /** Loads an XML file which respects the Libgda DTD, and creates all the necessary
   * objects that are defined within the XML file. During the creation of the other
   * objects, all the normal signals are emitted.
   * 
   * If the GdaDict object already has some contents, then it is first of all
   * destroyed (to return its state as when it was first created).
   * 
   * If an error occurs during loading then the GdaDict object is left as empty
   * as when it is first created.
   * 
   * The file loaded is the one specified using set_xml_filename()
   * @return <tt>true</tt> if loading was successfull and <tt>false</tt> otherwise.
   */
#ifdef GLIBMM_EXCEPTIONS_ENABLED
  bool load();
#else
  bool load(std::auto_ptr<Glib::Error>& error);
#endif //GLIBMM_EXCEPTIONS_ENABLED

  
  /** Saves the contents of a GdaDict object to a file which is specified using the
   * set_xml_filename() method.
   * @return <tt>true</tt> if saving was successfull and <tt>false</tt> otherwise.
   */
#ifdef GLIBMM_EXCEPTIONS_ENABLED
  bool save();
#else
  bool save(std::auto_ptr<Glib::Error>& error);
#endif //GLIBMM_EXCEPTIONS_ENABLED

  
  /** Loads an XML file which respects the Libgda DTD, and creates all the necessary
   * objects that are defined within the XML file. During the creation of the other
   * objects, all the normal signals are emitted.
   * 
   * If the GdaDict object already has some contents, then it is first of all
   * destroyed (to return its state as when it was first created).
   * 
   * If an error occurs during loading then the GdaDict object is left as empty
   * as when it is first created.
   * @param xmlfile The name of the file to which the XML will be written to.
   * @return <tt>true</tt> if loading was successfull and <tt>false</tt> otherwise.
   */
#ifdef GLIBMM_EXCEPTIONS_ENABLED
  bool load_xml_file(const std::string& xmlfile);
#else
  bool load_xml_file(const std::string& xmlfile, std::auto_ptr<Glib::Error>& error);
#endif //GLIBMM_EXCEPTIONS_ENABLED

  
  /** Saves the contents of a GdaDict object to a file which is given as argument.
   * @param xmlfile The name of the file to which the XML will be written to.
   * @return <tt>true</tt> if saving was successfull and <tt>false</tt> otherwise.
   */
#ifdef GLIBMM_EXCEPTIONS_ENABLED
  bool save_xml_file(const std::string& xmlfile);
#else
  bool save_xml_file(const std::string& xmlfile, std::auto_ptr<Glib::Error>& error);
#endif //GLIBMM_EXCEPTIONS_ENABLED


  /** Obtain a pointer to a Gda::DataHandler which can convert Value values of type @a for_type.
   * 
   * Unlike the get_default_handler() method, this method asks the provider (for
   * the connection assigned to @a dict using set_connection()) if there is any.
   * 
   * It fallbacks to the same data handler as
   * get_default_handler() if no connection has been assigned, or if the assigned'd provider
   * offers no data handler for that type.
   * 
   * The returned pointer is <tt>0</tt> if there is no data handler available for the @a for_type type.
   * @param for_type A Type type.
   * @return A Gda::DataHandler.
   */
  Glib::RefPtr<DataHandler> get_handler(GType for_type);
  
  /** Obtain a pointer to a Gda::DataHandler which can convert Value values of type @a for_type.
   * 
   * Unlike the get_default_handler() method, this method asks the provider (for
   * the connection assigned to @a dict using set_connection()) if there is any.
   * 
   * It fallbacks to the same data handler as
   * get_default_handler() if no connection has been assigned, or if the assigned'd provider
   * offers no data handler for that type.
   * 
   * The returned pointer is <tt>0</tt> if there is no data handler available for the @a for_type type.
   * @param for_type A Type type.
   * @return A Gda::DataHandler.
   */
  Glib::RefPtr<const DataHandler> get_handler(GType for_type) const;
  
  /** Obtain a pointer to a Gda::DataHandler which can manage
   * Value values of type @a for_type
   * 
   * The returned pointer is <tt>0</tt> if there is no default data handler available for the @a for_type data type
   * @param for_type A Type type.
   * @return A Gda::DataHandler.
   */
  Glib::RefPtr<DataHandler> get_default_handler(GType for_type);
  
  /** Obtain a pointer to a Gda::DataHandler which can manage
   * Value values of type @a for_type
   * 
   * The returned pointer is <tt>0</tt> if there is no default data handler available for the @a for_type data type
   * @param for_type A Type type.
   * @return A Gda::DataHandler.
   */
  Glib::RefPtr<const DataHandler> get_default_handler(GType for_type) const;

  //Note that these are described in libgda_others.defs, because the C functions are actually macros:
   

  Glib::SListHandle<Glib::RefPtr<DictType> > get_dict_types();
  
  Glib::SListHandle<Glib::RefPtr<const DictType> > get_dict_types() const;

  
  Glib::RefPtr<DictType> get_dict_type_by_name(const Glib::ustring& type_name);
  
  Glib::RefPtr<const DictType> get_dict_type_by_name(const Glib::ustring& type_name) const;

  
  Glib::RefPtr<DictType> get_dict_type_by_xml_id(const Glib::ustring& xml_id);
  
  Glib::RefPtr<const DictType> get_dict_type_by_xml_id(const Glib::ustring& xml_id) const;

/* GdaDictFunction manipulations */
  //_WRAP_METHOD(GSList* get_functions() const, gda_dict_get_functions)
  //_WRAP_METHOD(GSList* get_functions_by_name(const Glib::ustring& funcname), gda_dict_get_functions_by_name)
  //_WRAP_METHOD(GdaDictFunction* get_function_by_name_arg(const Glib::ustring& funcname, const GSList* argtypes), gda_dict_get_function_by_name_arg)
  //_WRAP_METHOD(GdaDictFunction* get_function_by_xml_id(const Glib::ustring& xml_id), gda_dict_get_function_by_xml_id)
  //_WRAP_METHOD(GdaDictFunction* get_function_by_dbms_id(const Glib::ustring& dbms_id), gda_dict_get_function_by_dbms_id)

  //TODO: Use a ListHandle or similar?
  GSList* get_aggregates() const;

  GSList* get_aggregates_by_name(const Glib::ustring& aggname);

  //TODO: Use a C++ type, or at least a reference instead of a pointer:
  //TODO: Make sure that these take a reference.
  Glib::RefPtr<DictAggregate> get_aggregate_by_name_arg(const Glib::ustring& aggname, GdaDictType *argtype);
  Glib::RefPtr<DictAggregate> get_aggregate_by_xml_id(const Glib::ustring& xml_id);
  Glib::RefPtr<DictAggregate> get_aggregate_by_dbms_id(const Glib::ustring& dbms_id);

/* GdaQuery manipulations */
  //_WRAP_METHOD(void declare_query(const Glib::RefPtr<Query>& query), gda_dict_declare_query)
  //_WRAP_METHOD(void assume_query (const Glib::RefPtr<Query>& query), gda_dict_assume_query)
  //_WRAP_METHOD(void unassume_query(const Glib::RefPtr<Query>& query), gda_dict_unassume_query)
  //_WRAP_METHOD(GSList* get_queries  () const, gda_dict_get_queries)
  //_WRAP_METHOD(Glib::RefPtr<Query> get_query_by_xml_id(const Glib::ustring& xml_id), gda_dict_get_query_by_xml_id, refreturn)
  //_WRAP_METHOD(Glib::RefPtr<const Query> get_query_by_xml_id(const Glib::ustring& xml_id), gda_dict_get_query_by_xml_id, constversion)

/* GdaGraph manipulations */
  //_WRAP_METHOD(void declare_graph(GdaGraph *graph), gda_dict_declare_graph)
  //_WRAP_METHOD(void assume_graph(GdaGraph *graph), gda_dict_assume_graph)
  //_WRAP_METHOD(void unassume_graph(GdaGraph *graph), gda_dict_unassume_graph)
  //_WRAP_METHOD(GSList* get_graphs (GraphType type_of_graphs), gda_dict_get_graphs)
  //_WRAP_METHOD(GdaGraph* get_graph_by_xml_id(const Glib::ustring& xml_id), gda_dict_get_graph_by_xml_id)
  //_WRAP_METHOD(GdaGraph* get_graph_for_object(GObject *obj), gda_dict_get_graph_for_object)

  
  /** Fetch a pointer to the GdaDictDatabase used by the GdaDict object.
   * @return A pointer to the GdaDictDatabase.
   */
  Glib::RefPtr<DictDatabase> get_database();
  
  /** Fetch a pointer to the GdaDictDatabase used by the GdaDict object.
   * @return A pointer to the GdaDictDatabase.
   */
  Glib::RefPtr<const DictDatabase> get_database() const;

  //_WRAP_METHOD(GSList* get_entities_fk_constraints(GdaEntity *entity1, GdaEntity *entity2, bool entity1_has_fk), gda_dict_get_entities_fk_constraints)


public:

public:
  //C++ methods used to invoke GTK+ virtual functions:
#ifdef GLIBMM_VFUNCS_ENABLED
#endif //GLIBMM_VFUNCS_ENABLED

protected:
  //GTK+ Virtual Functions (override these to change behaviour):
#ifdef GLIBMM_VFUNCS_ENABLED
#endif //GLIBMM_VFUNCS_ENABLED

  //Default Signal Handlers::
#ifdef GLIBMM_DEFAULT_SIGNAL_HANDLERS_ENABLED
#endif //GLIBMM_DEFAULT_SIGNAL_HANDLERS_ENABLED


};

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


#endif /* _LIBGDAMM_DICT_H */

