/*
 * dbreader.h: definition of a base class for database-objects
 *
 * See the README file for copyright information and how to reach the author.
 *
 * $Id$
 */
#ifndef _DBREADER_H
#define _DBREADER_H
#include <mysql.h>
#include "config.h"
#include "tools.h"

template<class T> class cDbReader {
public:
  cDbReader():sql(NULL),res(NULL),numfields(0) {_};
 ~cDbReader() {_
	  if(res) mysql_free_result(res);
     };
  T * Read(T *o, void * info) {_
	  if(!res || !XmsSetup.DbHandle()) {
		  if(o) free(o);
		  return NULL; 
	     }
	  MYSQL_ROW row;
	  cDataInfo * DatInf = (cDataInfo *)info;

	  if(row = mysql_fetch_row(res)) {
		  unsigned long * widths = mysql_fetch_lengths(res);
		  char * base = (char *)o;
		  char * tmp;
		  char	scratch[128];

		  for(int i=0; i < numfields; i++) {
			  switch(DatInf[i].type) {
				  case cDataInfo::TEXT:
					  asprintf(&tmp, "%.*s", (int)widths[i], row[i] ? row[i] : "");
					  *((char **)(base + DatInf[i].off)) = tmp;
					  break;
				  case cDataInfo::INTEGER:
					  sprintf(scratch, "%.*s", (int)widths[i], row[i] ? row[i] : "0");
					  *((int *)(base + DatInf[i].off)) = atoi(scratch);
					  break;
				  case cDataInfo::DECIMAL:
					  sprintf(scratch, "%.*s", (int)widths[i], row[i] ? row[i] : "0");
					  *((double *)(base + DatInf[i].off)) = atof(scratch);
					  break;
				  default:
					  SLERROR("ERROR: invalid data description for field #%d\n", i);
			     }
		     }
		  o->Compile();
	     }
	  else {
		  free(o);
		  o = NULL;
	     }
	  return o;
     };

protected:
  char * sql;
  MYSQL_RES *res;
  int numfields;

  class cDataInfo {
  public:
	  enum DATATYPES {
		    UNKNOWN
        , TEXT
	     , INTEGER
        , DECIMAL
        } type;
     int  off;
     };	 

  bool Init() {_
	  if(!sql) return false;
	  if(mysql_query(XmsSetup.DbHandle(), sql)) {
		  SLERROR("Error on query - %s\n", mysql_error(XmsSetup.DbHandle()));
	     }
	  else {
		  res = mysql_store_result(XmsSetup.DbHandle());
		  if(res) numfields = mysql_num_fields(res);
		  return true;
	     }
	  return false;
     };
  }; 

#endif
