Xbase Class Library 2.0.0

dbf.h

Go to the documentation of this file.
00001 /*  $Id: dbf.h,v 1.8 2001/01/13 20:20:53 dbryson Exp $
00002 
00003     Xbase project source code
00004 
00005     This file contains the Class definition for a xbDBF object.
00006 
00007     Copyright (C) 1997  StarTech, Gary A. Kunkel   
00008 
00009     This library is free software; you can redistribute it and/or
00010     modify it under the terms of the GNU Lesser General Public
00011     License as published by the Free Software Foundation; either
00012     version 2.1 of the License, or (at your option) any later version.
00013 
00014     This library 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 GNU
00017     Lesser General Public License for more details.
00018 
00019     You should have received a copy of the GNU Lesser General Public
00020     License along with this library; if not, write to the Free Software
00021     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022 
00023     Contact:
00024 
00025       Mail:
00026 
00027         Technology Associates, Inc.
00028         XBase Project
00029         1455 Deming Way #11
00030         Sparks, NV 89434
00031         USA
00032 
00033       Email:
00034 
00035         xbase@techass.com
00036 
00037       See our website at:
00038 
00039         xdb.sourceforge.net
00040 
00041 
00042     V 1.0    10/10/97   - Initial release of software
00043     V 1.3    11/30/97   - Added memo field processing
00044     V 1.6a   4/1/98     - Added expression support
00045     V 1.6b   4/8/98     - Numeric index keys
00046     V 1.7.4d 10/28/98   - Added support for OS2/DOS/Win/NT locking
00047     V 1.8    11/29/98   - New class names and types 
00048     V 1.9.2  9/14/99    - Updated EOR and EOF processing
00049 */
00050 
00051 
00052 #ifndef __XB_DBF_H__
00053 #define __XB_DBF_H__
00054 
00055 #ifdef __GNUG__
00056 #pragma interface
00057 #endif
00058 
00059 #ifdef __WIN32__
00060 #include <xbase/xbconfigw32.h>
00061 #else
00062 #include <xbase/xbconfig.h>
00063 #endif
00064 
00065 #include <xbase/xtypes.h>
00066 #include <xbase/xdate.h>
00067 
00068 #include <iostream>
00069 using namespace std;
00070 #include <stdio.h>
00071 
00075 #if defined(XB_INDEX_ANY)
00076    class XBDLLEXPORT xbIndex;
00077    class XBDLLEXPORT xbNdx;
00078    class XBDLLEXPORT xbNtx;
00079 #endif
00080 
00081 /*****************************/
00082 /* Field Types               */
00083 
00084 #define XB_CHAR_FLD      'C'
00085 #define XB_LOGICAL_FLD   'L'
00086 #define XB_NUMERIC_FLD   'N'
00087 #define XB_DATE_FLD      'D'
00088 #define XB_MEMO_FLD      'M'
00089 #define XB_FLOAT_FLD     'F'
00090 
00091 /*****************************/
00092 /* File Status Codes         */
00093 
00094 #define XB_CLOSED  0
00095 #define XB_OPEN    1
00096 #define XB_UPDATED 2
00097 
00098 /*****************************/
00099 /* Other defines             */
00100 
00101 #define XB_OVERLAY     1
00102 #define XB_DONTOVERLAY 0
00103 
00104 #define XB_CHAREOF  '\x1A'         /* end of DBF        */
00105 #define XB_CHARHDR  '\x0D'         /* header terminator */
00106 
00108 
00141 struct XBDLLEXPORT xbSchema {
00142    char      FieldName[11];
00143    char      Type;
00144 // xbUShort  FieldLen;       /* does not work */
00145 // xbUShort  NoOfDecs;       /* does not work */
00146    unsigned  char FieldLen;  /* fields are stored as one byte on record*/
00147    unsigned  char NoOfDecs;
00148 };
00149 
00151 
00154 struct XBDLLEXPORT xbSchemaRec {
00155    char     FieldName[11];
00156    char     Type;            /* field type */
00157    char     *Address;        /* pointer to field in record buffer 1 */
00158 // xbUShort FieldLen;        /* does not work */
00159 // xbUShort NoOfDecs;        /* does not work */
00160    unsigned char FieldLen;   /* fields are stored as one byte on record */
00161    unsigned char NoOfDecs;
00162    char     *Address2;       /* pointer to field in record buffer 2 */
00163    char     *fp;             /* pointer to null terminated buffer for field */
00164                              /* see method GetString */
00165    xbShort  LongFieldLen;    /* to handle long field lengths */
00166 };
00167 
00169 
00172 struct XBDLLEXPORT xbIxList {
00173    xbIxList * NextIx;
00174    xbString IxName;
00175 #if defined(XB_INDEX_ANY)
00176    xbIndex  * index;
00177    xbShort  Unique;
00178    xbShort  KeyUpdated;
00179 #endif
00180 };
00181 
00183 
00187 #ifdef XB_MEMO_FIELDS
00188 struct XBDLLEXPORT xbMH{                      /* memo header                    */
00189    xbLong  NextBlock;             /* pointer to next block to write */
00190    char    FileName[8];           /* name of dbt file               */
00191    char    Version;               /* not sure                       */
00192    xbShort BlockSize;             /* memo file block size           */
00193 };
00194 #endif
00195 
00197 
00201 class XBDLLEXPORT xbDbf {
00202 
00203 public:
00204    xbDbf( xbXBase * );
00205    xbXBase  *xbase;               /* linkage to main base class */
00206 //   char EofChar[10];
00207 
00208 /* datafile methods */
00209 #if defined(XB_INDEX_ANY)
00210    xbShort   AddIndexToIxList(xbIndex *, const char *IndexName);
00211    xbShort   RemoveIndexFromIxList( xbIndex * );
00212 #endif
00213    xbShort   AppendRecord( void );
00214    xbShort   BlankRecord( void );
00215    xbLong    CalcCheckSum( void );
00216    xbShort   CloseDatabase(bool deleteIndexes = 0);
00217    xbShort   CopyDbfStructure( const char *, xbShort );
00218    xbShort   CreateDatabase( const char * Name, xbSchema *, const xbShort Overlay );
00220 
00222    xbLong    DbfTell( void ) { return ftell( fp ); }
00224 
00226    xbShort   DeleteAllRecords( void ) { return DeleteAll(0); }
00227    xbShort   DeleteRecord( void );
00228 #ifdef XBASE_DEBUG
00229    xbShort   DumpHeader( xbShort );
00230 #endif
00231    xbShort   DumpRecord( xbULong );
00233 
00235    xbLong    FieldCount( void ) { return NoOfFields; }
00237 
00239    xbString& GetDbfName( void ) { return DatabaseName; }
00241 
00243    xbShort   GetDbfStatus( void ) { return DbfStatus; }
00244    xbShort   GetFirstRecord( void );
00245    xbShort   GetLastRecord( void );
00246    xbShort   GetNextRecord( void );
00247    xbShort   GetPrevRecord( void );
00249 
00251    xbLong    GetCurRecNo( void ) { return CurRec; }
00252    xbShort   GetRecord( xbULong );
00254 
00256    char *    GetRecordBuf( void ) { return RecBuf; }
00258 
00260    xbShort   GetRecordLen( void ) { return RecordLen; }
00261    xbShort   NameSuffixMissing( xbShort, const char * );
00262    xbLong    NoOfRecords( void );
00263    xbLong    PhysicalNoOfRecords(void);
00264    xbShort   OpenDatabase( const char * );
00265    xbShort   PackDatabase(xbShort LockWaitOption,
00266                           void (*packStatusFunc)(xbLong itemNum, xbLong numItems) = 0,
00267                           void (*indexStatusFunc)(xbLong itemNum, xbLong numItems) = 0);
00268    xbShort   PutRecord(void); // Put record to current position
00269    xbShort   PutRecord(xbULong);
00270    xbShort   RebuildAllIndices(void (*statusFunc)(xbLong itemNum, xbLong numItems) = 0);
00271    xbShort   RecordDeleted( void );
00273 
00275    void      ResetNoOfRecs( void ) { NoOfRecs = 0L; }
00276    xbShort   SetVersion( xbShort );
00278 
00280    xbShort   UndeleteAllRecords( void ) { return DeleteAll(1); }
00281    xbShort   UndeleteRecord( void );
00282    xbShort   Zap( xbShort );
00283 
00284 /* field methods */
00285    const char *GetField(xbShort FieldNo) const; // Using internal static buffer
00286    const char *GetField(const char *Name) const;
00287    xbShort   GetField( xbShort FieldNo, char *Buf) const;
00288    xbShort   GetRawField(const xbShort FieldNo, char *Buf) const;
00289    xbShort   GetField( xbShort FieldNo, char *Buf, xbShort RecBufSw) const;
00290    xbShort   GetField( const char *Name, char *Buf) const;
00291    xbShort   GetRawField(const char *Name, char *Buf) const;
00292    xbShort   GetField( const char *Name, char *Buf, xbShort RecBufSw) const;
00293    xbShort   GetField(xbShort FieldNo, xbString&, xbShort RecBufSw ) const;
00294    xbShort   GetFieldDecimal( const xbShort );
00295    xbShort   GetFieldLen( const xbShort );
00296    char *    GetFieldName( const xbShort );
00297    xbShort   GetFieldNo( const char * FieldName ) const;
00298    char      GetFieldType( const xbShort FieldNo ) const;
00299    xbShort   GetLogicalField( const xbShort FieldNo );
00300    xbShort   GetLogicalField( const char * FieldName );
00301 
00302    char *    GetStringField( const xbShort FieldNo );
00303    char *    GetStringField( const char * FieldName );
00304 
00305    xbShort   PutField( const xbShort, const char * );
00306    xbShort   PutRawField( const xbShort FieldNo, const char *buf );
00307    xbShort   PutField( const char *Name, const char *buf);
00308    xbShort   PutRawField( const char *Name, const char *buf );
00309    xbShort   ValidLogicalData( const char * );
00310    xbShort   ValidNumericData( const char * );
00311 
00312    xbLong    GetLongField( const char *FieldName) const;
00313    xbLong    GetLongField( const xbShort FieldNo) const;
00314    xbShort   PutLongField( const xbShort, const xbLong );
00315    xbShort   PutLongField( const char *, const xbLong);
00316 
00317    xbFloat   GetFloatField( const char * FieldName );
00318    xbFloat   GetFloatField( const xbShort FieldNo );
00319    xbShort   PutFloatField( const char *, const xbFloat);
00320    xbShort   PutFloatField( const xbShort, const xbFloat);
00321 
00322    xbDouble  GetDoubleField(const char *);
00323    xbDouble  GetDoubleField(const xbShort, xbShort RecBufSw = 0);
00324    xbShort   PutDoubleField(const char *, const xbDouble);
00325    xbShort   PutDoubleField(const xbShort, const xbDouble);
00326 
00327 #ifdef XB_LOCKING_ON
00328    xbShort   LockDatabase( const xbShort, const xbShort, const xbULong );
00329    xbShort   ExclusiveLock( const xbShort );
00330    xbShort   ExclusiveUnlock( void );
00331 
00332 #ifndef HAVE_FCNTL
00333    xbShort   UnixToDosLockCommand( const xbShort WaitOption,
00334              const xbShort LockType ) const;
00335 #endif
00336 
00337 #else
00338    xbShort   LockDatabase( const xbShort, const xbShort, const xbLong )
00339      { return XB_NO_ERROR; }
00340    xbShort   ExclusiveLock( const xbShort ) { return XB_NO_ERROR; };
00341    xbShort   ExclusiveUnlock( void )      { return XB_NO_ERROR; };
00342 #endif
00343 
00345 
00347    void    AutoLockOn( void )  { AutoLock = 1; }
00349 
00351    void    AutoLockOff( void ) { AutoLock = 0; }
00353 
00355    xbShort GetAutoLock(void) { return AutoLock; }
00356 
00357 #ifdef XB_MEMO_FIELDS
00358    xbShort   GetMemoField( const xbShort FieldNo,const xbLong len,
00359              char * Buf, const xbShort LockOption );
00360    xbLong    GetMemoFieldLen( const xbShort FieldNo );
00361    xbShort   UpdateMemoData( const xbShort FieldNo, const xbLong len,
00362               const char * Buf, const xbShort LockOption );
00363    xbShort   MemoFieldExists( const xbShort FieldNo ) const;
00364    xbShort   LockMemoFile( const xbShort WaitOption, const xbShort LockType );
00365    xbShort   MemoFieldsPresent( void ) const;
00366    xbLong    CalcLastDataBlock();
00367    xbShort   FindBlockSetInChain( const xbLong BlocksNeeded, const xbLong
00368                LastDataBlock, xbLong & Location, xbLong &PreviousNode );
00369    xbShort   GetBlockSetFromChain( const xbLong BlocksNeeded, const xbLong
00370                Location, const xbLong PreviousNode );
00371 
00372 #ifdef XBASE_DEBUG
00373    xbShort   DumpMemoFreeChain( void );
00374    void      DumpMemoHeader( void ) const;
00375    void      DumpMemoBlock( void ) const;
00376 #endif
00377 #endif
00378 
00380 
00388    void      RealDeleteOn(void) { RealDelete = 1; if(fp) ReadHeader(1); }
00391    void      RealDeleteOff(void) { RealDelete = 0; if(fp) ReadHeader(1); }
00393 
00397    xbShort   GetRealDelete(void) { return RealDelete; }
00398 
00399 #if defined(XB_INDEX_ANY)
00400    xbShort   IndexCount(void);
00401    xbIndex   *GetIndex(xbShort indexNum);
00402 #endif
00403 
00404 protected:
00405    xbString DatabaseName;
00406    xbShort  XFV;                  /* xBASE file version            */
00407    xbShort  NoOfFields;
00408    char   DbfStatus;              /* 0 = closed
00409                                      1 = open
00410                                      2 = updates pending           */
00411    FILE   *fp;                    /* file pointer                  */
00412    xbSchemaRec *SchemaPtr;        /* Pointer to field data         */
00413    char   *RecBuf;                /* Pointer to record buffer      */
00414    char   *RecBuf2;               /* Pointer to original rec buf   */
00415 
00416 #ifdef XB_MEMO_FIELDS
00417    FILE    *mfp;                  /* memo file pointer             */
00418    void    *mbb;                  /* memo block buffer             */
00419    xbMH     MemoHeader;           /* memo header structure         */
00420 
00421    xbShort  mfield1;              /* memo block field one FF       */
00422    xbShort  MStartPos;            /* memo start pos of data        */
00423    xbLong   MFieldLen;            /* memo length of data           */
00424    xbLong   NextFreeBlock;        /* next free block in free chain */
00425    xbLong   FreeBlockCnt;         /* count of free blocks this set */
00426 
00427    xbLong   MNextBlockNo;         /* free block chain              */
00428    xbLong   MNoOfFreeBlocks;      /* free block chain              */
00429 
00430    xbLong   CurMemoBlockNo;       /* Current block no loaded       */
00431 #endif
00432 
00433 /* Next seven variables are read directly off the database header */
00434 /* Don't change the order of the following seven items            */
00435    char   Version;
00436    char   UpdateYY;
00437    char   UpdateMM;
00438    char   UpdateDD;
00439 //   xbLong   NoOfRecs;
00440 //   xbShort  HeaderLen;
00441 //   xbShort  RecordLen;
00442 
00443    xbULong  NoOfRecs;
00444    xbUShort HeaderLen;
00445    xbUShort RecordLen;
00446 
00447 //#ifdef XB_REAL_DELETE
00448    xbULong  FirstFreeRec;
00449    xbULong  RealNumRecs;
00450 //#endif
00451 
00452    xbIxList * MdxList;
00453    xbIxList * NdxList;
00454    xbIxList * FreeIxList;
00455    xbULong  CurRec;               /* Current record or zero   */
00456    xbShort  AutoLock;             /* Auto update option 0 = off  */
00457 
00458 //#ifdef XB_REAL_DELETE
00459    xbShort  RealDelete;           /* real delete option 0 = off */
00460 //#endif
00461 
00462 #ifdef XB_LOCKING_ON
00463    xbShort CurLockType;           /* current type of file lock */
00464    xbShort CurLockCount;          /* number of current file locks */
00465    xbULong CurLockedRecNo;        /* currently locked record no */
00466    xbShort CurRecLockType;        /* current type of rec lock held (F_RDLOCK or F_WRLCK) */
00467    xbShort CurRecLockCount;       /* number of current record locks */
00468    xbShort CurMemoLockType;       /* current type of memo lock */
00469    xbShort CurMemoLockCount;      /* number of current memo locks */
00470 #endif
00471 
00472    xbShort   DeleteAll( xbShort );
00473    void    InitVars( void );
00474    xbShort   PackDatafiles(void (*statusFunc)(xbLong itemNum, xbLong numItems) = 0);
00475    xbShort   ReadHeader( xbShort );
00476    xbShort   WriteHeader( const xbShort );
00477 
00478 #ifdef XB_MEMO_FIELDS
00479    xbShort   AddMemoData( const xbShort FieldNo, const xbLong Len, const char * Buf );
00480    xbShort   CreateMemoFile( void );
00481    xbShort   DeleteMemoField( const xbShort FieldNo );
00482    xbShort   GetDbtHeader( const xbShort Option );
00483    xbShort   GetMemoBlockSize( void ) { return MemoHeader.BlockSize; }
00484    xbShort   OpenMemoFile( void );
00485    xbShort   PutMemoData( const xbLong StartBlock, const xbLong BlocksNeeded,
00486              const xbLong Len, const char * Buf );
00487    xbShort   ReadMemoBlock( const xbLong BlockNo, const xbShort Option);
00488    xbShort   SetMemoBlockSize( const xbShort );
00489    xbShort   UpdateHeadNextNode( void ) const;
00490    xbShort   WriteMemoBlock( const xbLong BlockNo, const xbShort Option );
00491    xbShort   IsType3Dbt( void ) const { return( Version==(char)0x83 ? 1:0 ); }
00492    xbShort   IsType4Dbt( void ) const
00493             {return (( Version==(char)0x8B || Version==(char)0x8E ) ? 1:0 );}
00494 #endif
00495 };
00496 #endif      // __XB_DBF_H__
00497