Xbase64 Class Library  3.1.2
xbdbf.h
Go to the documentation of this file.
00001 /*  xbdbf.h
00002 
00003     Xbase64 project source code
00004 
00005     This file contains the Class definition for a xbDBF object.
00006 
00007     Copyright (C) 1997,2003  Gary A Kunkel
00008     
00009     This program is free software; you can redistribute it and/or modify
00010     it under the terms of the GNU Lesser General Public License as published by
00011     the Free Software Foundation; either version 2 of the License, or
00012     (at your option) any later version.
00013 
00014     This program is distributed in the hope that it will be useful,
00015     but WITHOUT ANY WARRANTY; without even the implied warranty of
00016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017     GNU Lesser General Public License for more details.
00018 
00019     You should have received a copy of the GNU Lesser General Public License
00020     along with this program; if not, write to the Free Software
00021     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022 
00023 
00024     Contact:
00025     
00026      Email:
00027     
00028       xdb-devel@lists.sourceforge.net
00029       xdb-users@lists.sourceforge.net
00030       
00031       
00032      Regular Mail:
00033      
00034        XBase Support
00035        149C South Main St
00036        Keller Texas, 76248     
00037        USA
00038 
00039 */
00040 
00041 #ifndef __XB_DBF_H__
00042 #define __XB_DBF_H__
00043 
00044 #ifdef __GNU_LesserG__
00045 #pragma interface
00046 #endif
00047 
00048 #ifdef __WIN32__
00049 #include <xbase64/xbwincfg.h>
00050 #else
00051 #include <xbase64/xbconfig.h>
00052 #endif
00053 
00054 #include <xbase64/xbtypes.h>
00055 #include <xbase64/xbdate.h>
00056 #include <xbase64/xbfile.h>
00057 
00058 #include <iostream>
00059 #include <stdio.h>
00060 
00064 #if defined(XB_INDEX_ANY)
00065    class XBDLLEXPORT xbIndex;
00066    class XBDLLEXPORT xbNdx;
00067    class XBDLLEXPORT xbNtx;
00068 #endif
00069 
00070 /*****************************/
00071 /* Field Types               */
00072 
00073 #define XB_CHAR_FLD      'C'
00074 #define XB_LOGICAL_FLD   'L'
00075 #define XB_NUMERIC_FLD   'N'
00076 #define XB_DATE_FLD      'D'
00077 #define XB_MEMO_FLD      'M'
00078 #define XB_FLOAT_FLD     'F'
00079 
00080 /*****************************/
00081 /* File Status Codes         */
00082 
00083 #define XB_CLOSED  0
00084 #define XB_OPEN    1
00085 #define XB_UPDATED 2
00086 
00087 /*****************************/
00088 /* Other defines             */
00089 
00090 #define XB_OVERLAY     1
00091 #define XB_DONTOVERLAY 0
00092 
00093 #define XB_CHAREOF  '\x1A'         /* end of DBF        */
00094 #define XB_CHARHDR  '\x0D'         /* header terminator */
00095 
00097 
00130 struct XBDLLEXPORT xbSchema {
00131   char      FieldName[11];
00132   char      Type;
00133 // xbUShort  FieldLen;       /* does not work */
00134 // xbUShort  NoOfDecs;       /* does not work */
00135   unsigned  char FieldLen;  /* fields are stored as one byte on record*/
00136   unsigned  char NoOfDecs;
00137 };
00138 
00140 
00143 struct XBDLLEXPORT xbSchemaRec {
00144   char     FieldName[11];
00145   char     Type;            /* field type */
00146   char     *Address;        /* pointer to field in record buffer 1 */
00147 // xbUShort FieldLen;        /* does not work */
00148 // xbUShort NoOfDecs;        /* does not work */
00149   unsigned char FieldLen;   /* fields are stored as one byte on record */
00150   unsigned char NoOfDecs;
00151   char     *Address2;       /* pointer to field in record buffer 2 */
00152   char     *fp;             /* pointer to null terminated buffer for field */
00153                              /* see method GetString */
00154   xbShort  LongFieldLen;    /* to handle long field lengths */
00155 };
00156 
00158 
00161 struct XBDLLEXPORT xbIxList {
00162   xbIxList * NextIx;
00163   xbString IxName;
00164 #if defined(XB_INDEX_ANY)
00165   xbIndex  * index;
00166   xbShort  Unique;
00167   xbShort  KeyUpdated;
00168 #endif
00169 };
00170 
00172 
00176 #ifdef XB_MEMO_FIELDS
00177 struct XBDLLEXPORT xbMH{                      /* memo header                    */
00178   xbLong  NextBlock;             /* pointer to next block to write */
00179   char    FileName[8];           /* name of dbt file               */
00180   char    Version;               /* not sure                       */
00181   xbShort BlockSize;             /* memo file block size           */
00182 };
00183 #endif
00184 
00186 
00190 class XBDLLEXPORT xbDbf : protected xbFile{
00191 
00192 public:
00193   xbDbf( xbXBase * );
00194   virtual ~xbDbf();
00195 
00196   xbXBase  *xbase;               /* linkage to main base class */
00197 
00198 /* datafile methods */
00199 #if defined(XB_INDEX_ANY)
00200   xbShort   AddIndexToIxList(xbIndex *, const char *IndexName);
00201   xbShort   RemoveIndexFromIxList( xbIndex * );
00202 #endif
00203   xbShort   AppendRecord();
00204   xbShort   BlankRecord();
00205   xbShort   CloseDatabase( xbBool deleteIndexes = 0 );
00206   xbShort   CopyDbfStructure( const char *, xbShort );
00207   xbShort   CreateDatabase( const char * Name, xbSchema *, xbShort Overlay );
00209 
00211   xbShort   DeleteAllRecords() { return DeleteAll(0); }
00212   xbShort   DeleteRecord();
00213 #ifdef XBASE_DEBUG
00214   xbShort   DumpHeader( xbShort );
00215 #endif
00216   xbShort   DumpRecord( xbULong );
00218 
00220   xbLong    FieldCount() { return NoOfFields; }
00222 
00224   const xbString& GetDbfName() { return GetFileName(); }
00226 
00228   xbShort   GetDbfStatus() { return DbfStatus; }
00229   xbShort   GetFirstRecord();
00230   xbShort   GetLastRecord();
00231   xbShort   GetNextRecord();
00232   xbShort   GetPrevRecord();
00234 
00236   xbLong    GetCurRecNo() { return CurRec; }
00237   xbShort   GetRecord( xbULong );
00239 
00241   char *    GetRecordBuf() { return RecBuf; }
00243 
00245   xbShort   GetRecordLen() { return RecordLen; }
00246   xbShort   NameSuffixMissing( xbShort, const char * );
00247   xbLong    GetRecCnt() { return NoOfRecords(); }
00248   xbLong    NoOfRecords();
00249   xbLong    PhysicalNoOfRecords();
00250   xbShort   OpenDatabase( const char * );
00251   xbShort   PackDatabase(xbShort LockWaitOption,
00252         void (*packStatusFunc)(xbLong itemNum, xbLong numItems) = 0,
00253         void (*indexStatusFunc)(xbLong itemNum, xbLong numItems) = 0);
00254   xbShort   PutRecord(); // Put record to current position
00255   xbShort   PutRecord(xbULong);
00256   xbShort   RebuildAllIndices(
00257       void (*statusFunc)(xbLong itemNum, xbLong numItems) = 0);
00258   xbShort   RecordDeleted();
00260 
00262   void      ResetNoOfRecs() { NoOfRecs = 0L; }
00263   xbShort   SetVersion( xbShort );
00265 
00267   xbShort   UndeleteAllRecords() { return DeleteAll(1); }
00268   xbShort   UndeleteRecord();
00269   xbShort   Zap( xbShort );
00270 
00271 /* field methods */
00272   const char *GetField(xbShort FieldNo) const; // Using internal static buffer
00273   const char *GetField(const char *Name) const;
00274   xbShort   GetField( xbShort FieldNo, char *Buf) const;
00275   xbShort   GetRawField( xbShort FieldNo, char *Buf) const;
00276   xbShort   GetField( xbShort FieldNo, char *Buf, xbShort RecBufSw) const;
00277   xbShort   GetField( const char *Name, char *Buf) const;
00278   xbShort   GetRawField(const char *Name, char *Buf) const;
00279   xbShort   GetField( const char *Name, char *Buf, xbShort RecBufSw) const;
00280   xbShort   GetField(xbShort FieldNo, xbString&, xbShort RecBufSw ) const;
00281   xbShort   GetFieldDecimal( xbShort );
00282   xbShort   GetFieldLen( xbShort );
00283   char *    GetFieldName( xbShort );
00284   xbShort   GetFieldNo( const char * FieldName ) const;
00285   char      GetFieldType( xbShort FieldNo ) const;
00286   xbShort   GetLogicalField( xbShort FieldNo );
00287   xbShort   GetLogicalField( const char * FieldName );
00288   char *    GetStringField( xbShort FieldNo );
00289   char *    GetStringField( const char * FieldName );
00290   xbShort   PutField( xbShort, const char * );
00291   xbShort   PutRawField( xbShort FieldNo, const char *buf );
00292   xbShort   PutField( const char *Name, const char *buf);
00293   xbShort   PutRawField( const char *Name, const char *buf );
00294   xbShort   ValidLogicalData( const char * );
00295   xbShort   ValidNumericData( const char * );
00296 
00297   xbLong    GetLongField( const char *FieldName) const;
00298   xbLong    GetLongField( const xbShort FieldNo) const;
00299   xbShort   PutLongField( const xbShort, const xbLong );
00300   xbShort   PutLongField( const char *, const xbLong);
00301 
00302   xbFloat   GetFloatField( const char * FieldName );
00303   xbFloat   GetFloatField( xbShort FieldNo );
00304   xbShort   PutFloatField( const char *, const xbFloat);
00305   xbShort   PutFloatField( const xbShort, const xbFloat);
00306 
00307   xbDouble  GetDoubleField( const char *);
00308   xbDouble  GetDoubleField( xbShort, xbShort RecBufSw = 0);
00309   xbShort   PutDoubleField( const char *, xbDouble);
00310   xbShort   PutDoubleField( const xbShort, xbDouble);
00311 
00312 #ifdef XB_LOCKING_ON
00313   xbShort   GetLockMode() { return LockMode; }
00314   xbShort   SetLockMode( xbShort );
00315 //  xbShort   OpenXbLockFile();
00316 //  xbShort   GetTableLockCnt() { return TableLockCnt; }
00317 //  xbShort   LockIndex( xbShort LockType );    /* for XB_XBASE_LOCK_MODE */
00318   int       GetDbfFileNo() { return fileno( fp ); }
00319   int       GetMemoFileNo() { return fileno( mfp ); }
00320 
00321 #ifdef XB_MEMO_FIELDS
00322 //  xbShort   GetMemoLockCnt() { return MemoLockCnt; }
00323 #endif
00324   
00325 /*
00326   xbShort   LockTable( xbShort LockType );
00327   xbShort   LockXbaseTable( xbShort LockType );
00328   xbShort   LockClipperTable( xbShort LockType );
00329   xbShort   LockFoxproTable( xbShort LockType );
00330   xbShort   LockDbaseTable( xbShort LockType );
00331   
00332   xbShort   LockRecord( xbShort LockType, xbULong RecNo, xbULong RecCnt );
00333   xbShort   LockXbaseRecord( xbShort LockType, xbULong RecNo, xbULong RecCnt );
00334   xbShort   LockClipperRecord( 
00335                xbShort LockType, xbULong RecNo, xbULong RecCnt );
00336   xbShort   LockFoxproRecord( xbShort LockType, xbULong RecNo, xbULong RecCnt );
00337   xbShort   LockDbaseRecord( xbShort LockType, xbULong RecNo, xbULong RecCnt );
00338 
00339   xbShort   LockDatabase( xbShort, xbShort, xbULong );
00340   xbShort   ExclusiveLock( xbShort );
00341   xbShort   ExclusiveUnlock();
00342   xbShort   LockDatabase( xbShort cmd, xbULong recNo ) { return 0; }
00343 */
00344 
00345 #ifndef HAVE_FCNTL
00346   xbShort   UnixToDosLockCommand( xbShort WaitOption,
00347               xbShort LockType ) const;
00348 #endif
00349 
00350 #else
00351   xbShort   LockDatabase( xbShort, xbShort, xbLong )
00352      { return XB_NO_ERROR; }
00353   xbShort   ExclusiveLock( xbShort ) { return XB_NO_ERROR; };
00354   xbShort   ExclusiveUnlock()      { return XB_NO_ERROR; };
00355 #endif
00356 
00358 
00360    void    AutoLockOn()  { AutoLock = 1; }
00362 
00364    void    AutoLockOff() { AutoLock = 0; }
00366 
00368   xbShort GetAutoLock() { return AutoLock; }
00369 
00370 #ifdef XB_MEMO_FIELDS
00371   xbShort   GetMemoField( xbShort FieldNo, xbLong len,
00372              char * Buf, xbShort LockOption );
00373   xbLong    GetMemoFieldLen( xbShort FieldNo );
00374   xbShort   GetFPTField( xbShort FieldNo, xbLong len,
00375               char * Buf, xbShort LockOption );
00376   xbLong    GetFPTFieldLen( xbShort FieldNo );
00377   xbShort   UpdateMemoData( xbShort FieldNo, xbLong len,
00378               const char * Buf, xbShort LockOption );
00379   xbShort   MemoFieldExists( xbShort FieldNo ) const;
00380   xbShort   LockMemoFile( xbShort WaitOption, xbShort LockType );
00381 
00382   xbShort   MemoFieldsPresent() const;
00383   xbLong    CalcLastDataBlock();
00384   xbShort   FindBlockSetInChain( xbLong BlocksNeeded, xbLong
00385                LastDataBlock, xbLong & Location, xbLong &PreviousNode );
00386   xbShort   GetBlockSetFromChain( xbLong BlocksNeeded, xbLong
00387                Location, xbLong PreviousNode );
00388   xbString & GetDbtName() { return MemofileName; }
00389 
00390 #ifdef XBASE_DEBUG
00391   xbShort   DumpMemoFreeChain();
00392   void      DumpMemoHeader() const;
00393   void      DumpMemoBlock() const;
00394 #endif
00395 #endif
00396 
00398 
00406   void      RealDeleteOn() { RealDelete = 1; if(fp) ReadHeader(1); }
00409   void      RealDeleteOff() { RealDelete = 0; if(fp) ReadHeader(1); }
00411 
00415   xbShort   GetRealDelete() { return RealDelete; }
00416 
00417 #if defined(XB_INDEX_ANY)
00418   xbShort   IndexCount();
00419   xbIndex   *GetIndex(xbShort indexNum);
00420 #endif
00421 
00422   void      Flush();
00423   virtual const char* GetExtWithDot( bool lower );
00424 
00425  private:
00426 
00427   xbShort   DeleteAll( xbShort );
00428   void      InitVars();
00429   xbShort   PackDatafiles(void (*statusFunc)(xbLong itemNum, xbLong numItems) = 0);
00430   xbShort   ReadHeader( xbShort );
00431   xbShort   WriteHeader( xbShort );
00432   
00433 #ifdef XB_MEMO_FIELDS
00434   xbShort   AddMemoData( xbShort FieldNo, xbLong Len, const char * Buf );
00435   xbShort   CreateMemoFile();
00436   xbShort   DeleteMemoField( xbShort FieldNo );
00437   xbShort   GetDbtHeader( xbShort Option );
00438   xbShort   GetMemoBlockSize() { return MemoHeader.BlockSize; }
00439   xbShort   OpenMemoFile();
00440   xbShort   OpenFPTFile();
00441   xbShort   PutMemoData( xbLong StartBlock, xbLong BlocksNeeded,
00442           xbLong Len, const char * Buf );
00443   xbShort   ReadMemoBlock( xbLong BlockNo, xbShort Option);
00444   xbShort   SetMemoBlockSize( xbShort );
00445   xbShort   UpdateHeadNextNode() const;
00446   xbShort   WriteMemoBlock( xbLong BlockNo, xbShort Option );
00447   xbShort   IsType3Dbt() const { return( Version==(char)0x83 ? 1:0 ); }
00448   xbShort   IsType4Dbt() const
00449         {return (( Version==(char)0x8B || Version==(char)0x8E ) ? 1:0 );}
00450   xbShort   CreateUniqueDbfName( xbString &, xbString & );
00451 #endif
00452 
00453 
00454 //  xbString DatabaseName;
00455   xbShort  XFV;                  /* xBASE file version            */
00456   xbShort  NoOfFields;
00457   char     DbfStatus;            /* 0 = closed
00458                                     1 = open
00459                                     2 = updates pending           */
00460   FILE   *fp;                    /* file pointer                  */
00461   xbSchemaRec *SchemaPtr;        /* Pointer to field data         */
00462   char   *RecBuf;                /* Pointer to record buffer      */
00463   char   *RecBuf2;               /* Pointer to original rec buf   */
00464 
00465 #ifdef XB_MEMO_FIELDS
00466   xbString MemofileName;         /* memo file name                */
00467   FILE    *mfp;                  /* memo file pointer             */
00468   void    *mbb;                  /* memo block buffer             */
00469   xbMH     MemoHeader;           /* memo header structure         */
00470   xbShort  mfield1;              /* memo block field one FF       */
00471   xbShort  MStartPos;            /* memo start pos of data        */
00472   xbLong   MFieldLen;            /* memo length of data           */
00473   xbLong   NextFreeBlock;        /* next free block in free chain */
00474   xbLong   FreeBlockCnt;         /* count of free blocks this set */
00475   xbLong   MNextBlockNo;         /* free block chain              */
00476   xbLong   MNoOfFreeBlocks;      /* free block chain              */
00477   xbLong   CurMemoBlockNo;       /* Current block no loaded       */
00478 #endif
00479 
00480 /* Next seven variables are read directly off the database header */
00481 /* Don't change the order of the following seven items            */
00482   char   Version;
00483   char   UpdateYY;
00484   char   UpdateMM;
00485   char   UpdateDD;
00486 //   xbLong   NoOfRecs;
00487 //   xbShort  HeaderLen;
00488 //   xbShort  RecordLen;
00489 
00490   xbULong  NoOfRecs;
00491   xbUShort HeaderLen;
00492   xbUShort RecordLen;
00493 
00494 //#ifdef XB_REAL_DELETE
00495   xbULong  FirstFreeRec;
00496   xbULong  RealNumRecs;
00497 //#endif
00498 
00499 //  xbIxList * MdxList;
00500   xbIxList * NdxList;
00501   xbIxList * FreeIxList;
00502   xbULong  CurRec;               /* Current record or zero   */
00503   xbShort  AutoLock;             /* Auto update option 0 = off  */
00504 
00505 //#ifdef XB_REAL_DELETE
00506   xbShort  RealDelete;           /* real delete option 0 = off */
00507 //#endif
00508 
00509 #ifdef XB_LOCKING_ON
00510   FILE     *xblfh;                /* xbase lock file pointer for xbase locking */
00511   xbShort  LockMode;              /* lock mode for this table */  
00512   xbString lfn;                   /* xbase lock file name for xbase locking */
00513   xbShort  TableLockCnt;          /* number of table locks  */
00514   xbShort  IndexLockCnt;          /* no of index locks XB_XBASE_LOCK_MODE only */
00515 
00516 #ifdef XB_MEMO_FIELDS
00517   xbShort  MemoLockCnt;           /* number of memo file locks */
00518 #endif
00519   
00520   /* old locking stuff */
00521   xbShort  CurLockType;           /* current type of file lock */
00522   xbShort  CurLockCount;          /* number of current file locks */
00523   xbULong  CurLockedRecNo;        /* currently locked record no */
00524   xbShort  CurRecLockType;        /* current type of rec lock held (F_RDLOCK or F_WRLCK) */
00525   xbShort  CurRecLockCount;       /* number of current record locks */
00526   xbShort  CurMemoLockType;       /* current type of memo lock */
00527   xbShort  CurMemoLockCount;      /* number of current memo locks */
00528 #endif
00529 
00530 };
00531 #endif      // __XB_DBF_H__
00532 
00533