/*
    stmtrel.h

    Copyright (c) 1995, by picoSoft
    ALL RIGHTS RESERVED.

    Revision History:
    -----------------
*/

# ifndef stmtrel_h
# define stmtrel_h "$Id: stmtrel.h 5.1 2001/03/14 11:28:29 picoSoft Exp Marco $"

# include "pstring.h"
# include "piteratr.h"
# include "relation.h" 
# include "attribut.h"
# include "stmtattr.h"
# include "conditn.h"
# include "serchidx.h"
# include "where.h"
extern "C" {
# include <string.h>
}
# include "blob.h"
class SqlParser;
class Relation;
class OrdCriteriaCopyList;
class DataBase;
class ExpressionList;

class StmtRel : public PObject
{
friend class SearchIndex;
   PCLASS(StmtRel, PObject)
   PString       Name;
   char         *Buffer;
   Relation     *Rel;
   PBool          FsOpen;      /* Flag di apertura */
   accessType    FsId; 
   SearchIndex   *CurrIndex;
   int           isStatus;
   StmtAttrList  Fields;
   unsigned short Order;
   void init(Relation *r);
   SearchIndexList Indexes;
   OrdCriteriaCopyList *OrderBy;
   OrdCriteriaCopyList *GroupBy;
   DataBase &DB;
   void DefineOrderGroup (OrderItemCopyList &o, PBool dups,
                          OrdCriteriaCopyList **occl);
   BlobFile *bFile;
public:
   // O^O oj
   PString join;
   Where *joinCond;
   PBool leftJoin;
   PBool foundJoin;
   PBool EvalJoin() {
      PBool Return = PTrue;
      if (joinCond != 0)
         joinCond->Eval(this, Return);
      return Return;
   }
   // O^O oj end
   StmtRel (DataBase &d) : DB(d) { init (0); }
   StmtRel (Relation &r) : DB(*(r.getParent())) { init(&r);
                          Name = r.getName();
                        }
   StmtRel (Relation &r, const PString & n) : DB(*(r.getParent())) {
                         init(&r);
                         if (n.size() == 0)
                            Name = Rel->getName();
                         else
                            Name = n;
                         }
   ~StmtRel ();
   void DeleteRel();
   void  setName (const PString &n) { Name = n; }
   const PString & getName () const { return Name; }
   StmtAttr * getByName (const PString &s);
   Relation * getRel() { if (this != 0)
                            return Rel;
                         else
                            return 0; } 
   char * getBuffer() { return Buffer; }
   void SetRel (StmtAttrList &sal, DataBase &d);
   void SetRel ();
   void BufferStmtRelAlloc();
   PBool isOpen () { return FsOpen; }
   Error Create ();
   Error Drop();
   Error Rename(char *newName);
   Error Open ();
   Error Write ();
   Error Start () { if (CurrIndex)
                       CurrIndex->AttrsAndCond.GetFirst();
                    // memset (Buffer, '\0', Rel->GetBufferLen());
                    Clear ();
                    return StartNext();
                  }
   Error PrevStart () { if (CurrIndex)
                           CurrIndex->AttrsAndCond.GetLast();
                        // memset (Buffer, '\xFF', Rel->GetBufferLen());
                        setHighValue ();
                        return StartPrev();
                      }
   Error StartNext();
   Error StartPrev();
   Error ReadNext (PBool lock) {
      return ReadNext (lock, PTrue);
   }
   Error ReadNext (PBool lock, PBool readBlob);
   Error ReadPrev (PBool lock);
   Error Erase ();
   Error DelCurrent ();
   Error UpdCurrent ();
   Error Replace ();
   void Close (PBool unloadCache = PFalse);
   Error ShareOpen (StmtRel *sr);
   void ShareClose();
   void ChooseIndex (SqlParser &p);
   Error AddIndexFile(SearchIndex &idx);
   void setBlob () {
      if (bFile == 0)
         bFile = new BlobFile (Rel->getFsDirName (), Rel->getFsDataName());
   }
   PBool hasBlob() {
      return bFile != 0;
   }
   BlobFile *getBlob () {
      return bFile;
   }
   short  getRelCond(); 
   PString  getRelCondWhere();
   Error GetCursorName (PString &cursorName);
   void AddIndex (SearchIndex *i) { Indexes.AddItem (i); }
   int getIndexesNum() { return (int) Indexes.GetItemNum(); }
   void DefineOrderBy (OrderItemCopyList &o, PBool dups)
        { DefineOrderGroup (o, dups, &OrderBy); } 
   void DefineGroupBy (OrderItemCopyList &o, PBool dups)
        { DefineOrderGroup (o, dups, &GroupBy); }
   
   void SetCurrIndex (SearchIndex *si) { CurrIndex = si; }
   void SortIndexes(void);
   Error CalcAggregate (StmtRel &v);
   void AddField (StmtAttr *sa) { Fields.AddItem (sa); } 
   StmtAttr * GetFirstField() {
      StmtAttr *Return;
      for (Return = Fields.GetFirst();
           Return && (Return->getAttr()->GetVisibility() & ATTR_HIDDEN);
           Return = Fields.GetNext())
         ;
      return Return;
   }
   StmtAttr * GetNextField() {
      StmtAttr *Return;
      for (Return = Fields.GetNext();
           Return && (Return->getAttr()->GetVisibility() & ATTR_HIDDEN);
           Return = Fields.GetNext())
         ;
      return Return;
   }  
   StmtAttr * GetFieldAt(int i) { return Fields.GetAt(i); } 
   SearchIndex *getCurrIndex() { return CurrIndex; } 
   void setCurrIndex(SearchIndex *i) { CurrIndex = i; }
   int getStatus () const { return isStatus; }
   void setStatus (int e) { isStatus = e; }
   accessType getFsId() { return FsId; }
   void Clear();
   void setHighValue ();
   void SetOrder (unsigned short i) { Order = i; }
   unsigned int getOrder () const { return Order; }
   void FillBuffer(StmtAttrList &, unsigned long count = 0L);
   void FillBuffer(ExpressionList &al, unsigned long count = 0L);
   StmtAttr * AddNewField (StmtAttr *sa, const PString *name);
   StmtAttr * AddNewInvis (StmtAttr *sa);
   void ReloadRelation(SqlParser *p);
   Error writeBlobs ();
   Error unwriteBlobs ();
   Error readBlobs ();
   Error rewriteBlobs ();
   Error removeBlobs ();
   void setBlobFile ();
};

PLIST(StmtRel);
PITERATOR(StmtRel);
# endif 
