|
Xbase Class Library 2.0.0
|
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
1.7.3