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

📄 bdedatabase.cpp

📁 程序1
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	{
		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 + -