///////
   //   Interface class for a MySQL Database client application
   //
   //    Copyright (c) 1999-2004 Comune di Prato - Prato - Italy
   //    Some Portions Copyright (c) 2008 Devise.IT srl <http://www.devise.it/>
   //    Author: Gabriele Bartolini - Prato - Italy <angusgb@users.sourceforge.net>
   //
   //    For copyright details, see the file COPYING in your distribution
   //    or the GNU General Public License version 2 or later 
   //    <http://www.gnu.org/copyleft/gpl.html>
   //
   //    $Id: Htmysql.h,v 1.13 2009/08/26 12:25:57 angusgb Exp $
   //
   //    G.Bartolini
   //    started: 02.07.1999
   //
///////

#ifndef _HTMYSQL_H
#define _HTMYSQL_H

#include "mysql.h"
#include "mysqld_error.h"

#ifdef HAVE_STD
#include <iostream>
#include <string>
#ifdef HAVE_NAMESPACES
using namespace std;
#endif
#else
#include <iostream.h>
#include <string.h>
#endif /* HAVE_STD */

class HtmysqlQueryResult;

class Htmysql
{
   public:

      Htmysql();
      virtual ~Htmysql() = 0;

      // Initializes the Database
      int Init();

      // Connects with a MySQL database

      virtual int Connect( const char *host=NULL, const char *user=NULL,
                           const char *passwd=NULL, const char *db=NULL,
                           uint port=0, const char *unix_socket=NULL,
                           uint client_flag=0);
	 
      // Close the connection
      void Close();
	 
      // Ping: checks whether or not the connection to the server is working
      //       Reconnect if necessary
      //    	Returns zero if alive, non-zero if an error occured
      int Ping();
	 
      // Select the current database
      int SelectDB(const std::string db);
	 
      // Execute a query
      int ExecQuery (const std::string query);

      enum Query_Type
      {
         Htmysql_Stored,
         Htmysql_Temporary
      };
	 
      // Store the result of a query
      HtmysqlQueryResult *StoreResult(HtmysqlQueryResult &);
      HtmysqlQueryResult *StoreResult();

      // Get next record directly from the connection
      HtmysqlQueryResult *UseResult(HtmysqlQueryResult &);
      HtmysqlQueryResult *UseResult();

      // Retrieve the database list with an optional pattern
      HtmysqlQueryResult *ListDBs (const char *wild = NULL);

      // Returns the ID that was most recently generated for AUTO_INCREMENT field
      int GetLastID();
      
      // Check if a database exists (with wilcards -- foo%)
      // Returns -1 if an error occurs, else the number of times
      // the database has been found (0, 1, >1 in a wildcard case)
      
      int Exists (const std::string &dbname);
            
      // Gets the error number
      int GetError();
	 
      // Displays an error message
      int DisplayError (ostream & _stream = cout);

      // Set SQL big tables option (for MySQL)
      virtual int SetSQLBigTableOption() = 0;

      // Optimize a database
      virtual int Optimize() = 0 ;

      // Static methods for managing debug level
      static void SetDebugLevel (int d) { debug=d;}

	  // Set/Get the flag for dropping or not the database
	  void SetDropDatabase(const bool f) { drop_database = f; }
	  const bool GetDropDatabase() const { return drop_database; }

      
   protected:
      MYSQL mysql;
	  bool drop_database; // Should we drop the database

      static int debug;    // Run-time debugging level

      void ReadDefaultGroup(const std::string& group);

};



///////
   //    Class containing query results
///////


class HtmysqlQueryResult
{
   friend class Htmysql;    // declaring friendship

   public:

      HtmysqlQueryResult();
      ~HtmysqlQueryResult();

         bool Empty() const { return !result;}
         Htmysql::Query_Type Type() const { return _query_type; }
      	 
	 unsigned int GetRows() const  	{return rows;}
	 unsigned int GetFields() const 	{return fields;}
         
	 void Free();
	 
	 MYSQL_ROW GetNextRecord();

         // View the whole database
         void View (ostream & _stream = cout);
	 
   protected:

   	 void Set(MYSQL_RES *);
	 void Refresh();
	    
   	 MYSQL_RES   *result;
         MYSQL_ROW   _record;
	 
	 unsigned int rows;
	 unsigned int fields;
         
         Htmysql::Query_Type  _query_type;

};

#endif
