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


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

// -*- C++ -*- //

/* dataselect.h
 *
 * Copyright 2006 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/datamodel.h>
#include <libgdamm/statement.h>
#include <libgdamm/set.h>

#ifndef DOXYGEN_SHOULD_SKIP_THIS
typedef struct _GdaDataSelect GdaDataSelect;
typedef struct _GdaDataSelectClass GdaDataSelectClass;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


namespace Gnome
{

namespace Gda
{ class DataSelect_Class; } // namespace Gda

} // namespace Gnome
namespace Gnome
{

namespace Gda
{

/** Data models returned by the execution of a SELECT statement.
 *
 * This data model implements the Gda::DataModel interface and is the required 
 * base object when database providers implement a data model returned when a 
 * SELECT statement has been executed. As the GdaDataModel interface is implemented, 
 * consult the API to access and modify the data held in a GdaDataSelect object.
 *
 * The default behaviour however is to disallow modifications, and this section 
 * documents how to characterize a Gda::DataSelect to allow modifications. 
 * Once this is done, any modification done to the data model whill be propagated 
 * to the modified table in the database using INSERT, UPDATE or DELETE statements.
 *
 * After any modification, it is still possible to read values from the data model
 * (even values for rows which have been modified or inserted). The data model 
 * might then execute some SELECT statement to fetch some actualized values. 
 * Note: there is a corner case where a modification made to a row would make 
 * the row not selected at first in the data model (for example is the original 
 * SELECT statement included a clause "WHERE id < 100" and the modification sets 
 * the "id" value to 110), then the row will still be in the data model 
 * even though it would not be if the SELECT statement which execution 
 * created the data model in the first place was re-run.
 *
 * @ingroup DataModels
 */

class DataSelect
 : public Glib::Object,
   public DataModel
{
  
#ifndef DOXYGEN_SHOULD_SKIP_THIS

public:
  typedef DataSelect CppObjectType;
  typedef DataSelect_Class CppClassType;
  typedef GdaDataSelect BaseObjectType;
  typedef GdaDataSelectClass BaseClassType;

private:  friend class DataSelect_Class;
  static CppClassType dataselect_class_;

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

protected:
  explicit DataSelect(const Glib::ConstructParams& construct_params);
  explicit DataSelect(GdaDataSelect* castitem);

#endif /* DOXYGEN_SHOULD_SKIP_THIS */

public:
  virtual ~DataSelect();

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

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

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

private:

  
public:
  
  /** Specifies the SQL condition corresponding to the WHERE part of a SELECT statement which would
   * return only 1 row (the expression of the primary key).
   * 
   * For example for a table created as <![CDATA["CREATE TABLE mytable (part1 int NOT <tt>0</tt>, part2 string NOT <tt>0</tt>, 
   * name string, PRIMARY KEY (part1, part2))"]]>, and if @a pmodel corresponds to the execution of the 
   * <![CDATA["SELECT name, part1, part2 FROM mytable"]]>, then the sensible value for @a sql_where would be
   * <![CDATA["part1 = ##-1::int AND part2 = ##-2::string"]]> because the values of the 'part1' field are located
   * in @a pmodel's column number 1 and the values of the 'part2' field are located
   * in @a pmodel's column number 2 and the primary key is composed of (part1, part2).
   * 
   * For more information about the syntax of the parameters (named <![CDATA["##-1::int"]]> for example), see the
   * GdaSqlParser documentation, and 
   * set_modification_statement().
   * @param sql_where An SQL condition (without the WHERE keyword).
   * @return <tt>true</tt> if no error occurred.
   */
  bool set_row_selection_condition_sql(const Glib::ustring& sql_where);
  // This is internal only
  
  
  /** Offers the same features as set_row_selection_condition() but the expression
   * is computed from the meta data associated to the connection being used when @a model was created.
   * 
   * NOTE1: make sure the meta data associated to the connection is up to date before using this
   * method, see Gda::Connection::update_meta_store().
   * 
   * NOTE2: if the SELECT statement from which @a model has been created uses more than one table, or
   * if the table used does not have any primary key, then this method will fail
   * @return <tt>true</tt> if no error occurred.
   */
  void compute_row_selection_condition();
  
  /** Informs @a model that it should allow modifications to the data in some columns and some rows
   * using @a mod_stmt to propagate those modifications into the database.
   * 
   * If @a mod_stmt is:
   * <itemizedlist>
   * <listitem>an UPDATE statement, then all the rows in @a model will be modifyable</listitem>
   * <listitem>a DELETE statement, then it will be possible to delete rows in @a model</listitem>
   * <listitem>in INSERT statement, then it will be possible to add some rows to @a model</listitem>
   * <listitem>any other statement, then this method will return an error</listitem>
   * </itemizedlist>
   * 
   * This method can be called several times to specify different types of modification.
   * 
   * If @a mod_stmt is an UPDATE or DELETE statement then it should have a WHERE part which identifies
   * a unique row in @a model (please note that this property can't be checked but may result
   * in @a model behaving in an unpredictable way).
   * 
   * NOTE1: However, if the set_row_selection_condition()
   * or set_row_selection_condition_sql() have been successfully be called before, the WHERE
   * part of @a mod_stmt <em>WILL</em> be modified to use the row selection condition specified through one of
   * these methods (please not that it is then possible to avoid specifying a WHERE part in @a mod_stmt then).
   * 
   * NOTE2: if set_row_selection_condition()
   * or set_row_selection_condition_sql() have not yet been successfully be called before, then
   * the WHERE part of @a mod_stmt will be used as if one of these functions had been called.
   * @param mod_stmt A Gda::Statement (INSERT, UPDATE or DELETE).
   * @return <tt>true</tt> if no error occurred.
   */
  void set_modification_statement(const Glib::RefPtr<Statement>& mod_stmt);
  
  /** Offers the same feature as set_modification_statement() but using an SQL statement
   * @param sql An SQL text.
   * @return <tt>true</tt> if no error occurred.
   */
  void set_modification_statement_sql(const Glib::ustring& sql);
  
  /** Makes @a model try to compute INSERT, UPDATE and DELETE statements to be used when modifying @a model's contents.
   * @note any modification statement set using set_modification_statement() will first be unset
   * @return <tt>true</tt> if no error occurred. If <tt>false</tt> is returned, then some modification statement may still have been
   * computed.
   */
  void compute_modification_statements();
  
  /** Computes correct attributes for each of @a model's columns, which includes the "NOT <tt>0</tt>" attribute, the
   * default value, the precision and scale for numeric values.
   * @return <tt>true</tt> if no error occurred.
   */
  void compute_columns_attributes();

  
  /** Get a pointer to the Gda::Connection object which was used when @a model was created
   * (and which may be used internally by @a model).
   * @return A pointer to the Gda::Connection, or <tt>0</tt>.
   */
  Glib::RefPtr<Connection> get_connection();

  
  /** Requests that @a model be re-run to have an updated result. If an error occurs,
   * then @a model will not be changed.
   * 
   * @newin{4,2}
   * @return <tt>true</tt> if no error occurred.
   */
  void rerun();

  #ifdef GLIBMM_PROPERTIES_ENABLED
/** Automatically re-run the SELECT statement if any parameter has changed since it was first executed.
   *
   * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
   * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
   * the value of the property changes.
   */
  Glib::PropertyProxy<bool> property_auto_reset() ;
#endif //#GLIBMM_PROPERTIES_ENABLED

#ifdef GLIBMM_PROPERTIES_ENABLED
/** Automatically re-run the SELECT statement if any parameter has changed since it was first executed.
   *
   * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
   * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
   * the value of the property changes.
   */
  Glib::PropertyProxy_ReadOnly<bool> property_auto_reset() const;
#endif //#GLIBMM_PROPERTIES_ENABLED

  #ifdef GLIBMM_PROPERTIES_ENABLED
/** Tells if model has analyzed all the rows.
   *
   * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
   * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
   * the value of the property changes.
   */
  Glib::PropertyProxy<bool> property_store_all_rows() ;
#endif //#GLIBMM_PROPERTIES_ENABLED

#ifdef GLIBMM_PROPERTIES_ENABLED
/** Tells if model has analyzed all the rows.
   *
   * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
   * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
   * the value of the property changes.
   */
  Glib::PropertyProxy_ReadOnly<bool> property_store_all_rows() const;
#endif //#GLIBMM_PROPERTIES_ENABLED

  #ifdef GLIBMM_PROPERTIES_ENABLED
/** Connection from which this data model is created.
   *
   * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
   * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
   * the value of the property changes.
   */
  Glib::PropertyProxy_ReadOnly< Glib::RefPtr<Connection> > property_connection() const;
#endif //#GLIBMM_PROPERTIES_ENABLED


  #ifdef GLIBMM_PROPERTIES_ENABLED
/** DELETE Statement to be executed to remove data.
   *
   * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
   * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
   * the value of the property changes.
   */
  Glib::PropertyProxy< Glib::RefPtr<Statement> > property_delete_stmt() ;
#endif //#GLIBMM_PROPERTIES_ENABLED

#ifdef GLIBMM_PROPERTIES_ENABLED
/** DELETE Statement to be executed to remove data.
   *
   * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
   * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
   * the value of the property changes.
   */
  Glib::PropertyProxy_ReadOnly< Glib::RefPtr<Statement> > property_delete_stmt() const;
#endif //#GLIBMM_PROPERTIES_ENABLED

  #ifdef GLIBMM_PROPERTIES_ENABLED
/** INSERT Statement to be executed to add data.
   *
   * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
   * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
   * the value of the property changes.
   */
  Glib::PropertyProxy< Glib::RefPtr<Statement> > property_insert_stmt() ;
#endif //#GLIBMM_PROPERTIES_ENABLED

#ifdef GLIBMM_PROPERTIES_ENABLED
/** INSERT Statement to be executed to add data.
   *
   * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
   * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
   * the value of the property changes.
   */
  Glib::PropertyProxy_ReadOnly< Glib::RefPtr<Statement> > property_insert_stmt() const;
#endif //#GLIBMM_PROPERTIES_ENABLED

  #ifdef GLIBMM_PROPERTIES_ENABLED
/** Associated prepared statement (for internal usage).
   *
   * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
   * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
   * the value of the property changes.
   */
  Glib::PropertyProxy< Glib::RefPtr<Statement> > property_prepared_stmt() ;
#endif //#GLIBMM_PROPERTIES_ENABLED

#ifdef GLIBMM_PROPERTIES_ENABLED
/** Associated prepared statement (for internal usage).
   *
   * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
   * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
   * the value of the property changes.
   */
  Glib::PropertyProxy_ReadOnly< Glib::RefPtr<Statement> > property_prepared_stmt() const;
#endif //#GLIBMM_PROPERTIES_ENABLED

  #ifdef GLIBMM_PROPERTIES_ENABLED
/** UPDATE Statement to be executed to update data.
   *
   * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
   * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
   * the value of the property changes.
   */
  Glib::PropertyProxy< Glib::RefPtr<Statement> > property_update_stmt() ;
#endif //#GLIBMM_PROPERTIES_ENABLED

#ifdef GLIBMM_PROPERTIES_ENABLED
/** UPDATE Statement to be executed to update data.
   *
   * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
   * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
   * the value of the property changes.
   */
  Glib::PropertyProxy_ReadOnly< Glib::RefPtr<Statement> > property_update_stmt() const;
#endif //#GLIBMM_PROPERTIES_ENABLED

  #ifdef GLIBMM_PROPERTIES_ENABLED
/** GdaSet used when the SELECT statement was executed.
   *
   * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
   * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
   * the value of the property changes.
   */
  Glib::PropertyProxy_ReadOnly< Glib::RefPtr<Set> > property_exec_params() const;
#endif //#GLIBMM_PROPERTIES_ENABLED


  #ifdef GLIBMM_PROPERTIES_ENABLED
/** Determines how the data model may be used.
   *
   * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
   * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
   * the value of the property changes.
   */
  Glib::PropertyProxy_ReadOnly<guint> property_model_usage() const;
#endif //#GLIBMM_PROPERTIES_ENABLED


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


#endif /* _LIBGDAMM_DATASELECT_H */

