/* Klaus Thiele (kth@oblib.teuto.de) - June '95 */
/*
INTERFACE TO
  mSQL
REVISION HISTORY
  07/10/95 API release 1.00
DESCRIPTION
  mSqlBase/mSqlCursor class definition
*/

#ifndef SQL_PRIV
#define SQL_PRIV

#include <fstream.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>

#include <msql.h>

typedef enum {
    SELECT,
    INSERT,
    UPDATE,
    DELETE,
    CREATE,
    DROP
} sqlcmd_t;

typedef int    bool;
#define FALSE  0
#define TRUE   1

const NAME_LEN         =    20;  // from msql_priv.h
const BINDVAR_LEN      =    32;

const MAX_CONN         =    10;
const MAX_CURSORS      =    20;
const MAX_BIND_VARS    =    40;
const MAX_STMT_SIZE    = 10240;

const SQLTPTY START_SRS = 100;
const SQLTPTY END_SRS   = 101;

typedef struct _Fld {
   char name[NAME_LEN+1];
   int  typ;
   int  length;
   int  nr;
   void *var_data;
   int  var_length;
   int  var_typ;
   unsigned char *cvl;
   unsigned char *flags;
} Fld;

typedef struct _Bnd {
   char name[BINDVAR_LEN+1];
   void *bnd_data;
   int  bnd_length;
   int  bnd_typ;
} Bnd;

typedef struct _CsrFlags {
   bool          compiled;            // command compiled TRUE/FALSE
   bool          executed;            // command executed TRUE/FALSE
   bool          rsetMode;            // result set mode
   unsigned char nullInd;             // null indicator
} CsrFlags;

typedef struct _Connection {
   int sockDesc;
   int useCount;
   char *host;
} Connection;

class mSqlBase;                       // forward declaration

extern char msqlErrMsg[];

//
// mSqlCursor Class
//
class mSqlCursor {

   private:
      static unsigned long staticID;
      unsigned long myID;

      int      sockDesc;              // socket descriptor
      char     *database;             // database
      char     *statement;            // SQL statement

      m_result *fieldResult;          // field result-set
      m_result *dataResult;           // data result-set

      Fld      **fields;              // field list
      Bnd      *binds[MAX_BIND_VARS]; // bind vars

      int      numSelItems;           // number of select items
      int      numBndVars;            // number of bind variables

      sqlcmd_t sqlcmd;                // type of command
      CsrFlags flag;                  // various flags

      SQLTRCD  lastRc;                // last returncode

      void cleanUp();
      void upperStr(char *s);
      int  setUpdateVars( char *s, char *e );

   public:
      mSqlCursor(char *dbase, int len, int sd);
      ~mSqlCursor();
      int Compile(char *stmt, int len);
      int BindName(char *bvar, int len, void *vaddr, int vlen, int vart);
      int BindNum(int nvar, void *vaddr, int vlen, int vart);
      int SetSelectBuf(int slc, int pdt, void *pbp, int pdl,
                       unsigned char *cvl, unsigned char *pfc);
      int Execute( void );
      int Fetch( void );
      int SetRowPos( SQLTROW row );
      int getNumSelItems( SQLTNSI PTR nsi );
      int getNumBndVars( SQLTNBV PTR nbv );
      int getNumRows( SQLTROW PTR rcountp );
      int getCmdType( SQLTCTY PTR cty );
      int describeItem(SQLTSLC slc, SQLTDDT PTR edt, SQLTDDL PTR edl, SQLTCHP chp, SQLTCHL PTR chlp);
      int describeItem(SQLTSLC slc, SQLTDDT PTR ddt, SQLTDDL PTR ddl, SQLTCHP chp, SQLTCHL PTR chlp, char *dummy);
      int GetParm( SQLTPTY parm, SQLTDAP p );
      int SetParm( SQLTPTY parm, SQLTDAP p );
      int ListTables( char *buffer, int length );
      int ClearBindVars( void );
      void RetCode( SQLTRCD PTR rcd ) {
              *rcd = lastRc;
      }
      void Reset( void ) {
              if( statement ) delete[] statement;
              statement = NULL;
              cleanUp();
      }
      const char *getDbaseName( void ) {
              return( database );
      }
      const int getSockDesc( void ) {
              return( sockDesc );
      }

};

//
// mSqlBase class
//
class mSqlBase {

 private:
   Connection connection[MAX_CONN];                    // array connections
   mSqlCursor *cursor[MAX_CURSORS];                    // ptr-array cursors

   int connectServer( char *host, int *rc );           // connect to server
   int disconnectServer( int sd );                     // disconnect from server
   int add( mSqlCursor *element );                     // add new cursor

 public:
   mSqlBase();                                         // constructor
   ~mSqlBase();                                        // destructor

   int createCursor( char *host, char* dbase, int len, int *rc );  // create cursor
   int deleteCursor( int cur );                                    // delete cursor

   mSqlCursor *operator[]( int index ) {               // operator [] overloading
      if( index > MAX_CURSORS || index < 0 )
         return NULL;
      return cursor[index];
   }

};

#endif
