📄 bdedatabase.cpp
字号:
/////////////////////////////////////////////////////////////////
// BdeDatabase.cpp -- Implementation of the CBdeDatabase class
// This class provides access to the Borland Database Engine
// For this to work, the BDE directory must be in the computers PATH statement
// Link with Idapi32m.lib,
#include "stdafx.h"
#include "BdeDatabase.h"
#include "BdeException.h"
BOOL CBdeDatabase::m_bInitialized = FALSE;
///////////////////////////////////////////////////////////////////
// CBdeDatabase Construction/Destruction
CBdeDatabase::CBdeDatabase()
{
m_hDb = NULL;
m_hCursor = NULL;
m_szTableName[0] = '\0';
m_szDatabaseName[0] = '\0';
m_szPrivateDir[0] = '\0';
m_pEditRecordBuffer = NULL;
m_nEditMode = 0;
m_nTableType = -1;
}
CBdeDatabase::~CBdeDatabase()
{
// perform any cleanup here
CloseDatabase();
}
////////////////////////////////////////////////////////////////////
// CBdeDatabase Operations
/*BOOL CBdeDatabase::OpenDatabase(LPCTSTR szAlias, BOOL bReadOnly, BOOL bExclusive)
{
} */
// function to open a database given the full path and table name in a single string
// Table type is determined by file extension
BOOL CBdeDatabase::OpenDatabase(LPCTSTR szFullPath,
BOOL bReadOnly, BOOL bExclusive, LPCTSTR szPrivateDir)
{
// split the file name into it's different parts
char drive[_MAX_DRIVE];
char dir[_MAX_DIR];
char fname[_MAX_FNAME];
char ext[_MAX_EXT];
_splitpath(szFullPath, drive, dir, fname, ext );
// use the file extension to determine the file type
int nTableType;
if (_stricmp(ext, ".txt") == 0) nTableType = TABLETYPE_TEXT;
else if (_stricmp(ext, ".csv") == 0) nTableType = TABLETYPE_TEXT;
else if (_stricmp(ext, ".dbf") == 0) nTableType = TABLETYPE_DBASE;
else nTableType = TABLETYPE_PARADOX;
CString strPath;
strPath.Format("%s%s", drive, dir);
return OpenDatabase(strPath, fname, nTableType, bReadOnly, bExclusive, szPrivateDir);
}
// function to open a database given a separate path and table name
BOOL CBdeDatabase::OpenDatabase(LPCTSTR szPath, LPCTSTR szTableName, int nTableType,
BOOL bReadOnly, BOOL bExclusive, LPCTSTR szPrivateDir)
{
if (!CheckInitialization()) return FALSE;
// If database is active, then throw and exception
if (m_hDb != NULL || m_hCursor != NULL)
{
throw new CBdeException(DBIERR_NONE, BDEEXERR_ALREADYOPEN,
m_szTableName, m_szDatabaseName, "");
return FALSE;
}
DBIResult dbiResult;
CString s;
DBIOpenMode eOpenMode;
DBIShareMode eShareMode;
// copy the string constants to the non-const member values
strncpy(m_szTableName, szTableName, DBIMAXNAMELEN-1);
strncpy(m_szDatabaseName, szPath, 254);
if (szPrivateDir != NULL)
strncpy(m_szPrivateDir, szPrivateDir, 254);
else
strncpy(m_szPrivateDir, "", 254);
// Set read only and share mode values
if (bReadOnly) eOpenMode = dbiREADONLY;
else eOpenMode = dbiREADWRITE;
if (bExclusive) eShareMode = dbiOPENEXCL;
else eShareMode = dbiOPENSHARED;
// Open the database
dbiResult = DbiOpenDatabase(
NULL, // Database name - NULL for standard database
NULL, // Database type - NULL for standard database
eOpenMode, // Open mode - Read/Write or Read only
eShareMode, // Share mode - Shared or Exclusive
NULL, // Password - not needed for the STANDARD database
NULL, // Number of optional parameters
NULL, // Field Desc for optional parameters
NULL, // Values for the optional parameters
&m_hDb); // Handle to the database
if (dbiResult != DBIERR_NONE)
{
s.Format("Failed to open database %s.", m_szDatabaseName);
throw new CBdeException(dbiResult, m_szTableName, m_szDatabaseName, s);
return FALSE;
}
return OpenDatabaseHelper(nTableType, eOpenMode, eShareMode, szPrivateDir);
}
// helper function to open the database, it actually opens the tables
// after a database has been opened. It is here to support the different
// variations on opening a database
BOOL CBdeDatabase::OpenDatabaseHelper(int nTableType,
DBIOpenMode eOpenMode, DBIShareMode eShareMode, LPCTSTR szPrivateDir)
{
// before entering this function, the database must have been opened
// but not the table
ASSERT(m_hDb != NULL);
ASSERT(m_hCursor == NULL);
// local variables
DBIResult dbiResult;
CString s;
CHAR szTableType[DBIMAXNAMELEN];
pBYTE pRecBuf = NULL;
CURProps CurProps; // cursor properties
// save the table type
m_nTableType = nTableType;
// set the table directory
dbiResult = DbiSetDirectory(
m_hDb, // Handle to the database which is being modified
m_szDatabaseName); // The new working directory
if (dbiResult != DBIERR_NONE)
{
s.Format("Failed to open database %s.", m_szDatabaseName);
throw new CBdeException(dbiResult, m_szTableName, m_szDatabaseName, s);
goto l_Failure;
}
// set the private dir
if (szPrivateDir != NULL)
{
dbiResult = DbiSetPrivateDir(m_szPrivateDir);
if (dbiResult != DBIERR_NONE)
{
s.Format("Failed to set private directory %s.", m_szPrivateDir);
throw new CBdeException(dbiResult, m_szTableName, m_szDatabaseName, s);
goto l_Failure;
}
} // end of setting private dir
// get the table type and open the table
// Use paradox by default
if (nTableType == TABLETYPE_TEXT)
strcpy(szTableType, szASCII);
else if (nTableType == TABLETYPE_DBASE)
strcpy(szTableType, szDBASE);
else strcpy(szTableType, szPARADOX);
// Open the table
dbiResult = DbiOpenTable( // Step 7
m_hDb, // Handle to the standard database
m_szTableName, // Name of the table
szTableType, // Type of the table - only used for local tables
NULL, // Index Name - Optional
NULL, // IndexTagName - Optional. Only used by dBASE
0, // IndexId - 0 = Primary.
eOpenMode, // Open Mode - Read/Write or Read Only
eShareMode, // Shared mode - SHARED or EXCL
xltFIELD, // Translate mode - Almost always xltFIELD
FALSE, // Unidirectional cursor movement.
NULL, // Optional Parameters.
&m_hCursor); // Handle to the cursor
if (dbiResult != DBIERR_NONE)
{
s.Format("Failed to open table %s in database %s.",
m_szTableName, m_szDatabaseName);
throw new CBdeException(dbiResult, m_szTableName, m_szDatabaseName, s);
goto l_Failure;
}
// get the cursor properties here
dbiResult = DbiGetCursorProps(
m_hCursor, // Handle to the cursor
&CurProps); // Properties of the cursor (table)
if (dbiResult != DBIERR_NONE)
{
s.Format("Failed to get database cursor properties in table %s.", m_szTableName);
throw new CBdeException(dbiResult, m_szTableName, m_szDatabaseName, s);
goto l_Failure;
}
// allocate the memory for the record buffer
pRecBuf = (pBYTE) malloc(CurProps.iRecBufSize * sizeof(BYTE));
if (pRecBuf == NULL)
{
s.Format("Insufficient memory to open table %s.", m_szTableName);
throw new CBdeException(DBIERR_NOMEMORY, m_szTableName, m_szDatabaseName, s);
goto l_Failure;
}
free(pRecBuf);
if (CurProps.iFields > 0) MoveFirst();
return TRUE;
// goto here for cleanup
l_Failure:;
CloseDatabase();
return FALSE;
} // end of OpenDatabase function
// function to initialize the database
BOOL CBdeDatabase::Initialize()
{
// make sure not already initialized
if (m_bInitialized) return TRUE;
// initialize the BDE
DBIResult dbiResult = DbiInit(NULL);
// Check error code
if (dbiResult == DBIERR_NONE)
{
m_bInitialized = TRUE;
return TRUE;
}
Check(dbiResult, "Failed to initialize Borland Database Engine.");
return FALSE;
}
// function to close the database
BOOL CBdeDatabase::CloseDatabase()
{
DBIResult dbiResult;
CString s;
if (m_hDb == NULL) return TRUE; // database was not open to begin with
// cancel any pending edits
Cancel();
// Close the cursor
if (m_hCursor != NULL)
{
dbiResult = DbiCloseCursor(&m_hCursor);
if (dbiResult != DBIERR_NONE)
{
s.Format("Failed to close table %s", m_szTableName);
Check(dbiResult, s);
return FALSE;
}
}
m_hCursor = NULL;
// close the database
dbiResult = DbiCloseDatabase(&m_hDb);
if (dbiResult != DBIERR_NONE)
{
s.Format("Failed to close database %s", m_szDatabaseName);
Check(dbiResult, s);
return FALSE;
}
m_hDb = NULL;
m_szTableName[0] = '\0';
m_szDatabaseName[0] = '\0';
m_nTableType = -1;
return TRUE;
}
// uninitialize the database, this should be last BDE call ever
void CBdeDatabase::Uninitialize()
{
DbiExit();
m_bInitialized = FALSE;
}
/////////////////////////////////////////////////////////////////////
// Functions to GetEnabling flags
BOOL CBdeDatabase::EnableFirst(CBdeDatabase* pBdeDb)
{
if (pBdeDb == NULL) return FALSE;
if (CBdeDatabase::m_bInitialized == FALSE) return FALSE;
if (pBdeDb->IsActive() == FALSE) return FALSE;
if (pBdeDb->GetEditMode() == TRUE) return FALSE;
return TRUE;
}
BOOL CBdeDatabase::EnableNext(CBdeDatabase* pBdeDb)
{
if (pBdeDb == NULL) return FALSE;
if (CBdeDatabase::m_bInitialized == FALSE) return FALSE;
if (pBdeDb->IsActive() == FALSE) return FALSE;
if (pBdeDb->GetEditMode() == TRUE) return FALSE;
return TRUE;
}
BOOL CBdeDatabase::EnablePrior(CBdeDatabase* pBdeDb)
{
if (pBdeDb == NULL) return FALSE;
if (CBdeDatabase::m_bInitialized == FALSE) return FALSE;
if (pBdeDb->IsActive() == FALSE) return FALSE;
if (pBdeDb->GetEditMode() == TRUE) return FALSE;
return TRUE;
}
BOOL CBdeDatabase::EnableLast(CBdeDatabase* pBdeDb)
{
if (pBdeDb == NULL) return FALSE;
if (CBdeDatabase::m_bInitialized == FALSE) return FALSE;
if (pBdeDb->IsActive() == FALSE) return FALSE;
if (pBdeDb->GetEditMode() == TRUE) return FALSE;
return TRUE;
}
BOOL CBdeDatabase::EnableInsert(CBdeDatabase* pBdeDb)
{
if (pBdeDb == NULL) return FALSE;
if (CBdeDatabase::m_bInitialized == FALSE) return FALSE;
if (pBdeDb->IsActive() == FALSE) return FALSE;
if (pBdeDb->GetEditMode() == TRUE) return FALSE;
return TRUE;
}
BOOL CBdeDatabase::EnableEdit(CBdeDatabase* pBdeDb)
{
if (pBdeDb == NULL) return FALSE;
if (CBdeDatabase::m_bInitialized == FALSE) return FALSE;
if (pBdeDb->IsActive() == FALSE) return FALSE;
if (pBdeDb->GetEditMode() == TRUE) return FALSE;
return TRUE;
}
BOOL CBdeDatabase::EnablePost(CBdeDatabase* pBdeDb)
{
if (pBdeDb == NULL) return FALSE;
if (CBdeDatabase::m_bInitialized == FALSE) return FALSE;
if (pBdeDb->IsActive() == FALSE) return FALSE;
if (pBdeDb->GetEditMode() == FALSE) return FALSE;
return TRUE;
}
BOOL CBdeDatabase::EnableCancel(CBdeDatabase* pBdeDb)
{
if (pBdeDb == NULL) return FALSE;
if (CBdeDatabase::m_bInitialized == FALSE) return FALSE;
if (pBdeDb->IsActive() == FALSE) return FALSE;
if (pBdeDb->GetEditMode() == FALSE) return FALSE;
return TRUE;
}
BOOL CBdeDatabase::EnableAppend(CBdeDatabase* pBdeDb)
{
if (pBdeDb == NULL) return FALSE;
if (CBdeDatabase::m_bInitialized == FALSE) return FALSE;
if (pBdeDb->IsActive() == FALSE) return FALSE;
if (pBdeDb->GetEditMode() == TRUE) return FALSE;
return TRUE;
}
BOOL CBdeDatabase::EnableDelete(CBdeDatabase* pBdeDb)
{
if (pBdeDb == NULL) return FALSE;
if (CBdeDatabase::m_bInitialized == FALSE) return FALSE;
if (pBdeDb->IsActive() == FALSE) return FALSE;
if (pBdeDb->GetEditMode() == TRUE) return FALSE;
return TRUE;
}
BOOL CBdeDatabase::EnableOpen(CBdeDatabase* pBdeDb)
{
if (pBdeDb == NULL) return FALSE;
if (CBdeDatabase::m_bInitialized == FALSE) return FALSE;
if (pBdeDb->IsActive() == TRUE) return FALSE;
return TRUE;
}
BOOL CBdeDatabase::EnableClose(CBdeDatabase* pBdeDb)
{
if (pBdeDb == NULL) return FALSE;
if (CBdeDatabase::m_bInitialized == FALSE) return FALSE;
if (pBdeDb->IsActive() == FALSE) return FALSE;
return TRUE;
}
/////////////////////////////////////////////////////////////////////
// Validity checking functions
// function to display an error message from BDE error code
// Most of this is copied from BDE API Help
// this function is not used within the class because all errors are handled as exceptions
DBIResult CBdeDatabase::Check(DBIResult ErrorValue, LPCTSTR szMessage)
{
char dbi_status[DBIMAXMSGLEN * 5] = {'\0'};
DBIMSG dbi_string = {'\0'};
DBIErrInfo ErrInfo;
CString s;
if (ErrorValue == DBIERR_NONE) return ErrorValue;
DbiGetErrorInfo(TRUE, &ErrInfo);
if (ErrInfo.iError == ErrorValue)
{
wsprintf(dbi_status, "%s", ErrInfo.szErrCode);
if (strcmp(ErrInfo.szContext1, ""))
wsprintf(dbi_status, "%s\r\n %s", dbi_status, ErrInfo.szContext1);
if (strcmp(ErrInfo.szContext2, ""))
wsprintf(dbi_status, "%s\r\n %s", dbi_status, ErrInfo.szContext2);
if (strcmp(ErrInfo.szContext3, ""))
wsprintf(dbi_status, "%s\r\n %s", dbi_status, ErrInfo.szContext3);
if (strcmp(ErrInfo.szContext4, ""))
wsprintf(dbi_status, "%s\r\n %s", dbi_status, ErrInfo.szContext4);
}
else
{
DbiGetErrorString(ErrorValue, dbi_string);
wsprintf(dbi_status, "%s", dbi_string);
}
if (szMessage != NULL)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -