#ifndef _SQL_H
#define _SQL_H

/*

    Copyright (C) 2009  Matthew William Coan

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

Small C++ SQL database client API.

Author: Matthew William Coan
Date: Sun May 22 14:55:18 EST 2011

*/

#include <mysql.h>
#include <string>

namespace sql_client {

using namespace std;

class Statement;

class Connection {
   string host;
   int port;
   MYSQL * conn;
   int error;

public:
   Connection(const string & host,
              const string & user,
              const string & pass,
              const string & db)
   {
      this->host = host;
      this->port = port;

      conn = mysql_init(NULL);

      if(!mysql_real_connect(conn, host.c_str(), user.c_str(), pass.c_str(), db.c_str(), 0, NULL, 0))
         error = 0;
      else
         error = 1;
   }

   virtual ~Connection()
   {
      if(conn != NULL)
         mysql_close(conn);
   }

   Statement * get_statement();

   void set_catalog(const string & db) { mysql_select_db(conn, db.c_str()); }

   operator void*() { return ((void*)(error)); }

   void close() {
      if(conn != NULL) {
         mysql_close(conn);
         conn = NULL;
      }
   }
};

class ResultSet;

class Statement {
   MYSQL * conn;

public:
   Statement(MYSQL * conn)
   {
      this->conn = conn;
   }

   ~Statement()
   {
   }
   
   ResultSet * execute(const string & sql);

   bool execute_update(const string & sql)
   {   
       bool ret = true;

       if(mysql_query(conn, sql.c_str()))
           ret = false;

       return ret;
   }
};

class ResultSet {
   MYSQL_RES * res;
   MYSQL_ROW row;

public:
   ResultSet(MYSQL_RES * res)
   {
      this->res = res;
      row = mysql_fetch_row(res);
   }

   ~ResultSet()
   {
      mysql_free_result(res);
   }

   string get_string(const size_t index)
   {
      return row[index];
   }

   string get_string(const string & name)
   {
      string ret;

      return ret;
   }

   void next()
   { 
      row = mysql_fetch_row(res);
   }

   bool has_more()
   { 
       bool ret = false;

       if(row) 
          ret = true;

       return ret;
   }
};

inline ResultSet * Statement::execute(const string & sql)
{
   MYSQL_RES * res = NULL;
   ResultSet * ret = 0;

   if(!mysql_query(conn, sql.c_str())) {
      res = mysql_use_result(conn);

      ret = new ResultSet(res);
   }

   return ret;
}

inline Statement * Connection::get_statement()
{
   return new Statement(conn);
}


}



#endif /* _SQL_H */
