From c894a7cdd8686ea695602a23a511a3f1b0d047be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Mon, 14 Aug 2023 21:07:46 +0200 Subject: New upstream version 4.1.4 --- src/core/xbdbf4.cpp | 885 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 885 insertions(+) create mode 100755 src/core/xbdbf4.cpp (limited to 'src/core/xbdbf4.cpp') diff --git a/src/core/xbdbf4.cpp b/src/core/xbdbf4.cpp new file mode 100755 index 0000000..a1f770e --- /dev/null +++ b/src/core/xbdbf4.cpp @@ -0,0 +1,885 @@ +/* xbdbf4.cpp + +XBase64 Software Library + +Copyright (c) 1997,2003,2014,2022,2023 Gary A Kunkel + +The xb64 software library is covered under the terms of the GPL Version 3, 2007 license. + +Email Contact: + + XDB-devel@lists.sourceforge.net + XDB-users@lists.sourceforge.net + +*/ + +#include "xbase.h" + + +#ifdef XB_DBF4_SUPPORT + +namespace xb{ + + +/************************************************************************/ +//! @brief Constructor. +xbDbf4::xbDbf4(xbXBase * x) : xbDbf( x ) { + + iFileVersion = 4; + #ifdef XB_MEMO_SUPPORT + ulCreateMemoBlockSize = 1024; + #endif +}; + +/************************************************************************/ +//! @brief Destructor. +xbDbf4::~xbDbf4() {}; + +/************************************************************************/ +//! @brief Create Version 4 table. +/*! + This routine creates a Dbase IV (tm) DBF file. + + \param sTableName DBF table name. + \param sAlias Table alias + \param pSchema Pointer to schema structure with field definitions. + \param iOverlay xbTrue - Overlay.
xbFalse - Don't overlay. + \param iShareMode XB_SINGLE_USER
XB_MULTI_USER + \returns Return Codes +*/ + +xbInt16 xbDbf4::CreateTable( const xbString &sTableName, const xbString &sAlias, xbSchema * pSchema, xbInt16 iOverlay, xbInt16 iShareMode ){ + + xbInt16 i, k, k2; + xbInt16 rc = XB_NO_ERROR; + xbInt16 iErrorStop = 0; + iDbfStatus = XB_CLOSED; + + xbString sNfn; + + try{ + sNfn = sTableName; + xbase->GetLogStatus(); + + rc = NameSuffixMissing( sNfn, 1 ); + if( rc > 0 ) + sNfn += ".DBF"; + + SetFileName( sNfn ); + this->sAlias = sAlias; + + /* check if the file already exists */ + if( FileExists( 0 )){ + if( !iOverlay ){ + iErrorStop = 100; + rc = XB_FILE_EXISTS; + throw rc; + } + + // remove other files if they exist + xbString sMname = sNfn; + xbUInt32 iMnameLen = sMname.Len(); + sMname.PutAt( iMnameLen-2, 'I' ); + sMname.PutAt( iMnameLen-1, 'N' ); + sMname.PutAt( iMnameLen, 'F' ); + xbFile fTemp( xbase ); + fTemp.SetFileName( sMname ); + if( fTemp.FileExists() ) + fTemp.xbRemove(); + + sMname.PutAt( iMnameLen-2, 'D' ); + sMname.PutAt( iMnameLen-1, 'B' ); + sMname.PutAt( iMnameLen, 'T' ); + fTemp.SetFileName( sMname ); + if( fTemp.FileExists() ) + fTemp.xbRemove(); + + sMname.PutAt( iMnameLen-2, 'M' ); + sMname.PutAt( iMnameLen-1, 'D' ); + sMname.PutAt( iMnameLen, 'X' ); + fTemp.SetFileName( sMname ); + if( fTemp.FileExists() ) + fTemp.xbRemove(); + } + + /* check if we already have a file with this alias */ + if(( rc = xbase->AddTblToTblList( this, GetFqFileName(), sAlias )) != XB_NO_ERROR ){ + iErrorStop = 110; + throw rc; + } + + rc = ValidateSchema( pSchema ); + if( rc < 0 ){ + iErrorStop = 120; + throw rc; + } else + iNoOfFields = rc; + + #ifdef XB_MEMO_SUPPORT + // if we have memo fields + iMemoFieldCnt = 0; + i = 0; + while( pSchema[i].cType != 0){ + if( pSchema[i].cType == 'M' ) + iMemoFieldCnt++; /* number of memo fields in the incoming definition */ + i++; + } + + if( iMemoFieldCnt > 0 ){ + xbString sMfn = sNfn; /* memo file name, same as filename except ends with a "t", not an "f" */ + xbUInt32 ulMfnLen = sMfn.Len(); + sMfn.PutAt( ulMfnLen, 'T' ); + + // dont overlay the memo file if it exists, and Overlay switch is off + xbFile fTemp( xbase ); + fTemp.SetFileName( sMfn ); + if( fTemp.FileExists() && !iOverlay ){ + iErrorStop = 130; + rc = XB_FILE_EXISTS; + throw rc; + } + + Memo = new xbMemoDbt4( this, fTemp.GetFqFileName()); + + if(( rc = Memo->CreateMemoFile()) != XB_NO_ERROR ){ + iErrorStop = 140; + throw rc; + } + } + #endif + + /* this is the dBase IV version of the class */ + cVersion = 0x03; // 0x03 for Dbase level 5 + #ifdef XB_MEMO_SUPPORT + if( iMemoFieldCnt > 0 ){ +// cVersion = cVersion |= 0x88; // version IV memos, compiler complains about this + cVersion |= 0x88; // version IV memos + } + #endif + + if(( rc = xbFopen( "w+b", iShareMode )) != XB_NO_ERROR ){ + iErrorStop = 150; + throw rc; + } + uiRecordLen++; /* add one byte for 0x0D */ + + if(( RecBuf = (char *) malloc( uiRecordLen )) == NULL ){ + iErrorStop = 160; + throw rc; + } + + if(( RecBuf2 = (char *) malloc( uiRecordLen )) == NULL ){ + iErrorStop = 170; + rc = XB_NO_MEMORY; + throw rc; + } + + /* BlankRecord(); */ + memset( RecBuf, 0x20, uiRecordLen ); + memset( RecBuf2, 0x20, uiRecordLen ); + ulCurRec = 0L; + uiHeaderLen = 33 + iNoOfFields * 32; + xbDate d; + d.Sysdate(); + cUpdateYY = (char) (d.YearOf() - 1900); + cUpdateMM = (char) d.MonthOf(); + cUpdateDD = (char) d.DayOf( XB_FMT_MONTH ); + cIndexFlag = 0; + // Default language driver to 0x1b + cLangDriver = 0x1b; + + /* write the header prolog */ + if(( rc = WriteHeader( 0, 0 )) != XB_NO_ERROR ){ + iErrorStop = 180; + rc = XB_WRITE_ERROR; + throw rc; + } + if((SchemaPtr=(xbSchemaRec *)malloc( (size_t) iNoOfFields * sizeof( xbSchemaRec ))) == NULL){ + iErrorStop = 190; + rc = XB_NO_MEMORY; + throw rc; + } + + /* write the field information into the header */ + for( i = 0, k = 1; i < iNoOfFields; i++ ){ + + memset( SchemaPtr[i].cFieldName, 0x00, 11 ); + for( int x = 0; x < 10 && pSchema[i].cFieldName[x]; x++ ) + SchemaPtr[i].cFieldName[x] = pSchema[i].cFieldName[x]; + + SchemaPtr[i].cType = pSchema[i].cType; + SchemaPtr[i].cFieldLen = (unsigned char) pSchema[i].iFieldLen; + SchemaPtr[i].cNoOfDecs = (unsigned char) pSchema[i].iNoOfDecs; + + if( SchemaPtr[i].cNoOfDecs > SchemaPtr[i].cFieldLen ){ + iErrorStop = 110; + rc = XB_WRITE_ERROR; + throw rc; + } + + k2 = k; + k += SchemaPtr[i].cFieldLen; + + if(( xbFwrite( &SchemaPtr[i].cFieldName, 1, 11 )) != XB_NO_ERROR ) { + iErrorStop = 200; + rc = XB_WRITE_ERROR; + throw rc; + } + + if(( xbFwrite( &SchemaPtr[i].cType, 1, 1 )) != XB_NO_ERROR ) { + iErrorStop = 210; + rc = XB_WRITE_ERROR; + throw rc; + } + + for( int j = 0; j < 4; j++ ) + xbFputc( 0x00 ); + + if(( xbFwrite( &SchemaPtr[i].cFieldLen, 1, 1 )) != XB_NO_ERROR ) { + iErrorStop = 220; + rc = XB_WRITE_ERROR; + throw rc; + } + + if(( xbFwrite( &SchemaPtr[i].cNoOfDecs, 1, 1 )) != XB_NO_ERROR ) { + iErrorStop = 230; + rc = XB_WRITE_ERROR; + throw rc; + } + + /* 14 bytes reserved */ + for( int j = 0; j < 14; j++ ) + xbFputc( 0x00 ); + + SchemaPtr[i].pAddress = RecBuf + k2; + SchemaPtr[i].pAddress2 = RecBuf2 + k2; + } + + /* write the header terminator */ + if(( xbFputc( XB_CHARHDR )) != XB_NO_ERROR ){ + iErrorStop = 240; + rc = XB_WRITE_ERROR; + throw rc; + } + } + catch( xbInt16 rc ) + { + xbString sMsg; + sMsg.Sprintf( "xbdbf4::CreateTable() Exception Caught Error Stop = [%d] rc = [%d]", iErrorStop, rc ); + xbase->WriteLogMessage( sMsg ); + xbase->WriteLogMessage( GetErrorMessage( rc )); + + sMsg.Sprintf( "Table Name = [%s]", GetFqFileName().Str()); + xbase->WriteLogMessage( sMsg ); + sMsg.Sprintf( "Alias Name = [%s]", sAlias.Str()); + xbase->WriteLogMessage( sMsg ); + + xbFclose(); + if( RecBuf ){ + free( RecBuf ); + RecBuf = NULL; + } + if( RecBuf2 ){ + free( RecBuf2 ); + RecBuf2 = NULL; + } + if( SchemaPtr ){ + free( SchemaPtr ); + SchemaPtr = NULL; + } + + InitVars(); + if( rc != XB_FILE_EXISTS ) + xbase->RemoveTblFromTblList( sAlias ); + } + + if( rc == XB_NO_ERROR ) + iDbfStatus = XB_OPEN; + + return rc; +} + +/************************************************************************/ +//! @brief Get version. +/*! + The version info can be retrieved to determine + which class is being used for a given dbf instance. + \returns 4 +*/ + +xbInt16 xbDbf4::GetVersion() const { + return 4; +} + +/************************************************************************/ +//! @brief Open dbf file/table. +/*! + \param sTableName DBF table name. + \param sAlias Table alias + \param iOpenMode XB_READ
XB_READ_WRITE + \param iShareMode XB_SINGLE_USER
XB_MULTI_USER + \returns Return Codes +*/ + +xbInt16 xbDbf4::Open( const xbString & sTableName, const xbString & sAlias, + xbInt16 iOpenMode, xbInt16 iShareMode ){ + xbInt16 i, j, iRc = XB_NO_ERROR; + xbInt16 iErrorStop = 0; + char buf[33]; + char *p; + + #ifdef XB_MEMO_SUPPORT + iMemoFieldCnt = 0; + #endif + + try{ + /* verify the file is not already open */ + if( iDbfStatus != XB_CLOSED ){ + iErrorStop = 100; + iRc = XB_ALREADY_OPEN; + throw iRc; + } + /* copy the file name to the class variable */ + SetFileName( sTableName ); + this->sAlias = sAlias; + + if( !FileExists()){ + iErrorStop = 110; + iRc = XB_FILE_NOT_FOUND; + throw iRc; + } + + if(( iRc = xbase->AddTblToTblList( this, GetFqFileName(), sAlias )) != XB_NO_ERROR ){ + iErrorStop = 120; + throw iRc; + } + + /* open the file */ + if(( iRc = xbFopen( iOpenMode, iShareMode )) != XB_NO_ERROR ){ + iErrorStop = 130; + throw iRc; + } + + /* copy the header into memory */ + if(( iRc = ReadHeader( 1, 0 )) != XB_NO_ERROR ){ + iErrorStop = 140; + throw iRc; + } + + /* check the version */ + //if(( xFileVersion = DetermineXbaseTableVersion( cVersion )) != 4 ){ + if(( cVersion & 0x07 ) != 3 ){ + iErrorStop = 150; + iRc = XB_FILE_TYPE_NOT_SUPPORTED; + throw iRc; + } + iFileVersion = 4; + + /* calculate the number of fields */ + if( cVersion == (char)0x30 ) { + iNoOfFields = ( uiHeaderLen - 296 ) / 32 ; + } else { + iNoOfFields = ( uiHeaderLen - 33 ) / 32; + } + + if(( RecBuf = (char *) malloc( uiRecordLen )) == NULL ){ + iErrorStop = 160; + iRc = XB_NO_MEMORY; + throw iRc; + } + + if(( RecBuf2 = (char *) malloc( uiRecordLen )) == NULL ) { + iErrorStop = 170; + iRc = XB_NO_MEMORY; + throw iRc; + } + + if((SchemaPtr=(xbSchemaRec *)malloc((size_t) iNoOfFields * sizeof( xbSchemaRec ))) == NULL){ + iErrorStop = 180; + iRc = XB_NO_MEMORY; + throw iRc; + } + + memset( SchemaPtr, 0x00, (size_t) iNoOfFields * (size_t) sizeof( xbSchemaRec )); + /* copy field info into memory */ + for( i = 0, j = 1; i < iNoOfFields; i++ ){ + xbFseek( ((xbInt64)i*32+32), SEEK_SET ); + xbFread( &buf, 1, 32 ); + p = buf; + for( int x = 0; x < 10 && buf[x]; x++ ){ + SchemaPtr[i].cFieldName[x] = buf[x]; + } + p = buf + 11; + SchemaPtr[i].cType = *p++; + SchemaPtr[i].pAddress = RecBuf + j; + SchemaPtr[i].pAddress2 = RecBuf2 + j; + SchemaPtr[i].cFieldLen = (unsigned char) *( p + 4 ); + SchemaPtr[i].cNoOfDecs = (unsigned char) *( p + 5 ); + SchemaPtr[i].cIxFlag = (unsigned char) *( p + 19 ); + j += SchemaPtr[i].cFieldLen; + #ifdef XB_MEMO_SUPPORT + if( (SchemaPtr[i].cType == 'M' || SchemaPtr[i].cType == 'B' || SchemaPtr[i].cType == 'O' )) + iMemoFieldCnt++; + #endif + } + ulCurRec = 0L; + iDbfStatus = XB_OPEN; + if(( iRc = BlankRecord()) != XB_NO_ERROR ){ + iErrorStop = 190; + throw iRc; + } + + + #ifdef XB_MEMO_SUPPORT + if( iMemoFieldCnt > 0 ){ /* does this table have memo fields ? */ + + // build the file name + xbString sMfn = GetFqFileName(); /* memo file name, same as filename except ends with a "t", not an "f" */ + xbUInt32 ulMfnLen = sMfn.Len(); + if( sMfn[ulMfnLen] == 'F' ) + sMfn.PutAt( ulMfnLen, 'T' ); + else + sMfn.PutAt( ulMfnLen, 't' ); + xbFile fTemp( xbase ); + fTemp.SetFileName( sMfn ); + + Memo = new xbMemoDbt4( this, fTemp.GetFqFileName()); + + if(( iRc = Memo->OpenMemoFile()) != XB_NO_ERROR ){ + iErrorStop = 200; + throw iRc; + } + } + #endif + + #ifdef XB_MDX_SUPPORT + +// printf( "cIndexFlag [%x]\n", cIndexFlag ); + + if( cIndexFlag ){ + // create the file name + xbString sIxFileName = GetFqFileName(); + sIxFileName.Trim(); + xbUInt32 lLen = sIxFileName.Len(); + sIxFileName.PutAt( lLen-2, 'M' ); + sIxFileName.PutAt( lLen-1, 'D' ); + sIxFileName.PutAt( lLen, 'X' ); + if(( iRc = OpenIndex( "MDX", sIxFileName )) != XB_NO_ERROR ){ + iErrorStop = 210; + throw iRc; + } + } + #endif + + } + catch ( xbInt16 iRc ) + { + xbString sMsg; + sMsg.Sprintf( "xbdbf4::Open() Exception Caught Error Stop = [%d] iRc = [%d] ShareMode = [%d] OpenMode = [%d]", iErrorStop, iRc, iShareMode, iOpenMode ); + xbase->WriteLogMessage( sMsg ); + xbase->WriteLogMessage( GetErrorMessage( iRc )); + xbFclose(); + if( RecBuf ){ + free( RecBuf ); + RecBuf = NULL; + } + if( RecBuf2 ){ + free( RecBuf2 ); + RecBuf2 = NULL; + } + if( SchemaPtr ){ + free( SchemaPtr ); + SchemaPtr = NULL; + } + InitVars(); + +#ifdef XB_MEMO_SUPPORT + if( Memo ){ + Memo->CloseMemoFile(); + delete Memo; + Memo = NULL; + } +#endif + } + + if( iRc == XB_NO_ERROR ) + iDbfStatus = XB_OPEN; + + return iRc; +} + +/************************************************************************/ +//! @brief Rename table. +/*! + This routine renames a table, associated memo, mdx and inf files + \param sNewName - New file name. + \returns Return Codes +*/ +xbInt16 xbDbf4::Rename( const xbString sNewName ){ + + xbInt16 iRc = XB_NO_ERROR; + xbInt16 iErrorStop = 0; + + xbString sNewDbf; + + #ifdef XB_MEMO_SUPPORT + xbString sNewDbt; + xbBool bDbtRenamed = xbFalse; + xbString sThisDbt; + #endif + + #ifdef XB_MDX_SUPPORT + xbString sNewMdx; + xbBool bMdxRenamed = xbFalse; + xbString sThisMdx; + #endif + + #ifdef XB_INF_SUPPORT + xbString sNewInf; + xbString sThisInf; + xbBool bInfRenamed = xbFalse; + #endif // XB_INF_SUPPORT + + xbBool bDbfRenamed = xbFalse; + + #ifdef XB_LOCKING_SUPPORT + xbBool bLocked = xbFalse; + #endif // XB_LOCKIN_SUPPORT + + + try{ + + xbString sDir; + xbString sFile; + xbString sExt; + xbString sNewNameWoExt; + sNewNameWoExt.Set( sNewName ); + if( sNewName.Pos( ".DBF" ) > 0 ) + sNewNameWoExt.Left( sNewName.Len() - 4 ); + +// std::cout << "NewName wo ext = [" << sNewNameWoExt.Str() << "]\n"; + + GetFileDirPart ( sDir ); + GetFileNamePart( sFile ); + GetFileExtPart ( sExt ); + + sNewDbf.Sprintf( "%s%s.DBF", sDir.Str(), sNewNameWoExt.Str()); + + #ifdef XB_MEMO_SUPPORT + sNewDbt.Sprintf( "%s%s.DBT", sDir.Str(), sNewNameWoExt.Str()); + if( FileExists( sNewDbt )) return XB_FILE_EXISTS; + sThisDbt.Sprintf( "%s%s.DBT", sDir.Str(), sFile.Str()); + #endif + + #ifdef XB_MDX_SUPPORT + sNewMdx.Sprintf( "%s%s.MDX", sDir.Str(), sNewNameWoExt.Str()); + if( FileExists( sNewMdx )) return XB_FILE_EXISTS; + sThisMdx.Sprintf( "%s%s.MDX", sDir.Str(), sFile.Str()); + #endif + + #ifdef XB_INF_SUPPORT + sNewInf.Sprintf( "%s%s.INF", sDir.Str(), sNewNameWoExt.Str()); + if( FileExists( sNewInf )) return XB_FILE_EXISTS; + sThisInf.Sprintf( "%s%s.INF", sDir.Str(), sFile.Str()); + #endif // XB_INF_SUPPORT + + +/* + std::cout << "xbDbf3::Rename dir = [" << sDir.Str() << "] file = [" << sFile.Str() << "] ext = [" << sExt.Str() << "]\n"; + std::cout << "xbDbf3::Rename new dbf = [" << sNewDbf.Str() << "]\n"; + std::cout << "xbDbf3::Rename new dbt = [" << sNewDbt.Str() << "]\n"; + std::cout << "xbDbf3::Rename new inf = [" << sNewInf.Str() << "]\n"; + std::cout << "xbDbf3::Rename new mdx = [" << sNewMdx.Str() << "]\n"; +*/ + + if( FileExists( sNewDbf )) return XB_FILE_EXISTS; + + #ifdef XB_LOCKING_SUPPORT + if( GetAutoLock() ){ + if(( iRc = LockTable( XB_LOCK )) != XB_NO_ERROR ){ + iErrorStop = 100; + throw iRc; + } + bLocked = xbTrue; + } + #endif + + xbInt16 iOpenMode = GetOpenMode(); + xbInt16 iShareMode = GetShareMode(); + xbBool bWasOpen = xbFalse; + if( FileIsOpen() ){ + bWasOpen = xbTrue; + if(( iRc = xbFclose()) != XB_NO_ERROR ){ + iErrorStop = 110; + throw iRc; + } + } + + if(( iRc = xbRename( GetFqFileName().Str(), sNewDbf.Str())) != XB_NO_ERROR ){ + iErrorStop = 120; + throw iRc; + } else { + bDbfRenamed = xbTrue; + } + xbString sNameWext; + sNameWext.Sprintf( "%s.DBF", sNewNameWoExt.Str()); + SetFileName( sNameWext ); + + + if( bWasOpen ){ + if(( iRc = xbFopen( iOpenMode, iShareMode )) != XB_NO_ERROR ){ + iErrorStop = 130; + throw iRc; + } + } + + #ifdef XB_MEMO_SUPPORT + if( FileExists( sThisDbt )){ + if(( iRc = Memo->xbFseek( 8, SEEK_SET )) != XB_NO_ERROR ){ + iErrorStop = 140; + throw iRc; + } + + sNewNameWoExt.PadRight( ' ', 8 ); + for( int i = 1; i < 9; i++ ) + Memo->xbFputc( sNewNameWoExt[i] ); + + if( bWasOpen ){ + if(( iRc = Memo->xbFclose()) != XB_NO_ERROR ){ + iErrorStop = 150; + throw iRc; + } + } + + Memo->SetFileName( sNewDbt ); + if(( xbRename( sThisDbt.Str(), sNewDbt.Str())) != XB_NO_ERROR ){ + iErrorStop = 160; + throw iRc; + } + + if( bWasOpen ){ + if(( iRc = Memo->xbFopen( iOpenMode, iShareMode )) != XB_NO_ERROR ){ + iErrorStop = 150; + throw iRc; + } + } + + bDbtRenamed = xbTrue; + } + #endif + + #ifdef XB_MDX_SUPPORT + if( FileExists( sThisMdx )){ + xbIxMdx *ixMdx; + xbString s; + xbBool bMdxFound = xbFalse; + xbIxList *ixList = GetIxList(); + while( ixList && !bMdxFound ){ + s = ixList->sFmt->Str(); + if( s == "MDX" ){ + ixMdx = (xbIxMdx *) ixList->ix; + bMdxFound = xbTrue; + } + } + + if( bMdxFound ){ + if(( iRc = ixMdx->xbFseek( 4, SEEK_SET )) != XB_NO_ERROR ){ + iErrorStop = 180; + throw iRc; + } + + sNewNameWoExt.PadRight( ' ', 8 ); + for( int i = 1; i < 9; i++ ) + ixMdx->xbFputc( sNewNameWoExt[i] ); + + if( bWasOpen ){ + if(( iRc = ixMdx->xbFclose()) != XB_NO_ERROR ){ + iErrorStop = 190; + throw iRc; + } + } + + ixMdx->SetFileName( sNewMdx ); + if(( xbRename( sThisMdx.Str(), sNewMdx.Str())) != XB_NO_ERROR ){ + iErrorStop = 200; + throw iRc; + } + + if( bWasOpen ){ + if(( iRc = ixMdx->xbFopen( iOpenMode, iShareMode )) != XB_NO_ERROR ){ + iErrorStop = 210; + throw iRc; + } + } + bMdxRenamed = xbTrue; + } + } + #endif // XB_MDX_SUPPORT + + #ifdef XB_INF_SUPPORT + if( FileExists( sThisInf )){ + if(( xbRename( sThisInf.Str(), sNewInf.Str())) != XB_NO_ERROR ){ + iErrorStop = 180; + throw iRc; + } else { + bInfRenamed = xbTrue; + } + } + #endif // XB_INF_SUPPORT + + // rename the table in the table list + xbTblList *tle = xbase->GetTblListEntry( this ); + if( tle ){ + tle->psFqTblName->Set( GetFqFileName().Str()); + tle->psTblAlias->Set( sNewNameWoExt.Str()); + } + + + } + catch ( xbInt16 iRc ) + { + xbString sMsg; + sMsg.Sprintf( "xbdbf4::Rename() Exception Caught Error Stop = [%d] iRc = [%d]", iErrorStop, iRc ); + xbase->WriteLogMessage( sMsg ); + xbase->WriteLogMessage( GetErrorMessage( iRc )); + + // attempt to reverse things out if unsuccessful + if( bDbfRenamed ){ + + #ifdef XB_MEMO_SUPPORT + if( bDbtRenamed ){ + xbRename( sNewDbt.Str(), sThisDbt.Str()); + } + #endif + + #ifdef XB_MDX_SUPPORT + if( bMdxRenamed ){ + xbRename( sNewMdx.Str(), sThisMdx.Str()); + } + #endif + + #ifdef XB_INF_SUPPORT + if( bInfRenamed ){ + xbRename( sNewInf.Str(), sNewInf.Str()); + } + #endif // XB_INF_SUPPORT + } + + #ifdef XB_LOCKING_SUPPORT + if( GetAutoLock() ){ + iRc = LockTable( XB_UNLOCK ); + } + #endif + + } + + #ifdef XB_LOCKING_SUPPORT + if( bLocked ){ + LockTable( XB_UNLOCK ); + } + #endif + + return iRc; +} + +/************************************************************************/ +#ifdef XB_MEMO_SUPPORT + +//! @brief Create memo block size. +/*! + This routine sets the memo file block size. This value is used when + the memo file is created so you if you want to change it, this must be + called before creating the table. + + The default size for version 4 is 1024. + + \param ulBlockSize - Block size, must be evenly divisible by 512. + \returns XB_INVALID_BLOCK_SIZE
XB_NO_ERROR +*/ + +xbInt16 xbDbf4::SetCreateMemoBlockSize( xbUInt32 ulBlockSize ){ + + if( ulBlockSize % 512 ) + return XB_INVALID_BLOCK_SIZE; + else + ulCreateMemoBlockSize = ulBlockSize; + + return XB_NO_ERROR; +} +#endif // XB_MEMO_SUPPORT +/************************************************************************/ +//! @brief Set version. +/*! + Sets the version to 4. The version info can be retrieved to determine + which class is being used for a given dbf instance. + \returns 4 +*/ +xbInt16 xbDbf4::SetVersion() { + iFileVersion = 4; + return iFileVersion; +} +/************************************************************************/ +//! @brief Validate schema +/*! + This routine verifies the field types are valid for Dbase IV (tm). + + \param s Pointer to schema structure with field definitions. + + \returns Number of fields or XB_INVALID_FIELD_TYPE. +*/ + + +xbInt16 xbDbf4::ValidateSchema( xbSchema * s ){ + + xbInt16 iFieldCnt = 0; + uiRecordLen = 0; + + // Count the number of fields and check paramaters + xbInt16 i = 0; + while( s[i].cType != 0 ){ + iFieldCnt++; + // Version IV field types + if( s[i].cType != 'C' && + s[i].cType != 'N' && + s[i].cType != 'F' && + s[i].cType != 'D' && + #ifdef XB_MEMO_SUPPORT + s[i].cType != 'M' && + #endif /* XB_MEMO_SUPPORT */ + s[i].cType != 'L' ){ + return XB_INVALID_FIELD_TYPE; + } + + if(s[i].cType == 'D'){ + s[i].iFieldLen = 8; + s[i].iNoOfDecs = 0; + } + + else if(s[i].cType == 'C') + s[i].iNoOfDecs = 0; + + // check for numeric fields which are too long + else if((s[i].cType == 'N' || s[i].cType == 'F') && s[i].iFieldLen > 19 ){ + return XB_INVALID_FIELD_LEN; + } + + // field len must be greater then number of decimals + else if((s[i].cType == 'N' || s[i].cType == 'F') && s[i].iFieldLen < s[i].iNoOfDecs ){ + return XB_INVALID_FIELD_LEN; + } + + #ifdef XB_MEMO_SUPPORT + else if(s[i].cType == 'M'){ + s[i].iFieldLen = 10; + s[i].iNoOfDecs = 0; + } + #endif // XB_MEMO_SUPPORT + + uiRecordLen += s[i].iFieldLen; + i++; + } + return iFieldCnt; +} + +} /* namespace */ +#endif /* XB_DBF4_SUPPORT */ \ No newline at end of file -- cgit v1.2.3