📄 bdedatabase.cpp
字号:
{
s.Format("%s\n\nBorland Database Engine returned the following error:\n%s",
szMessage, dbi_status);
}
else
{
s.Format("Borland Database Engine Error:\n%s",
dbi_status);
}
AfxMessageBox(s, MB_OK | MB_ICONEXCLAMATION);
return ErrorValue;
}
// function to make sure the BDE has been initialize before any function calls
BOOL CBdeDatabase::CheckInitialization(LPCTSTR szOperation /* = NULL */)
{
if (m_bInitialized) return TRUE;
// if this happens, it is not BDE's fault, it is the programmers!
throw new CBdeException(DBIERR_NONE, BDEEXERR_NOTINITIALIZED,
m_szTableName, m_szDatabaseName, szOperation);
return FALSE;
}
// function throws an exception if the cursor position is not valid
// meaning a database has not been opened
BOOL CBdeDatabase::CheckValidCursor(LPCTSTR szOperation /* = NULL */)
{
// check for initialization
if (!CheckInitialization(szOperation)) return FALSE;
// check the validity of the cursor
if (m_hCursor != NULL && m_hDb != NULL) return TRUE;
throw new CBdeException(DBIERR_NONE, BDEEXERR_INVALIDCURSOR,
m_szTableName, m_szDatabaseName, szOperation);
return FALSE;
}
// function throws an exception if the database is NOT in edit mode
BOOL CBdeDatabase::CheckEditMode(LPCTSTR szOperation /* = NULL */)
{
if (m_nEditMode != EDITMODE_NONE) return TRUE;
throw new CBdeException(DBIERR_NONE, BDEEXERR_NOTINEDITMODE,
m_szTableName, m_szDatabaseName, szOperation);
return FALSE;
}
// function throws an exception if the database IS in edit mode
BOOL CBdeDatabase::CheckNotEditMode(LPCTSTR szOperation /* = NULL */)
{
if (m_nEditMode == EDITMODE_NONE) return TRUE;
throw new CBdeException(DBIERR_NONE, BDEEXERR_ALREADYINEDITMODE,
m_szTableName, m_szDatabaseName, szOperation);
return FALSE;
}
/////////////////////////////////////////////////////////////
// Database Navigation Functions
void CBdeDatabase::MoveFirst()
{
// Throw an exception if database is in Edit mode
if (!CheckValidCursor("Failed to move to beginning of table.")) return;
if (!CheckNotEditMode("Failed to move to beginning of table.")) return;
DBIResult dbiResult = DbiSetToBegin(m_hCursor);
if (dbiResult == DBIERR_NONE || dbiResult == DBIERR_BOF)
{
dbiResult = DbiGetNextRecord(m_hCursor, dbiNOLOCK, NULL, NULL);
return;
}
CString s;
s.Format("Failed to move to the beginning of table %s.", m_szTableName);
throw new CBdeException(dbiResult, m_szTableName, m_szDatabaseName, s);
dbiResult = DbiGetNextRecord(m_hCursor, dbiNOLOCK, NULL, NULL);
}
void CBdeDatabase::MoveNext()
{
// Throw an exception if database is in Edit mode
if (!CheckValidCursor("Failed to move to next record.")) return;
if (!CheckNotEditMode("Failed to move to next record.")) return;
DBIResult dbiResult = DbiGetNextRecord(m_hCursor, dbiNOLOCK, NULL, NULL);
if (dbiResult == DBIERR_NONE) return;
if (dbiResult == DBIERR_EOF)
{
dbiResult = DbiGetPriorRecord(m_hCursor, dbiNOLOCK, NULL, NULL);
return;
}
CString s;
s.Format("Failed to move to the next record in table %s.", m_szTableName);
throw new CBdeException(dbiResult, m_szTableName, m_szDatabaseName, s);
}
void CBdeDatabase::MovePrior()
{
// Throw an exception if database is in Edit mode
if (!CheckValidCursor("Failed to move to previous record.")) return;
if (!CheckNotEditMode("Failed to move to previous record.")) return;
DBIResult dbiResult = DbiGetPriorRecord(m_hCursor, dbiNOLOCK, NULL, NULL);
if (dbiResult == DBIERR_NONE) return;
if (dbiResult == DBIERR_BOF)
{
dbiResult = DbiGetNextRecord(m_hCursor, dbiNOLOCK, NULL, NULL);
return;
}
CString s;
s.Format("Failed to move to the previous record in table %s.", m_szTableName);
throw new CBdeException(dbiResult, m_szTableName, m_szDatabaseName, s);
}
void CBdeDatabase::MoveLast()
{
// Throw an exception if database is in Edit mode
if (!CheckValidCursor("Failed to move to end of table.")) return;
if (!CheckNotEditMode("Failed to move to end of table.")) return;
DBIResult dbiResult = DbiSetToEnd(m_hCursor);
if (dbiResult == DBIERR_NONE || dbiResult == DBIERR_EOF)
{
dbiResult = DbiGetPriorRecord(m_hCursor, dbiNOLOCK, NULL, NULL);
return;
}
CString s;
s.Format("Failed to move to the end of table %s.", m_szTableName);
throw new CBdeException(dbiResult, m_szTableName, m_szDatabaseName, s);
}
LONG CBdeDatabase::GetRecordCount()
{
// Throw an exception if database is in Edit mode
if (!CheckValidCursor("Failed to get number of records.")) return -1L;
ASSERT(m_hCursor != NULL);
UINT32 nRecNum;
DBIResult dbiResult = DbiGetRecordCount(m_hCursor, &nRecNum);
if (dbiResult == DBIERR_NONE) return (LONG)nRecNum;
CString s;
s.Format("Failed to determine the number of records in table %s.", m_szTableName);
throw new CBdeException(dbiResult, m_szTableName, m_szDatabaseName, s);
return -1L;
}
BOOL CBdeDatabase::IsBOF()
{
// Throw an exception if database is in Edit mode
if (!CheckValidCursor()) return FALSE;
if (!CheckNotEditMode()) return FALSE;
DBIResult dbiResult;
BOOL bRetVal;
// Check if we are at the end of the table.
dbiResult = DbiGetPriorRecord(m_hCursor, dbiNOLOCK, NULL, NULL);
if (dbiResult == DBIERR_BOF) bRetVal = TRUE;
else bRetVal = FALSE;
// Put the cursor back to where it was before entering this function.
DbiGetNextRecord(m_hCursor, dbiNOLOCK, NULL, NULL);
return bRetVal;
}
BOOL CBdeDatabase::IsEOF()
{
// Throw an exception if database is in Edit mode
if (!CheckValidCursor()) return FALSE;
if (!CheckNotEditMode()) return FALSE;
DBIResult dbiResult;
BOOL bRetVal;
// Check if we are at the end of the table.
dbiResult = DbiGetNextRecord(m_hCursor, dbiNOLOCK, NULL, NULL);
if (dbiResult == DBIERR_EOF) bRetVal = TRUE;
else bRetVal = FALSE;
// Put the cursor back to where it was before entering this function.
DbiGetPriorRecord(m_hCursor, dbiNOLOCK, NULL, NULL);
return bRetVal;
}
/////////////////////////////////////////////////////////////////////////////
// Functions to read field values
CString CBdeDatabase::GetFieldAsString(UINT16 nFieldNumber, BOOL* pbBlank)
{
// Throw an exception if database is in Edit mode
if (!CheckValidCursor("Failed to get field value.")) return "";
if (!CheckNotEditMode("Failed to get field value.")) return "";
DBIResult dbiResult = DBIERR_NONE;
CString strValue;
CString strError;
CURProps curProps; // Table Properties
pFLDDesc pFldDesc = NULL; // field information
pBYTE pRecBuf = NULL; // Record Buffer
int nBdeExError = 0;
// get the cursor properties for the table
dbiResult = DbiGetCursorProps(m_hCursor, &curProps);
if (dbiResult != DBIERR_NONE)
{
strError.Format("Failed to get cursor properties.");
throw new CBdeException(dbiResult, m_szTableName, m_szDatabaseName, strError);
return "";
}
// make sure the field number is valid
if (nFieldNumber < 1 || nFieldNumber > curProps.iFields)
{
strError.Format("Invalid field index %d. Valid numbers are between 1 and %d.",
nFieldNumber, curProps.iFields);
throw new CBdeException(DBIERR_NONE, BDEEXERR_INVALIDFIELDINDEX,
m_szTableName, m_szDatabaseName, strError);
return "";
}
// allocate memory for the field descriptors
pFldDesc = (pFLDDesc)malloc(curProps.iFields * sizeof(FLDDesc));
if (pFldDesc == NULL)
{
// Throw exception for DBIERR_NOMEMORY
throw new CBdeException(DBIERR_NOMEMORY);
return "";
}
dbiResult = DbiGetFieldDescs(m_hCursor, pFldDesc);
if (dbiResult != DBIERR_NONE)
{
free(pFldDesc);
strError.Format("Failed to retrieve field information.");
throw new CBdeException(dbiResult, m_szTableName, m_szDatabaseName, strError);
return "";
}
// save the size and type of the field
UINT16 nSize = pFldDesc[nFieldNumber-1].iLen;
UINT16 nFieldType = pFldDesc[nFieldNumber-1].iFldType;
UINT16 nFieldSubType = pFldDesc[nFieldNumber-1].iSubType;
UINT16 nUnits = pFldDesc[nFieldNumber-1].iUnits2;
free(pFldDesc); // clean up the field descriptor
pFldDesc = NULL;
// allocate the record buffer for the table
pRecBuf = (pBYTE) malloc(curProps.iRecBufSize * sizeof(BYTE));
if (pRecBuf == NULL)
{
strError.Format("Insufficient memory to get field number %d.", nFieldNumber);
throw new CBdeException(DBIERR_NOMEMORY, m_szTableName, m_szDatabaseName, strError);
return "";
}
// fill the record buffer with information
dbiResult = DbiGetRecord(m_hCursor, dbiNOLOCK, pRecBuf, NULL);
if (dbiResult != DBIERR_NONE)
{
free(pRecBuf);
strError.Format("Failed to get record information.");
throw new CBdeException(dbiResult, m_szTableName, m_szDatabaseName, strError);
return "";
}
// allocate memory for the string buffer to recieve data
pBYTE pDestBuf = (pBYTE)malloc(nSize*sizeof BYTE);
memset(pDestBuf, 0, nSize*sizeof BYTE);
if (pDestBuf == NULL)
{
// Throw memory exception here
free(pRecBuf);
strError.Format("Failed to get record information.");
throw new CBdeException(DBIERR_NOMEMORY, m_szTableName, m_szDatabaseName, strError);
return "";
}
// get the actual field value
switch (nFieldType)
{
case fldBYTES: // Bytes
case fldZSTRING: // String
{
dbiResult = DbiGetField(m_hCursor, nFieldNumber, pRecBuf, (pBYTE)pDestBuf, pbBlank);
strValue.Format("%s", (char*)pDestBuf);
break;
}
case fldFLOAT:
{
double f;
dbiResult = DbiGetField(m_hCursor, nFieldNumber, pRecBuf, (pBYTE)&f, pbBlank);
if (*pbBlank == FALSE)
{
if (nFieldSubType == fldstMONEY)
{
strValue.Format("$%.2lf", f);
}
else
{
strValue.Format("%g", f);
}
}
break;
}
case fldBCD:
{
dbiResult = DbiGetField(m_hCursor, nFieldNumber, pRecBuf,
(pBYTE)pDestBuf, pbBlank);
if (*pbBlank == FALSE)
{
double lfFloat;
DbiBcdToFloat((FMTBcd *)pDestBuf, &lfFloat);
strValue.Format("%.*lf", nUnits, lfFloat);
}
break;
}
case fldDATE:
{
dbiResult = DbiGetField(m_hCursor, nFieldNumber, pRecBuf,
(pBYTE)pDestBuf, pbBlank);
if (*pbBlank == FALSE)
{
// Here is a difficult situation...
// dates are returned as 4 bytes, but in the 32-bit world
// the DATE type is 8 bytes. Typcasting directly to DATE
// does not work. We have to type cast to 32 bit int, then
// to 64-bit int, and then to DATE
INT32 n32 = (*(INT32 *)pDestBuf);
strValue = FormatDate(n32);
}
break;
}
case fldTIME:
{
dbiResult = DbiGetField(m_hCursor, nFieldNumber, pRecBuf,
(pBYTE)pDestBuf, pbBlank);
if (*pbBlank == FALSE)
{
strValue = FormatTime(*(TIME *)pDestBuf);
}
break;
}
case fldTIMESTAMP:
{
// size of timestamp is 8
dbiResult = DbiGetField(m_hCursor, nFieldNumber, pRecBuf,
(pBYTE)pDestBuf, pbBlank);
if (*pbBlank == FALSE)
{
TIMESTAMP dt = *(TIMESTAMP*)pDestBuf;
strValue = FormatTimeStamp(dt);
}
break;
}
case fldINT16:
{
INT16 n;
dbiResult = DbiGetField(m_hCursor, nFieldNumber, pRecBuf, (pBYTE)&n, pbBlank);
if (*pbBlank == FALSE)
{
strValue.Format("%d", n);
}
break;
}
case fldUINT16:
{
UINT16 n;
dbiResult = DbiGetField(m_hCursor, nFieldNumber, pRecBuf, (pBYTE)&n, pbBlank);
if (*pbBlank == FALSE)
{
strValue.Format("%d", n);
}
break;
}
case fldINT32:
{
INT32 n;
dbiResult = DbiGetField(m_hCursor, nFieldNumber, pRecBuf, (pBYTE)&n, pbBlank);
if (*pbBlank == FALSE)
{
strValue.Format("%d", n);
}
break;
}
case fldUINT32:
{
UINT32 n;
dbiResult = DbiGetField(m_hCursor, nFieldNumber, pRecBuf, (pBYTE)&n, pbBlank);
if (*pbBlank == FALSE)
{
strValue.Format("%d", n);
}
break;
}
case fldBOOL:
{
dbiResult = DbiGetField(m_hCursor, nFieldNumber, pRecBuf, (pBYTE)pDestBuf, pbBlank);
if (*pbBlank == FALSE)
{
if (*(BYTE*)pDestBuf == 0) strValue = "FALSE";
else strValue = "TRUE";
}
break;
}
case fldBLOB: // NOTE: This does not work on dBase files.
{
if (nFieldSubType == fldstMEMO)
{
UINT32 ulBlobSize; // Size of the BLOB
// Open the blob
dbiResult = DbiOpenBlob(m_hCursor, pRecBuf, nFieldNumber, dbiREADONLY);
if (dbiResult != DBIERR_NONE) break;
// Determine the size of the BLOB.
dbiResult = DbiGetBlobSize(m_hCursor, pRecBuf, nFieldNumber, &ulBlobSize);
if (dbiResult != DBIERR_NONE) break;
// Get the BLOB from the table.
dbiResult = DbiGetBlob(m_hCursor, pRecBuf, nFieldNumber, 0,
ulBlobSize, (pBYTE)pDestBuf, &ulBlobSize);
pDestBuf[ulBlobSize + 1] = '\0';
strValue.Format("%s", pDestBuf);
DbiFreeBlob(m_hCursor, pRecBuf, nFieldNumber);
if (dbiResult != DBIERR_NONE) break;
}
else
{
// Handle non-memo formats here
nBdeExError = BDEEXERR_UNSUPPORTEDBLOBTYPE;
}
break;
}
default:
{
nBdeExError = BDEEXERR_UNSUPPORTEDFIELDTYPE;
break;
}
} // end of swtich
// process the final error codes
if (dbiResult != DBIERR_NONE || nBdeExError != 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -