/*****************************************************************************/
/*                                                                           */
/*                           OCO SOURCE MATERIALS                            */
/*                             IBM CONFIDENTIAL                              */
/*                                    OR                                     */
/*                        IBM CONFIDENTIAL RESTRICTED                        */
/*            WHEN COMBINED WITH THE AGGREGATED OCO SOURCE MODULES           */
/*                           FOR THIS PROGRAM PRODUCT                        */
/*                                                                           */
/*      VisualAge Generator Server for OS/2, AIX, HP-UX, and Windows NT      */
/*                          Version 3.1  5697-C28                            */
/*                    (C) COPYRIGHT IBM CORP. 1994,1998                      */
/*                                                                           */
/*****************************************************************************/
/* ************************************************************************* */
/*    Date      Userid          Description of problem                       */
/*                                                                           */
/*  11/10/98    dewittsc        PQ20911 - Handle VARCHARs correctly          */
/*  07/18/00    dewittsc        PQ38022 - Handle LIKE predicate correctly    */
/*                                                                           */
/* ************************************************************************* */

#ifndef  FCWMSQR_H
#define  FCWMSQR_H

#include <fcwcsql.h>
#include <fcwmsgno.h>

class Item;

// --------------------------------------------------------------------
//         SQL Host variable parameter entry ( equivalent to SQLDA )
// --------------------------------------------------------------------
struct HVENTRY {
     short    Type;
     short    Precision;
     short    Scale;
     unsigned char *pData;
     short    *pNullInd;                          // nid in data item
     void     *pObj;
     Bool     SQLVarChar;
     short    *pNullSrc;                          // nid in generated src
};

class HVLIST {
   public:
     HVLIST( short n );
     ~HVLIST();
     void StoreDA( short, Item&, short, short, short, unsigned char*, short *, Bool );
     void SetHostVar( short, AHVPTR, AHVPTR );
     unsigned char* GetEntryData( short idx );
     void FixupBindCols();

   private:
     short     MaxNumHv;
     short     NumInUse;
     HVENTRY   *pEntry;
};

// --------------------------------------------------------------------
//         FCW level of SQL statement handle
// --------------------------------------------------------------------
class SQLStmt {

  public:
    SQLStmt( short, short, short, short, short );
    ~SQLStmt();
    Bool CursorIsOpen();
    Bool ParmWasSet();
    Bool ColWasBind();
    Bool IsDynamic();
    void SetParmStatus();
    void SetBindColStatus();
    void SetParm( short, Item&, Bool, Bool, Bool );          // PQ20911,PQ38022
    void BindCol( short, Item&, Bool );
    void SetHostVar( short, AHVPTR, AHVPTR );
    void BindHostVar( short, AHVPTR, AHVPTR );
    void ResetCursor();
    short StmtID();
    void FixupBindCols();
    Bool GetCursorDef();
    double New_atof( char* );                                // PN91982

  private:
    short           Id1;                   // primary statement id
    short           Id2;                   // secondary statement id
    short           Option;                // statement exec option
    short           Operation;             // Process Option
    Bool            StatusSetParm;         // Status for SetParm
    Bool            StatusBindCol;         // status for BindCol
    Bool            NeedPrep;              // statement needs PREPARE flag
    Bool            CursorStatus;          // indicator for cursor use
    HVLIST          *pIHvLst;              // For SetParm
    HVLIST          *pOHvLst;              // For BindCol on SELECT statement
    void            *pImpData;             // implementation data
};

// --------------------------------------------------------------------
//                     SQL row interface
// Usage: an APP object contains one or more SQLROWs which are based
//        on MSQLRecord
// --------------------------------------------------------------------

class MSQLRecord : public Record
{
  public:
           MSQLRecord( char*, long l );
          ~MSQLRecord();

     void Setup( void* = 0 );
     int  BeginAdd( short stmtID, short opt, short ida, short oda );
     int  EndAdd( void * );
     int  BeginInq( short stmtID, short opt, short ida, short oda );
     int  EndInq( void * );
     int  BeginUpd( short stmtID, short opt, short ida, short oda );
     int  EndUpd( void * );
     int  BeginRep( short stmtID, short opt, short ida, short oda );
     int  EndRep( void * );
     int  BeginDel( short stmtID, short opt, short ida, short oda );
     int  EndDel( void * );
     int  BeginSetInq( short stmtID, short opt, short ida, short oda );
     int  EndSetInq( void * );
     int  BeginScan( short stmtID, short opt, short ida, short oda );
     int  EndScan( void* );
     int  BeginSetUpd( short stmtID, short opt, short ida, short oda );
     int  EndSetUpd( void* );
     int  BeginSQLExec( short stmtID, short opt, short ida, short oda );
     int  EndSQLExec( void* );

     int  BeginCloseCursor();
     int  EndCloseCursor( void * );

     int  BeginPrcOpt( short stmtID, short opr, short opt, short ida, short oda );
     int  EndPrcOpt( short,  void *, int );

     int  Close( short opt = 0 );
     virtual void CloseCursor() {};

     int  StmtInit( short StmtID, short Opr, short Opt, short ida, short oda );
     void StmtFree();

     int  SetParm( unsigned short ParmNum,     // setup hostvars for WHERE
                   AHVPTR pHv, AHVPTR pNid,
                   Item&  Dte,
                   short  SQLType );

     int  SetParm( unsigned short ParmNum,     // PQ38022
                   AHVPTR pHv, AHVPTR pNid,    // setup hostvars for WHERE
                   Item&  Dte,                 // include hostvar context info
                   short  SQLType,
                   Bool   SQLVarInLike );


     int  BindCol( unsigned short ParmNum,
                   AHVPTR pHv, AHVPTR pNid,
                   Item& Dte, short SQLType );

     void CheckDBIOError( void* pCA, int msgno );

     void CheckAssociation( short id, char* procName );

     short GetCursorID();
     void  SetCursorID( short );
     void  EndAppOnInvalidCursorID();
     SQLStmt* FindStmtWithCursorID( short id );

     int  Err() { return IOStatus; };                          /*D8295*/
     int  Hrd() { return IOStatus & rcHRD; };
     int  Nrf() { return IOStatus & rcNRF; };
     int  Dup() { return IOStatus & rcDUP; };
     int  Ded() { return IOStatus & rcDED; };
     int  Unq() { return IOStatus & rcUNQ; };

     int  Lok() { return 0; };               // followings not supported by SQL:
     int  Eof() { return 0; };               //     always return False!!!
     int  Ful() { return 0; };
     int  Fmt() { return 0; };
     int  Fnf() { return 0; };
     int  Fna() { return 0; };

     void SetupRpc();

     void CloseOnCommit();                    // reset cursor on LUW
     void CloseOnRollback();
     char*  Name() { return recName;} ;       // return name of SQL row  @0001

     int  ErrorDueToOpenCursor( int );        // retry if cursor already open
                                              //                      <DUOW>
   private:
     FCWString       recName;                 // name of SQL row         @0001
     unsigned short  IOStatus;                // rc for last operation
     short           LastOpr;                 // last record operation
     void*           pSQLCA;                  // ptr to SQLCA

     CmnSQLItf       *pSQLDrv;                // ptr to SQL driver object

     short           IdxCursor;               // index for current cursor
     Bool            CursorWithHold;          // whether cursor is WITH HOLD
     SQLStmt*        CurrStmt;                // current FCW statement handle
     SQLStmt*        LastStmtSet;             // last FCW statement set
     LIST (SQLStmt*) LStmts;                  // list of SQL statement handles

     void*           pImpData;                // internal implementation
     Bool SQLTypeIsActualVarLenChar( short ); // PQ20911
};

// --------------------------------------------------------------------
//   inlines for MSQLRecord
// --------------------------------------------------------------------

inline
int MSQLRecord :: BeginAdd( short id, short opt, short ida, short oda )
{
    return( BeginPrcOpt( id, ADD_OPR, opt, ida, oda ) );
};

inline
int MSQLRecord :: EndAdd( void *pCA )
{
    return( EndPrcOpt( ADD_OPR, pCA, ERRMSG_SQL_IO ) );
};

inline
int MSQLRecord :: BeginSQLExec( short id, short opt, short ida, short oda )
{
    return( BeginPrcOpt( id, SQLEXEC_OPR, opt, ida, oda ) );
};

inline
int MSQLRecord :: EndSQLExec( void *pCA )
{
    return( EndPrcOpt( SQLEXEC_OPR, pCA, ERRMSG_SQL_IO ) );
};

inline
int MSQLRecord :: BeginInq( short id, short opt, short ida, short oda )
{
    return( BeginPrcOpt( id, INQUIRY_OPR, opt, ida, oda ) );
};

inline
int MSQLRecord :: BeginSetInq( short id, short opt, short ida, short oda )
{
    return( BeginPrcOpt( id, SETINQ_OPR, opt, ida, oda ) );
};

inline
int MSQLRecord :: BeginSetUpd( short id, short opt, short ida, short oda )
{
    return( BeginPrcOpt( id, SETUPD_OPR, opt, ida, oda ) );
};

inline
int MSQLRecord :: BeginUpd( short id, short opt, short ida, short oda )
{
    return( BeginPrcOpt( id, UPDATE_OPR, opt, ida, oda ) );
};

// -------------------------------------------------------------------
//  Function:  Dummy SQL row for SQLEXEC process option without
//             a process object
// -------------------------------------------------------------------
struct rcdEZESQR : public MSQLRecord
{
   rcdEZESQR() : MSQLRecord( "EZESQR_", 0 ) {};
};

struct STROpenCursor {                    // structure for open cursor  @0001
   FCWString     appName;
   FCWString     recName;
   short         iCursor;
   Bool          cursorType;
};


// --------------------------------------------------------------------
//               Database object interface
// Usage  :  RU contains a DBMOBJ
// --------------------------------------------------------------------
class MDBOBJ : public FCWDBOBJ                                 // ODBC
{
  public:
                MDBOBJ( InitValue );
               ~MDBOBJ();
    int         StartDBM();                  // start DBM
    int         DftDBConnect( void* pCA );   // connect to database
    int         EZEConnect( char* id, char* psw, char* dbname, char* product,
                            char* release, char* uow, void* pCA );  /* DUOW*/
    int         Commit( int option );
    int         RollBack( int option );
    int         Close( char opt );           // close cursors for SQL rows
    void*       Register( void *p );         // associated row to DB object
    int         DeRegister( void *p );       // release row from DB object
    int         Bind( char* dbname, void* pCA );

    FCWString   GetProduct( void* pCA );
    FCWString   GetRelease( void* pCA );

    CmnSQLItf* GetDrv();
                                                                    // @0001
    void SaveOpenCursor( char* App, char* Rec, short CursorID, Bool bWithHold );
    void GetOpenCursor( char* App, char* Rec, short& cursor, Bool& bWithHold );

    void SetIO( Bool f );                       // Set I/O flag
    Bool IOPending();                           // Return I/O flag

    int  SwitchSFDB ( SFDBValue newDB );        // Switch database   @PQ01395

    InitValue  DbmType();                       // DB2 or ODBC    <ODBC>

    Bool FileSystemIsManagedByDB2();            // PQ01395
    void SetDBNameForNextSQLIO( char* n );

    Bool DriverExists();                        // PQ19733

  private:
    CmnSQLItf *pSQLDrv;                         // ptr to SQL driver object
    FCWString  DBName;                          // database name
    FCWString  DBDrvName;                       // database driver name
    LIST  (MSQLRecord*) LSQLRows;               // List of SQL row objects

    LIST  (STROpenCursor *) LOpenCursors;       // List of Open cursors  @0001

    Bool  ioFlag;                               // Database I/O indicator

                                                //       PQ01395
    short       dbVersion;                      // Database version, 1, 2 ...
    FCWString   sqlDBName;                      // Database for SQL I/O
    FCWString   fileDBName;                     // Database for File I/O
    Bool        sfDBstate;                      // True if (fileDBName + sqlDBName) defined  flag
                                                // False,  otherwise.
    InitValue   dbType;                         // DB2 or Oracle?

    void  *pImpData;                            // Internal data
};


// ----------------------------------------------------------------------
//    Structure for SQL variable length character columns
// ----------------------------------------------------------------------
struct VARITM {
   short         len;
   unsigned char data[1];
};

//typedef struct VARITM VARCHAR;

struct WARITM {
   short         len;
   wchar_t       data[1];
};

//typedef struct WARITM WARCHAR;

#endif
