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


#include <glibmm.h>

// -*- C++ -*- // this is for the .hg, I realize gensig puts one in

/* query.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 <glibmm/object.h>
#include <libgdamm/dict.h>
#include <libgdamm/datamodel.h>

#include <libgdamm/xmlstorage.h>
#include <libgdamm/referer.h>
#include <libgdamm/renderer.h>
#include <libgdamm/entity.h>
#include <libgdamm/queryobject.h>

#include <libgdamm/queryfield.h>
#include <libgdamm/querytarget.h>
#include <libgdamm/querycondition.h>
#include <libgdamm/queryjoin.h>


#ifndef DOXYGEN_SHOULD_SKIP_THIS
typedef struct _GdaQuery GdaQuery;
typedef struct _GdaQueryClass GdaQueryClass;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


namespace Gnome
{

namespace Gda
{ class Query_Class; } // namespace Gda

} // namespace Gnome
namespace Gnome
{

namespace Gda
{

/** @addtogroup libgdammEnums Enums and Flags */

/**
 * @ingroup libgdammEnums
 */
enum QueryType
{
  QUERY_TYPE_SELECT,
  QUERY_TYPE_INSERT,
  QUERY_TYPE_UPDATE,
  QUERY_TYPE_DELETE,
  QUERY_TYPE_UNION,
  QUERY_TYPE_INTERSECT,
  QUERY_TYPE_EXCEPT,
  QUERY_TYPE_NON_PARSED_SQL
};

} // namespace Gda

} // namespace Gnome


#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

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

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


namespace Gnome
{

namespace Gda
{

/**
 * @ingroup libgdammEnums
 * @par Bitwise operators:
 * <tt>%QueryFieldState operator|(QueryFieldState, QueryFieldState)</tt><br>
 * <tt>%QueryFieldState operator&(QueryFieldState, QueryFieldState)</tt><br>
 * <tt>%QueryFieldState operator^(QueryFieldState, QueryFieldState)</tt><br>
 * <tt>%QueryFieldState operator~(QueryFieldState)</tt><br>
 * <tt>%QueryFieldState& operator|=(QueryFieldState&, QueryFieldState)</tt><br>
 * <tt>%QueryFieldState& operator&=(QueryFieldState&, QueryFieldState)</tt><br>
 * <tt>%QueryFieldState& operator^=(QueryFieldState&, QueryFieldState)</tt><br>
 */
enum QueryFieldState
{
  ENTITY_FIELD_VISIBLE = 1 << 0,
  ENTITY_FIELD_INVISIBLE = 1 << 1,
  ENTITY_FIELD_ANY = 0x1
};

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

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

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

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

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

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

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

} // namespace Gda

} // namespace Gnome


#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

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

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


namespace Gnome
{

namespace Gda
{

class QueryError : public Glib::Error
{
public:
  enum Code
  {
    QUERY_XML_LOAD_ERROR,
    QUERY_META_DATA_UPDATE,
    QUERY_FIELDS_ERROR,
    QUERY_TARGETS_ERROR,
    QUERY_RENDER_ERROR,
    QUERY_PARSE_ERROR,
    QUERY_SYNTAX_ERROR,
    QUERY_STRUCTURE_ERROR,
    QUERY_SQL_ANALYSE_ERROR,
    QUERY_NO_CNC_ERROR,
    QUERY_CNC_CLOSED_ERROR,
    QUERY_EXEC_ERROR
  };

  QueryError(Code error_code, const Glib::ustring& error_message);
  explicit QueryError(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::QueryError::Code> : public Glib::Value_Enum<Gnome::Gda::QueryError::Code>
{
public:
  static GType value_type() G_GNUC_CONST;
};

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


namespace Gnome
{

namespace Gda
{


/** Represents any kind of DML query.
 *
 * @ingroup Queries
 */

class Query
 : public QueryObject,
   public XmlStorage,
   public Referer,
   public Renderer,
   public Entity
{
  
#ifndef DOXYGEN_SHOULD_SKIP_THIS

public:
  typedef Query CppObjectType;
  typedef Query_Class CppClassType;
  typedef GdaQuery BaseObjectType;
  typedef GdaQueryClass BaseClassType;

private:  friend class Query_Class;
  static CppClassType query_class_;

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

protected:
  explicit Query(const Glib::ConstructParams& construct_params);
  explicit Query(GdaQuery* castitem);

#endif /* DOXYGEN_SHOULD_SKIP_THIS */

public:
  virtual ~Query();

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

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

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

private:


  // These have nothing to do with query
  
  
protected:
  explicit Query(const Glib::RefPtr<Dict>& dict);
  Query(const Glib::RefPtr<Dict>& dict, QueryType type);

public:
  
  static Glib::RefPtr<Query> create(const Glib::RefPtr<Dict>& dict);

  
  static Glib::RefPtr<Query> create(const Glib::RefPtr<Dict>& dict, QueryType type);


  // TODO: How to wrap GHashTable in g*mm? armin.
  

  // Not wrapped because it only calls gda_query_set_sql_text(). However,
  // gda_query_set_sql_text() might throw an exception and if this was a
  // constructor, it would prevent the object from being constructed, but in
  // C a new object is returned. This is why the caller should call
  // gda_query_set_sql_text her/himself.
  

  /** Sets the type of @a query
   * @param type The new type of query.
   */
  void set_query_type(QueryType type);
  
  /** Get the type of a query
   * @return The type of @a query.
   */
  QueryType get_query_type() const;
  
  /** Get the type of a query as a human readable string
   * @return A string for the type of @a query.
   */
  Glib::ustring get_query_type_string() const;
  
  /** Tells if @a query is a SELECTION query (a simple SELECT, UNION, INTERSECT or EXCEPT);
   * @return <tt>true</tt> if @a query is a selection query.
   */
  bool is_select_query() const;
  
  /** Tells if @a query is a INSERT query.
   * @return <tt>true</tt> if @a query is an insertion query.
   */
  bool is_insert_query() const;
  
  /** Tells if @a query is a UPDATE query.
   * @return <tt>true</tt> if @a query is an update query.
   */
  bool is_update_query() const;
  
  /** Tells if @a query is a DELETE query.
   * @return <tt>true</tt> if @a query is an delete query.
   */
  bool is_delete_query() const;
  
  /** Tells if @a query is a modification query (a simple UPDATE, DELETE, INSERT).; pure SQL
   * queries are not handled and will always return <tt>false</tt>.
   * @return <tt>true</tt> if @a query is a modification query.
   */
  bool is_modify_query() const;
  
  /** Tells if @a query is well formed, and if @a context is not <tt>0</tt>, also tells if rendering to
   * SQL can be done without error
   * @param context A Gda::ParameterList obtained using get_parameter_list(), or <tt>0</tt>.
   * @return <tt>false</tt> if @a query is not well formed.
   */
#ifdef GLIBMM_EXCEPTIONS_ENABLED
  bool is_well_formed(const Glib::RefPtr<ParameterList>& context) const;
#else
  bool is_well_formed(const Glib::RefPtr<ParameterList>& context, std::auto_ptr<Glib::Error>& error) const;
#endif //GLIBMM_EXCEPTIONS_ENABLED


  /** Defines @a query's contents from an SQL statement. The SQL text is parsed and the internal query structured
   * is built from that; the query type is also set. If the SQL text cannot be parsed, then the internal structure
   * of the query is emptied and the query type is set to GDA_QUERY_TYPE_NON_PARSED_SQL.
   * 
   * To be parsed successfully, the expected SQL must respect the SQL standard; some extensions have been
   * added to be able to define variables within the SQL statement. See the introduction to the Gda::Query
   * for more information.
   * @param sql The SQL statement.
   */
#ifdef GLIBMM_EXCEPTIONS_ENABLED
  void set_sql_text(const Glib::ustring& sql);
#else
  void set_sql_text(const Glib::ustring& sql, std::auto_ptr<Glib::Error>& error);
#endif //GLIBMM_EXCEPTIONS_ENABLED

  
  /** Obtain a new string representing the SQL version of the query.
   * 
   * WARNING: the returned SQL statement may contain some extensions which allow for the definition of
   * variables (see the introduction to the Gda::Query for more information). As such the returned SQL cannot
   * be executed as it may provoque errors. To get an executable statement, use the Gda::Renderer interface's
   * methods.
   * @return The new string.
   */
  Glib::ustring get_sql_text() const;

   
  /** Get a list of parameters which the query accepts.
   * @return A list of Gda::Parameter objects (the list and objects must be freed by the caller).
   */
  Glib::SListHandle<Glib::RefPtr<Parameter> > get_parameters();

  
  /** Like the get_parameters() method, get a list of parameters which the query accepts,
   * except that the parameters are stored within a Gda::ParameterList object, and can be used as an argument
   * to the execute() method.
   * @return A new Gda::ParameterList object, or <tt>0</tt> if @a query does not accept any parameter.
   */
  Glib::RefPtr<ParameterList> get_parameter_list();
  
  /** Like the get_parameters() method, get a list of parameters which the query accepts,
   * except that the parameters are stored within a Gda::ParameterList object, and can be used as an argument
   * to the execute() method.
   * @return A new Gda::ParameterList object, or <tt>0</tt> if @a query does not accept any parameter.
   */
  Glib::RefPtr<const ParameterList> get_parameter_list() const;

  
  /** Executes @a query and returns Gda::DataModel if @a query's execution yields to a data set, or a
   * Gda::ParameterList object otherwise, or <tt>0</tt> if an error occurred. You can test the return value
   * using GObject's introscpection features such as GDA_IS_DATA_MODEL() or GDA_IS_PARAMETER_LIST().
   * 
   * For more information about the returned value, see Gda::ServerProvider::execute_command().
   * @param params A Gda::ParameterList object obtained using get_parameter_list().
   * @param iter_model_only_requested Set to <tt>true</tt> if the returned data model will only be accessed using an iterator.
   * @return A Gda::DataModel, a Gda::ParameterList or <tt>0</tt>.
   */
#ifdef GLIBMM_EXCEPTIONS_ENABLED
  Glib::RefPtr<Object> execute(const Glib::RefPtr<ParameterList>& params, bool iter_model_only_requested = false);
#else
  Glib::RefPtr<Object> execute(const Glib::RefPtr<ParameterList>& params, bool iter_model_only_requested, std::auto_ptr<Glib::Error>& error);
#endif //GLIBMM_EXCEPTIONS_ENABLED

  //I don't think that an exectute() function should be const. We can add it later if necessary. murrayc: _WRAP_METHOD(Glib::RefPtr<const Object> execute(const Glib::RefPtr<ParameterList>& params, bool iter_model_only_requested) const, gda_query_execute, errthrow, constversion)
  
  /** Get the parent query of @a query
   * @return The parent query, or <tt>0</tt> if @a query does not have any parent.
   */
  Glib::RefPtr<Query> get_parent_query();
  
  /** Get the parent query of @a query
   * @return The parent query, or <tt>0</tt> if @a query does not have any parent.
   */
  Glib::RefPtr<const Query> get_parent_query() const;

   
  /** Get a list of all the sub-queries managed by @a query
   * @return A new list of the sub-queries.
   */
  Glib::SListHandle<Glib::RefPtr<Query> > get_sub_queries();
  
  /** Tells @a query that @a param_source is a query which potentially will constraint the possible values
   * of one or more of @a query's parameters. This implies that @a query keeps a reference on @a param_source.
   * @param param_source A Gda::DataModel object.
   */
  void add_param_source(const Glib::RefPtr<DataModel>& param_source);
  
  /** Tells @a query that it should no longer take care of @a param_source.
   * The parameters which depend on @a param_source will still depend on it, though.
   * @param param_source A Gda::DataModel object.
   */
  void del_param_source(const Glib::RefPtr<DataModel>& param_source);

   
  /** Get a list of the parameter source queries that are references as such by @a query.
   * @return The list of Gda::Query objects.
   */
  Glib::SListHandle<Glib::RefPtr<const Query> > get_param_sources() const;

  
  /** Add @a sub_query to @a query. Sub queries are managed by their parent query, and as such they
   * are destroyed when their parent query is destroyed.
   * @param sub_query A Gda::Query object.
   */
  void add_sub_query(const Glib::RefPtr<Query>& sub_query);
  
  /** Removes @a sub_query from @a query. @a sub_query MUST be present within @a query.
   * @param sub_query A Gda::Query object.
   */
  void del_sub_query(const Glib::RefPtr<Query>& sub_query);

  
  /** Adds a target to @a query. A target represents a entity (it can actually be a table,
   * a view, or another query) which @a query will use. 
   * 
   * For a SELECT query, the targets appear
   * after the FROM clause. The targets can be joined two by two using Gda::QueryJoin objects
   * 
   * For UPDATE, DELETE or INSERT queries, there can be only ONE Gda::QueryTarget object which is
   * the one where the data modifications are performed.
   * 
   * For UNION and INTERSECT queries, there is no possible Gda::QueryTarget object.
   * @param target A Gda::QueryTarget to add to @a query.
   * @return <tt>true</tt> if no error occurred.
   */
#ifdef GLIBMM_EXCEPTIONS_ENABLED
  bool add_target(const Glib::RefPtr<QueryTarget>& target);
#else
  bool add_target(const Glib::RefPtr<QueryTarget>& target, std::auto_ptr<Glib::Error>& error);
#endif //GLIBMM_EXCEPTIONS_ENABLED

  
  /** Removes @a target from @a query. @a target MUST be present within @a query. Warning:
   * All the joins and fields which depended on @a target are also removed.
   * @param target A Gda::QueryTarget object.
   */
  void del_target(const Glib::RefPtr<QueryTarget>& target);

   
  /** Get a list of all the targets used in @a query
   * @return A new list of the targets.
   */
  Glib::SListHandle<Glib::RefPtr<QueryTarget> > get_targets();
  
  /** Get a list of all the targets used in @a query
   * @return A new list of the targets.
   */
  Glib::SListHandle<Glib::RefPtr<const QueryTarget> > get_targets() const;

  
  /** Get a pointer to a Gda::QueryTarget (which must be within @a query) using
   * its XML Id
   * @param xml_id The XML Id of the requested Gda::QueryTarget object.
   * @return The Gda::QueryTarget object, or <tt>0</tt> if not found.
   */
  Glib::RefPtr<QueryTarget> get_target_by_xml_id(const Glib::ustring& xml_id);
  
  /** Get a pointer to a Gda::QueryTarget (which must be within @a query) using
   * its XML Id
   * @param xml_id The XML Id of the requested Gda::QueryTarget object.
   * @return The Gda::QueryTarget object, or <tt>0</tt> if not found.
   */
  Glib::RefPtr<const QueryTarget> get_target_by_xml_id(const Glib::ustring& xml_id) const;
  
  /** Get a pointer to a Gda::QueryTarget (which must be within @a query) using
   * its alias (if not found then @a alias_or_name is interpreted as the target name)
   * @param alias_or_name The alias or name.
   * @return The Gda::QueryTarget object, or <tt>0</tt> if not found.
   */
  Glib::RefPtr<QueryTarget> get_target_by_alias(const Glib::ustring& alias_or_name);
  
  /** Get a pointer to a Gda::QueryTarget (which must be within @a query) using
   * its alias (if not found then @a alias_or_name is interpreted as the target name)
   * @param alias_or_name The alias or name.
   * @return The Gda::QueryTarget object, or <tt>0</tt> if not found.
   */
  Glib::RefPtr<const QueryTarget> get_target_by_alias(const Glib::ustring& alias_or_name) const;

   
  /** Makes a list of the Gda::QueryField objects which represent primary key fields of
   * the entity represented by @a target.
   * 
   * If the entity represented by @a target does not have any primary key, or if the 
   * primary key's fields are not present in @a query, then the returned value is <tt>0</tt>.
   * @param target A Gda::QueryTarget object.
   * @return A new GSList, or <tt>0</tt>.
   */
  Glib::SListHandle<Glib::RefPtr<QueryField> > get_target_pkfields(const Glib::RefPtr<QueryTarget>& target);
  
  /** Makes a list of the Gda::QueryField objects which represent primary key fields of
   * the entity represented by @a target.
   * 
   * If the entity represented by @a target does not have any primary key, or if the 
   * primary key's fields are not present in @a query, then the returned value is <tt>0</tt>.
   * @param target A Gda::QueryTarget object.
   * @return A new GSList, or <tt>0</tt>.
   */
  Glib::SListHandle<Glib::RefPtr<const QueryField> > get_target_pkfields(const Glib::RefPtr<QueryTarget>& target) const;

  
  /** Add a join to @a query. A join is defined by the two Gda::QueryTarget objects it joins and by
   * a join condition which MUST ONLY make use of fields of the two entities represented by the
   * targets.
   * 
   * For any given couple of Gda::QueryTarget objects, there can exist ONLY ONE Gda::QueryJoin which joins the
   * two.
   * @param join A Gda::QueryJoin object.
   * @return <tt>true</tt> on success, and <tt>false</tt> otherwise.
   */
  bool add_join(const Glib::RefPtr<QueryJoin>& join);
  
  /** Removes @a join from @a query. @a join MUST be present within @a query.
   * @param join A Gda::QueryJoin object.
   */
  void del_join(const Glib::RefPtr<QueryJoin>& join);

   
  /** Get a list of all the joins used in @a query
   * @return A new list of the joins.
   */
  Glib::SListHandle<Glib::RefPtr<QueryJoin> > get_joins();
  
  /** Get a list of all the joins used in @a query
   * @return A new list of the joins.
   */
  Glib::SListHandle<Glib::RefPtr<const QueryJoin> > get_joins() const;

  
  /** Find a join in @a query which joins the @a target1 and @a target2 targets
   * @param target1 A Gda::QueryTarget object.
   * @param target2 A Gda::QueryTarget object.
   * @return The Gda::QueryJoin object, or <tt>0</tt>.
   */
  Glib::RefPtr<QueryJoin> get_join_by_targets(const Glib::RefPtr<QueryTarget>& target1, const Glib::RefPtr<QueryTarget>& target2);
  
  /** Find a join in @a query which joins the @a target1 and @a target2 targets
   * @param target1 A Gda::QueryTarget object.
   * @param target2 A Gda::QueryTarget object.
   * @return The Gda::QueryJoin object, or <tt>0</tt>.
   */
  Glib::RefPtr<const QueryJoin> get_join_by_targets(const Glib::RefPtr<QueryTarget>& target1, const Glib::RefPtr<QueryTarget>& target2) const;

  
  /** Get the query's associated condition
   * @return The Gda::QueryCondition object.
   */
  Glib::RefPtr<QueryCondition> get_condition();
  
  /** Get the query's associated condition
   * @return The Gda::QueryCondition object.
   */
  Glib::RefPtr<const QueryCondition> get_condition() const;
  
  /** Sets the query's associated condition; if there was already a query condition,
   * then the old one is trashed first.
   * 
   * Pass <tt>0</tt> as the @a cond argument to remove any query condition
   * @param cond A Gda::QueryCondition object, or <tt>0</tt> to remove condition.
   */
  void set_condition(const Glib::RefPtr<QueryCondition>& cond);
  
  /** Appends the @a cond object to @a query's condition. If @a query does not yet
   * have any condition, then the result is the same as set_condition();
   * otherwise, @a cond is added to @a query's condition, using the AND operator
   * if @a append_as_and is <tt>true</tt>, and an OR operator if @a append_as_and is <tt>false</tt>.
   * @param cond A Gda::QueryCondition object.
   * @param append_as_and Mode of append if there is already a query condition.
   */
  void append_condition(const Glib::RefPtr<QueryCondition>& cond, bool append_as_and = true);

   
  /** Makes a list of all the conditions (part of the WHERE clause) which
   * are always verified by @a query when it is executed.
   * 
   * Examples: if the WHERE clause is:
   * --&gt; "A and B" then the list will contains {A, B}
   * --&gt; "A and (B or C)" it will contain {A, B or C}
   * --&gt; "A and (B and not C)", it will contain {A, B, not C}
   * @return A new list of Gda::QueryCondition objects.
   */
  Glib::SListHandle<Glib::RefPtr<QueryCondition> > get_main_conditions();
  
  /** Makes a list of all the conditions (part of the WHERE clause) which
   * are always verified by @a query when it is executed.
   * 
   * Examples: if the WHERE clause is:
   * --&gt; "A and B" then the list will contains {A, B}
   * --&gt; "A and (B or C)" it will contain {A, B or C}
   * --&gt; "A and (B and not C)", it will contain {A, B, not C}
   * @return A new list of Gda::QueryCondition objects.
   */
  Glib::SListHandle<Glib::RefPtr<const QueryCondition> > get_main_conditions() const;

  // The libgda documentation says these are internally used functions
  
  
  /** Sets @a field to be used in the ORDER BY clause (using the @a order and @a ascendant attributes) if
   *  @a order &gt;= 0. If @a order &lt; 0, then @a field will not be used in the ORDER BY clause.
   * @param field A Gda::QueryField which is in @a query.
   * @param order The order in the list of ORDER BY fields (starts at 0), or -1.
   * @param ascendant <tt>true</tt> to sort ascending.
   */
  void set_order_by_field(const Glib::RefPtr<QueryField>& field, int order = 0, bool ascendant = true);
  int get_order_by_field(const Glib::RefPtr<QueryField>& field) const;
  int get_order_by_field(const Glib::RefPtr<QueryField>& field, bool& ascendant) const;

  
  /** Parses @a field and if it represents a valid SQL expression for a
   * field, then add it to @a query.
   * @param field A SQL expression.
   * @return A new Gda::QueryField object, or <tt>0</tt>.
   */
#ifdef GLIBMM_EXCEPTIONS_ENABLED
  Glib::RefPtr<QueryField> add_field_from_sql(const Glib::ustring& field);
#else
  Glib::RefPtr<QueryField> add_field_from_sql(const Glib::ustring& field, std::auto_ptr<Glib::Error>& error);
#endif //GLIBMM_EXCEPTIONS_ENABLED

  
  /** Fetch a list of all the fields of @a query: the ones which are visible, and
   * the ones which are not visible and are not internal query fields.
   * @return A new list of fields.
   */
  Glib::SListHandle<Glib::RefPtr<QueryField> > get_all_fields();
  
  /** Fetch a list of all the fields of @a query: the ones which are visible, and
   * the ones which are not visible and are not internal query fields.
   * @return A new list of fields.
   */
  Glib::SListHandle<Glib::RefPtr<const QueryField> > get_all_fields() const;
  
  /** 
   * @param sql_name The SQL naming for the requested field.
   */
  Glib::RefPtr<QueryField> get_field_by_sql_naming(const Glib::ustring& sql_name);
  
  /** 
   * @param sql_name The SQL naming for the requested field.
   */
  Glib::RefPtr<const QueryField> get_field_by_sql_naming(const Glib::ustring& sql_name) const;
  
  Glib::RefPtr<QueryField> get_field_by_param_name(const Glib::ustring& param_name);
  
  Glib::RefPtr<const QueryField> get_field_by_param_name(const Glib::ustring& param_name) const;
  
  /** Finds the first Gda::QueryField object in @a query which represents @a ref_field.
   * The returned object will be a Gda::QueryFieldField object which represents @a ref_field.
   * 
   * If @a target is specified, then the returned field will be linked to that Gda::QueryTarget object.
   * @param target A Gda::QueryTarget, or <tt>0</tt>.
   * @param ref_field A Gda::EntityField object.
   * @param field_state Tells about the status of the requested field, see Gda::QueryFieldState.
   * @return A Gda::QueryFieldField object or <tt>0</tt>.
   */
  Glib::RefPtr<QueryField> get_field_by_ref_field(const Glib::RefPtr<QueryTarget>& target, const Glib::RefPtr<EntityField>& ref_field, QueryFieldState field_state);
  
  /** Finds the first Gda::QueryField object in @a query which represents @a ref_field.
   * The returned object will be a Gda::QueryFieldField object which represents @a ref_field.
   * 
   * If @a target is specified, then the returned field will be linked to that Gda::QueryTarget object.
   * @param target A Gda::QueryTarget, or <tt>0</tt>.
   * @param ref_field A Gda::EntityField object.
   * @param field_state Tells about the status of the requested field, see Gda::QueryFieldState.
   * @return A Gda::QueryFieldField object or <tt>0</tt>.
   */
  Glib::RefPtr<const QueryField> get_field_by_ref_field(const Glib::RefPtr<QueryTarget>& target, const Glib::RefPtr<EntityField>& field, QueryFieldState field_state) const;
  
  /** Finds the first occurence of a Gda::QueryFieldField object whose target is @a target in @a query
   * @return The requested field, or <tt>0</tt>.
   */
  Glib::RefPtr<QueryField> get_first_field_for_target(const Glib::RefPtr<QueryTarget>& target);
  
  /** Finds the first occurence of a Gda::QueryFieldField object whose target is @a target in @a query
   * @return The requested field, or <tt>0</tt>.
   */
  Glib::RefPtr<const QueryField> get_first_field_for_target(const Glib::RefPtr<QueryTarget>& target) const;

  
  /** Converts each visible "target.*" (Gda::QueryFieldAll) field into its list of fields. For example "t1.*" becomes "t1.a, t1.b"
   * if table t1 is composed of fields "a" and "b". The original GdaQueryFieldAll field is not removed, but
   * simply rendered non visible.
   * 
   * The returned list must be free'd by the caller using Glib::slist_free().
   * @param target A Gda::QueryTarget, or <tt>0</tt>.
   * @return A new list of the Gda::QueryField objects which have been created.
   */
  Glib::SListHandle<Glib::RefPtr<QueryField> > expand_all_field(const Glib::RefPtr<QueryTarget>& target);
  
  /** Re-orders the fields in @a query using the joins' conditions: for each join condition,
   * the used query fields are grouped together near the 1st visible field.
   */
  void order_fields_using_join_conds();
  
  /** Get a list of all the Gda::QueryField objects in @a query which depent on the existance of 
   *  @a target.
   * @param target A Gda::QueryTarget object representing a target in @a query.
   * @return A new list of Gda::QueryField objects.
   */
  Glib::SListHandle<Glib::RefPtr<QueryField> > get_fields_by_target(const Glib::RefPtr<QueryTarget>& target, bool visible_fields_only = true);
  
  /** Get a list of all the Gda::QueryField objects in @a query which depent on the existance of 
   *  @a target.
   * @param target A Gda::QueryTarget object representing a target in @a query.
   * @return A new list of Gda::QueryField objects.
   */
  Glib::SListHandle<Glib::RefPtr<const QueryField> > get_fields_by_target(const Glib::RefPtr<QueryTarget>& target, bool visible_fields_only = true) const;

  // TODO: This is declared in a separate header that looks a bit private. We can still add it
  // later if we need it. armin.
  //_WRAP_METHOD(Glib::RefPtr<QueryField> get_field_by_sql_naming_fields(const Glib::ustring& sql_name, const Glib::SListHandle<Glib::RefPtr<QueryField> >& fields_list), gda_query_get_field_by_sql_naming_fields, refreturn)
  //_WRAP_METHOD(Glib::RefPtr<const QueryField> get_field_by_sql_naming_fields(const Glib::ustring& sql_name, const Glib::SListHandle<Glib::RefPtr<QueryField> >& fields_list) const, gda_query_get_field_by_sql_naming_fields, refreturn, constversion)

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

  Glib::SignalProxy0< void > signal_type_changed();

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

  Glib::SignalProxy0< void > signal_condition_changed();

  
  /**
   * @par Prototype:
   * <tt>void on_my_%target_added(const Glib::RefPtr<QueryTarget>& target)</tt>
   */

  Glib::SignalProxy1< void,const Glib::RefPtr<QueryTarget>& > signal_target_added();

  
  /**
   * @par Prototype:
   * <tt>void on_my_%target_removed(const Glib::RefPtr<QueryTarget>& target)</tt>
   */

  Glib::SignalProxy1< void,const Glib::RefPtr<QueryTarget>& > signal_target_removed();

  
  /**
   * @par Prototype:
   * <tt>void on_my_%target_updated(const Glib::RefPtr<QueryTarget>& target)</tt>
   */

  Glib::SignalProxy1< void,const Glib::RefPtr<QueryTarget>& > signal_target_updated();

  
  /**
   * @par Prototype:
   * <tt>void on_my_%join_added(const Glib::RefPtr<QueryJoin>& join)</tt>
   */

  Glib::SignalProxy1< void,const Glib::RefPtr<QueryJoin>& > signal_join_added();

  
  /**
   * @par Prototype:
   * <tt>void on_my_%join_removed(const Glib::RefPtr<QueryJoin>& join)</tt>
   */

  Glib::SignalProxy1< void,const Glib::RefPtr<QueryJoin>& > signal_join_removed();

  
  /**
   * @par Prototype:
   * <tt>void on_my_%join_updated(const Glib::RefPtr<QueryJoin>& join)</tt>
   */

  Glib::SignalProxy1< void,const Glib::RefPtr<QueryJoin>& > signal_join_updated();

  
  /**
   * @par Prototype:
   * <tt>void on_my_%sub_query_added(const Glib::RefPtr<Query>& query)</tt>
   */

  Glib::SignalProxy1< void,const Glib::RefPtr<Query>& > signal_sub_query_added();

  
  /**
   * @par Prototype:
   * <tt>void on_my_%sub_query_removed(const Glib::RefPtr<Query>& query)</tt>
   */

  Glib::SignalProxy1< void,const Glib::RefPtr<Query>& > signal_sub_query_removed();

  
  /**
   * @par Prototype:
   * <tt>void on_my_%sub_query_updated(const Glib::RefPtr<Query>& query)</tt>
   */

  Glib::SignalProxy1< void,const Glib::RefPtr<Query>& > signal_sub_query_updated();


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
  virtual void on_type_changed();
  virtual void on_condition_changed();
  virtual void on_target_added(const Glib::RefPtr<QueryTarget>& target);
  virtual void on_target_removed(const Glib::RefPtr<QueryTarget>& target);
  virtual void on_target_updated(const Glib::RefPtr<QueryTarget>& target);
  virtual void on_join_added(const Glib::RefPtr<QueryJoin>& join);
  virtual void on_join_removed(const Glib::RefPtr<QueryJoin>& join);
  virtual void on_join_updated(const Glib::RefPtr<QueryJoin>& join);
  virtual void on_sub_query_added(const Glib::RefPtr<Query>& query);
  virtual void on_sub_query_removed(const Glib::RefPtr<Query>& query);
  virtual void on_sub_query_updated(const Glib::RefPtr<Query>& query);
#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::Query
   */
  Glib::RefPtr<Gnome::Gda::Query> wrap(GdaQuery* object, bool take_copy = false);
}


#endif /* _LIBGDAMM_QUERY_H */

