⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dbf.cpp

📁 一个通讯管理机的源代码。比较好用。推荐
💻 CPP
📖 第 1 页 / 共 5 页
字号:
          /* lock the database */#ifdef XB_LOCKING_ON   if( AutoLock )   {      if(( rc = LockDatabase( F_SETLKW, F_WRLCK, CurRec )) != XB_NO_ERROR )       {        return rc;      }      if(( rc = LockDatabase( F_SETLKW, F_WRLCK, 0L )) != XB_NO_ERROR )      {         LockDatabase( F_SETLK, F_UNLCK, CurRec );         return rc;      }            if((rc = ReadHeader(1)) != XB_NO_ERROR)      {         if(AutoLock)         {            LockDatabase( F_SETLK, F_UNLCK, CurRec );            LockDatabase( F_SETLK, F_UNLCK, 0L );         }         return rc;      }   }#endif/* lock the indexes */#if defined(XB_INDEX_ANY) && defined(XB_LOCKING_ON) && defined(XB_REAL_DELETE)   i = NdxList;   while( i && AutoLock )   {      if(( rc = i->index->LockIndex( F_SETLKW, F_WRLCK )) != XB_NO_ERROR )         return rc;      i = i->NextIx;   }#endif/* remove keys from indexes */#if defined(XB_REAL_DELETE) && defined(XB_INDEX_ANY)   if(RealDelete)   {     i = NdxList;     while(i)     {        i->index->CreateKey(0, 0);      /* load key buf */        if(i->index->GetCurDbfRec() == (xbLong)CurRec)        {          i->index->DeleteKey(CurRec);          newCurRec = i->index->GetCurDbfRec();        }        else          i->index->DeleteKey(CurRec);        i->index->TouchIndex();        i = i->NextIx;     }   }#endif   RecBuf[0] = 0x2a;   #ifdef XB_REAL_DELETE//fprintf(stderr, "DeleteRecord() -> RealDelete = %d\n", RealDelete);   if(RealDelete)   {      xbase->PutULong(&RecBuf[1], FirstFreeRec);      FirstFreeRec = CurRec;      RealNumRecs--;      WriteHeader(1);   }#endif         if(!RealDelete)   {      if( DbfStatus != XB_UPDATED )      {         DbfStatus = XB_UPDATED;         memcpy( RecBuf2, RecBuf, RecordLen );      }        rc = PutRecord( CurRec );   }   else   {      if(fseek( fp, (long) HeaderLen + ((CurRec - 1L) * RecordLen), 0))         xb_error(XB_SEEK_ERROR);      if(fwrite( RecBuf, RecordLen, 1, fp ) != 1 )         xb_error(XB_WRITE_ERROR);           //      //  Attempt to read in the record for the current location      //  in the active index.      //      CurRec = newCurRec;      if(CurRec)         rc = GetRecord(CurRec);      else         BlankRecord();   }      #ifdef XB_LOCKING_ON   if(AutoLock)   {      LockDatabase( F_SETLK, F_UNLCK, CurRec );      LockDatabase( F_SETLK, F_UNLCK, 0L );   }#if defined(XB_INDEX_ANY) && defined(XB_REAL_DELETE)   i = NdxList;   while( i && AutoLock )   {      i->index->LockIndex( F_SETLK, F_UNLCK );      i = i->NextIx;   }#endif               /* XB_INDEX_ANY  */#endif               /* XB_LOCKING_ON */   return rc;}/************************************************************************///! Undelete the current record/*!  Marks the currect record as not deleted (i.e. removes the flag indicating  the record is deleted).  This method may not be used (and will return  an error code) if "real" deletes are on.    \returns One of the following:    \htmlonly      <p>      <table border=2><tr><th>Return Code</th><th>Description</th></tr>        <tr><td>XB_NO_ERROR</td><td>No error</td></tr>        <tr><td>XB_INVALID_RECORD</td><td>Invalid record number</td></tr>      </table>    \endhtmlonly    \latexonly      \\      \\      \begin{tabular}{|l|l|} \hline        \textbf{Return Code} & \textbf{Description} \\ \hline \hline        XB\_NO\_ERROR & No error \\ \hline   XB\_INVALID\_RECORD & Invalid record number \\ \hline      \end{tabular}    \endlatexonly*/xbShort xbDbf::UndeleteRecord( void ){   xbShort rc;   #ifdef XB_REAL_DELETE   if(RealDelete)     xb_error(XB_INVALID_RECORD);#endif   if( RecBuf )    {      if( DbfStatus != XB_UPDATED )      {         DbfStatus = XB_UPDATED;         memcpy( RecBuf2, RecBuf, RecordLen );      }        RecBuf[0] = 0x20;      if(( rc = PutRecord( CurRec )) != 0 )         return rc;   }   else     xb_error(XB_INVALID_RECORD);   return 0;}/************************************************************************///! Determine if current record is deleted/*!  \returns TRUE (1) if the current record is marked as deleted or FALSE    (0) if not.*/xbShort xbDbf::RecordDeleted( void ){   if( RecBuf && RecBuf[0] == 0x2a )      return 1;   else      return 0;} /************************************************************************///! Pack data file/*!*/xbShort xbDbf::PackDatafiles(void (*statusFunc)(xbLong itemNum, xbLong numItems)){   xbShort rc = 0, i, NameLen;   FILE *t;   xbLong l;   char *target, *source;   xbString TempDbfName;   char   * Buf = 0;#ifdef XB_MEMO_FIELDS   char tbuf[4];#endif#ifdef XB_MEMO_FIELDS   xbLong   len, BufSize;   xbString TempDbtName;   xbShort  MemoFields;#endif  /* XB_MEMO_FIELDS */   xbDbf Temp( xbase );   if(( rc = xbase->DirectoryExistsInName( DatabaseName )) > 0 )      NameLen = rc + 13;   else      NameLen = 13;   if (rc) {      TempDbfName.assign(DatabaseName, 0, rc);      TempDbfName += "TMPXBASE.DBF";   } else     TempDbfName = "TMPXBASE.DBF";   if (( t = fopen( TempDbfName, "w+b" )) == NULL )     xb_open_error(TempDbfName);   /* copy file header */   if(( rc = fseek( fp, 0, SEEK_SET )) != 0 )      xb_io_error(XB_SEEK_ERROR, TempDbfName);     for( i = 0; i < HeaderLen; i++ )      fputc( fgetc( fp ), t );   fputc( 0x1a, t );   if( fclose( t ) != 0 )     xb_io_error(XB_CLOSE_ERROR, TempDbfName);#ifdef XB_MEMO_FIELDS   if(( MemoFields = MemoFieldsPresent()) > 0 )   {      TempDbtName = TempDbfName;      TempDbtName.putAt(TempDbtName.len()-1, 'T');      if ((t = fopen( TempDbtName, "w+b" )) == NULL)   xb_open_error(TempDbtName);      l = 1L;      memset( tbuf, 0x00, 4 );      xbase->PutLong( tbuf, l );            if ((fwrite(&tbuf, 4, 1, t)) != 1)         xb_io_error(XB_WRITE_ERROR, TempDbfName);      if( MemoHeader.Version == 0x03 )      {         for( i = 0; i < 12; i++ ) fputc( 0x00, t );         fputc( 0x03, t );         for( i = 0; i < 495; i++ ) fputc( 0x00, t );      } else {         for( i = 0; i < 4; i++ ) fputc( 0x00, t );         if ((fwrite(&MemoHeader.FileName, 8, 1, t)) != 1)      xb_io_error(XB_WRITE_ERROR, TempDbfName);         for( i = 0; i < 4; i++ ) fputc( 0x00, t );         memset( tbuf, 0x00, 2 );         xbase->PutShort( tbuf, MemoHeader.BlockSize );         if ((fwrite(&tbuf, 2, 1, t)) != 1)       xb_io_error(XB_WRITE_ERROR, TempDbfName);         for( i = 22; i < MemoHeader.BlockSize; i++ ) fputc( 0x00, t );      }       if( fclose( t ) != 0 )            xb_io_error(XB_CLOSE_ERROR, TempDbfName);   }#endif   /* XB_MEMO_FIELDS */   /* reopen as database */   if(( rc = Temp.OpenDatabase( TempDbfName )) != XB_NO_ERROR )     return rc;   Temp.ResetNoOfRecs();   Temp.WriteHeader(2);          // flush NoOfRecs=0 to disk   target = Temp.GetRecordBuf();   source = GetRecordBuf();   for( l = 1; l <= NoOfRecords(); l++ )   {      if(statusFunc && (l == 1 || !(l % 100) || l == PhysicalNoOfRecords()))         statusFunc(l, PhysicalNoOfRecords());               if(( rc = GetRecord( l )) != XB_NO_ERROR )        return rc;      if( !RecordDeleted())      {         strncpy( target, source, GetRecordLen());#ifdef XB_MEMO_FIELDS         len = BufSize = 0L;         Buf = NULL;         for( i = 0; i < NoOfFields; i++ )         {            if( GetFieldType( i ) == 'M' && MemoFieldExists( i ))            {               len = GetMemoFieldLen( i );               if( len > BufSize )               {                  if( BufSize )                      free( Buf );                  if ((Buf = (char *)malloc(len)) == NULL)                              xb_memory_error;                  BufSize = len;               }               GetMemoField( i, len, Buf, -1 );               Temp.UpdateMemoData( i, len, Buf, -1 );            }         }#endif         if(( rc = Temp.AppendRecord()) != XB_NO_ERROR )    {       if(Buf) free(Buf);       return rc;         }      }   }   if( Buf ) free( Buf );   Temp.CloseDatabase();    if (fclose(fp) != 0)         xb_io_error(XB_CLOSE_ERROR, DatabaseName);   if(remove(DatabaseName) != 0)         xb_io_error(XB_WRITE_ERROR, DatabaseName);   if(rename(TempDbfName, DatabaseName) != 0)         xb_io_error(XB_WRITE_ERROR, TempDbfName);#ifdef XB_MEMO_FIELDS   if( MemoFields )   { //     len = DatabaseName.len(); //     len--; //     lb = DatabaseName[len];            int len = DatabaseName.len() - 1;      char lb = DatabaseName[len];      if( lb == 'F' )         DatabaseName.putAt(len, 'T');      else         DatabaseName.putAt(len, 't');         if(fclose(mfp) != 0)       /* thanks Jourquin */         xb_io_error(XB_CLOSE_ERROR, TempDbtName);         if (remove(DatabaseName) != 0)      {         DatabaseName.putAt(len, lb);         xb_io_error(XB_WRITE_ERROR, DatabaseName);      }      if( rename( TempDbtName, DatabaseName ) != 0 )      {         DatabaseName.putAt(len, lb);         xb_io_error(XB_WRITE_ERROR, DatabaseName);      }      if(( mfp = fopen( DatabaseName, "r+b" )) == NULL )        xb_open_error(DatabaseName);#ifdef XB_LOCKING_ON        /* no buffering in multi user mode */        setbuf( mfp, NULL );#endif      DatabaseName.putAt(len, lb);   }#endif /* XB_MEMO_FIELDS */   if(( fp = fopen( DatabaseName, "r+b" )) == NULL )     xb_open_error(DatabaseName);#ifdef XB_LOCKING_ON   /* no buffering in multi user mode */   setbuf( fp, NULL );#endif   return XB_NO_ERROR;}/************************************************************************///! Pack the database/*!  This method removes all records marked for deletion from an Xbase (.DBF)   file, reindexes any open index files, and also reorganizes any memo fields  stored in a .DBT memo file.     \param LockWaitOption One of the following:    \htmlonly      <p>      <table border=2><tr><th>LockWaitOption</th><th>Description</th></tr>        <tr><td>F_SETLK</td><td>Return immediately if the DBF file cannot be locked</td></tr>        <tr><td>F_SETLKW</td><td>Wait for lock on DBF file to succeed</td></tr>      </table>    \endhtmlonly    \latexonly      \\      \\      \begin{tabular}{|l|l|} \hline        \textbf{LockWaitOption} & \textbf{Description} \\ \hline \hline        F\_SETLK & Return immediately if DBF file cannot be locked \\ \hline        F\_SETLKW  & Wait for lock on DBF file to succeed \\ \hline      \end{tabular}    \endlatexonly      \returns One of the following return codes:    \htmlonly      <p>      <table border=2><tr><th>Return Code</th><th>Description</th></tr>        <tr><td>XB_NO_ERROR</td><td>No error</td></tr>   <tr><td>XB_CLOSE_ERROR</td><td>Unable to close intermediate work file</td></tr>   <tr><td>XB_OPEN_ERROR</td><td>Could not open file</td></tr>   <tr><td>XB_NO_MEMORY</td><td>Memory allocation error</td></tr>        <tr><td>XB_WRITE_ERROR</td><td>Couldn't write to disk</td></tr>   <tr><td>XB_SEEK_ERROR</td><td>Error seeking file</td></tr>   <tr><td>XB_LOCK_FAILED</td><td>Unable to lock file or index</td></tr>      </table>    \endhtmlonly    \latexonly      \\      \\      \begin{tabular}{|l|l|} \hline        \textbf{Return Code} & \textbf{Description} \\ \hline \hline        XB\_NO\_ERROR & No Error \\ \hline   XB\_CLOSE\_ERROR & Unable to close intermediate work file \\ \hline        XB\_OPEN\_ERROR & Couldn't open the file \\ \hline   XB\_NO\_MEMORY & Memory allocation error \\ \hline        XB\_WRITE\_ERROR & Couldn't write to disk \\ \hline   XB\_SEEK\_ERROR & Error seeking file \\ \hline   XB\_LOCK\_FAILED & Unable to lock file or index \\ \hline      \end{tabular}    \endlatexonly*/xbShort xbDbf::PackDatabase(xbShort LockWaitOption,                            void (*packStatusFunc)(xbLong itemNum, xbLong numItems),                            void (*indexStatusFunc)(xbLong itemNum, xbLong numItems)){   xbShort rc = 0;   /* lock all open files and indexes */   if(( rc = ExclusiveLock( LockWaitOption )) != XB_NO_ERROR ) return rc;   if(( rc = PackDatafiles(packStatusFunc)) != XB_NO_ERROR )   {      ExclusiveUnlock();      return rc;   }   /* refresh file header */   if(( rc = ReadHeader(1)) != XB_NO_ERROR )      return rc;   if(( rc = RebuildAllIndices(indexStatusFunc)) != XB_NO_ERROR )       return rc;   ExclusiveUnlock();   return XB_NO_ERROR;}/************************************************************************///! Copy DBF structure/*!*/xbShort xbDbf::C

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -