/*
_____       _    _    Corso   Italia,  178
(_|__   .  (_   |_|_  56125           Pisa
(_|_) |)|(()_)()| |   tel.  +39  050 46380
  |   |               picosoft@picosoft.it

 Copyright (C) Picosoft s.r.l. 1995-2002

 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 2, 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, write to the Free Software
 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*/
# ifndef relation_h
# define relation_h "$Id: relation.h 5.0 1999/10/08 10:17:43 picoSoft Exp $"

# include "relobjec.h" 
# include "attribut.h"
# include "stmtattr.h"
# include "conditn.h"
# include "lex.h"
# include "sort.h"

class StmtRel;

class RelBase : public RelObject
{
   PCLASS(RelBase, PObject)
protected:
   PString       FsDirName;
   PString       FsDataName; 
   tFileType     FileType;
   long          BufferLen;
   long          MinRecordLen;
   long          MaxRecordLen;
   long          RealRecordLen;
   short         FsKeyNum;
   PString       XfdName;
   short         relCond;
   tRelationType RelationType;
   enum {
      PF_NEVER_OPEN,
      PF_EXISTS,
      PF_NOT_EXISTS
   } PhisicFile;
   char *Collating; 
public:
   RelBase (const char *, DataBase &p);
   RelBase (RelBase &rb);
   ~RelBase();
   PBool FileOpenExists ( accessType *fd = 0 );
   virtual PBool Exists () { return FileOpenExists(); }
   void setDirName(const char * dirName) {FsDirName = dirName;}
   void setFileName(const char * fileName) {
      FsDataName = fileName;
   }
   tRelationType getRelationType () { return RelationType; }
   void setFileType(char type) {FileType = (enum ftipo) type;};
   tFileType getFileType () { return FileType; }
   void setMinRecordLen (long l) { MinRecordLen = l; }
   void setMaxRecordLen (long l) { MaxRecordLen = l; }
   void setRealRecordLen (long l) { RealRecordLen = l; }     
   long getMinRecordLen () { return MinRecordLen; }
   long getMaxRecordLen () { return MaxRecordLen; }
   long getRealRecordLen () { return RealRecordLen; }
   void Debug();
   const PString & getFsDirName () const { return FsDirName; }
   const PString & getFsDataName () const { return FsDataName; }
   void          setRelCond(short c) { relCond = c; }
   short         getRelCond() { return relCond; }
   void setCollating(char *coll);
   unsigned char * getCollating() { return (unsigned char*) Collating; }
   PBool IsNeverOpen () { return PhisicFile == PF_NEVER_OPEN; }
   PBool IsExistant () { return PhisicFile == PF_EXISTS; }
   PBool IsNotExistant () { return PhisicFile == PF_NOT_EXISTS; }
   void SetExistant () { PhisicFile = PF_EXISTS; }
   void SetNotExistant () { PhisicFile = PF_NOT_EXISTS; }
};

PLIST(RelBase);
PITERATOR(RelBase);

class Relation : public RelBase
{
// friend class StmtRel;

   PCLASS(Relation, RelBase)

   PBool CheckFormat (Lex &l, int linea);
   void Get1Param (Lex &l, int &dim, int linea);
   void Get2Param (Lex &l, int &dim, int &decimals, int linea);
   AttributeList AllAttrs;
   AttributeList VisAttrs;
   RelBase *base;
public: 
   Error ReadFields(StmtRel *);
   Relation (const char *d, DataBase &p) : RelBase(d, p) { base = 0; }
   Relation (RelBase &rb) : RelBase(rb) { base = &rb; }
   Relation (Relation &);
   Relation (StmtAttrList &, DataBase &p);
   Relation (DataBase &p);
   ~Relation ();
   void BufferCalc();  
   Attribute * AddVisible (StmtAttr *sa);   
   Attribute * AddInvis (StmtAttr *sa);   
   Attribute * AddInvis (Attribute *a);  
   void SetInvis (Attribute *a);
   // void Clear ()
   Error ReadSpf();
   long GetBufferLen () { return BufferLen; }
   long GetFieldNum () { return VisAttrs.GetItemNum(); }
   Attribute * GetFieldAt (int i) { return VisAttrs.GetAt(i); }
   int GetNumRecords (long *numRecords);
   AttributeList &getAllAttrs() { return AllAttrs; }
   AttributeList &getVisAttrs() { return VisAttrs; }
   void setName (const char *s) {
      RelObject::setName(s);
      if (base)
         base->setName(s);
   }
   void setFileName(const char * fileName) {
      RelBase::setFileName(fileName);
      if (base)
         base->setFileName(fileName);
   }
};

PLIST(Relation);

# endif
