Files
envi-code/SourceCode/Code2026/Dimension/DBFCursorSet.cpp
T
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

585 lines
10 KiB
C++

#include "stdafx.h"
#include "DBFCursorset.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
IMPLEMENT_DYNAMIC(CDBFCursorset, CDBFRecordset)
CDBFCursorset::CDBFCursorset(CDBFTableDef* pDBFTable)
{
m_bDesc = FALSE;
m_bShowDeletedRec = TRUE;
m_nCurCursorRecN = -1;
m_bBOF = TRUE;
m_bEOF = TRUE;
m_lpfnIsInclude = NULL;
}
CDBFCursorset::~CDBFCursorset()
{
if (IsOpen())
Close();
}
void CDBFCursorset::Open(LPCTSTR lpszFileName, UINT nOpenFlag)
{
if (!this)
return;
CString strFileName;
if(lpszFileName == NULL)
strFileName = GetDefaultDBName();
else
strFileName = lpszFileName;
if(!(strFileName.GetLength() > 4))
return;
// Re-Opening is invalid.
if (IsOpen())
{
return;
}
m_pTableDef = new CDBFTableDef;
m_pTableDef->m_bOpen = FALSE;
m_pTableDef->Open(strFileName, nOpenFlag);
if(!IsOpen())
return;
m_DBFFields = m_pTableDef->m_DBFFields;
Requery();
}
void CDBFCursorset::Close()
{
CDBFRecordset::Close();
m_bDesc = FALSE;
m_bShowDeletedRec = TRUE;
m_nCurCursorRecN = -1;
m_bBOF = TRUE;
m_bEOF = TRUE;
m_RecPtr.RemoveAll();
}
BOOL CDBFCursorset::IsBOF() const
{
return m_bBOF;
}
BOOL CDBFCursorset::IsEOF() const
{
return m_bEOF;
}
long CDBFCursorset::GetRecordCount()
{
if (!IsOpen())
return -1;
return m_RecPtr.GetSize();
}
long CDBFCursorset::GetAbsolutePosition()
{
if (!IsOpen())
return -1;
return m_nCurCursorRecN;
}
void CDBFCursorset::SetAbsolutePosition(long lPosition)
{
if (!IsOpen())
return ;
if (!(lPosition >= 0 && lPosition < GetRecordCount()))
return;
DBF_LONG lCursorRecN = lPosition;
// Call Move.
m_pTableDef->ReadRecord(m_RecPtr[lCursorRecN], m_DBFFields.m_pCurRec);
m_nCurTableRecN = m_RecPtr[lCursorRecN];
m_nCurCursorRecN = lCursorRecN;
m_bBOF = m_bEOF = FALSE;
}
void CDBFCursorset::MoveNext()
{
if (IsEOF())
return;
m_nEditMode = DbfUtility::noMode;
DBF_LONG lCursorRecN = m_nCurCursorRecN;
lCursorRecN++;
if(lCursorRecN < GetRecordCount())
{
// Call Move.
m_pTableDef->ReadRecord(m_RecPtr[lCursorRecN], m_DBFFields.m_pCurRec);
m_nCurTableRecN = m_RecPtr[lCursorRecN];
m_nCurCursorRecN = lCursorRecN;
m_bBOF = m_bEOF = FALSE;
}
else
{
m_bEOF = TRUE;
m_bBOF = GetRecordCount() > 0;
}
}
void CDBFCursorset::MovePrev()
{
if (IsBOF())
return;
m_nEditMode = DbfUtility::noMode;
DBF_LONG lCursorRecN = m_nCurCursorRecN;
lCursorRecN--;
if(lCursorRecN < GetRecordCount())
{
// Call Move.
m_pTableDef->ReadRecord(m_RecPtr[lCursorRecN], m_DBFFields.m_pCurRec);
m_nCurTableRecN = m_RecPtr[lCursorRecN];
m_nCurCursorRecN = lCursorRecN;
}
else
{
m_bEOF = TRUE;
m_bBOF = GetRecordCount() > 0;
}
}
void CDBFCursorset::MoveFirst()
{
if (GetRecordCount() <= 0)
return;
m_nEditMode = DbfUtility::noMode;
DBF_LONG lCursorRecN = 0;
// Call Move.
m_pTableDef->ReadRecord(m_RecPtr[lCursorRecN], m_DBFFields.m_pCurRec);
m_nCurTableRecN = m_RecPtr[lCursorRecN];
m_nCurCursorRecN = lCursorRecN;
m_bBOF = m_bEOF = FALSE;
}
void CDBFCursorset::MoveLast()
{
if (GetRecordCount() <= 0)
return;
m_nEditMode = DbfUtility::noMode;
DBF_LONG lCursorRecN = 0;
lCursorRecN = GetRecordCount() - 1;
// Call Move.
m_pTableDef->ReadRecord(m_RecPtr[lCursorRecN], m_DBFFields.m_pCurRec);
m_nCurTableRecN = m_RecPtr[lCursorRecN];
m_nCurCursorRecN = lCursorRecN;
m_bBOF = m_bEOF = FALSE;
}
void CDBFCursorset::Move(long lOffsetRec)
{
if (GetRecordCount() <= 0)
return;
m_nEditMode = DbfUtility::noMode;
DBF_LONG lCursorRecN = m_nCurCursorRecN + lOffsetRec;
if(lOffsetRec < 0)
{
if(lCursorRecN < 0)
{
lCursorRecN = 0;
m_bBOF = TRUE;
}
else
m_bBOF = FALSE;
m_bEOF = FALSE;
}
else if(lOffsetRec > 0)
{
if(lCursorRecN >= GetRecordCount())
{
lCursorRecN = GetRecordCount() - 1;
m_bEOF = TRUE;
}
else
m_bEOF = FALSE;
m_bBOF = FALSE;
}
// Call Move.
m_pTableDef->ReadRecord(m_RecPtr[lCursorRecN], m_DBFFields.m_pCurRec);
m_nCurTableRecN = m_RecPtr[lCursorRecN];
m_nCurCursorRecN = lCursorRecN;
}
void CDBFCursorset::CancelUpdate()
{
if (!IsOpen())
return;
if (m_nEditMode == DbfUtility::noMode)
return;
m_pTableDef->ReadRecord(m_RecPtr[m_nCurCursorRecN], m_DBFFields.m_pCurRec);
m_nCurTableRecN = m_RecPtr[m_nCurCursorRecN];
m_nEditMode = DbfUtility::noMode;
}
void CDBFCursorset::AddNew()
{
if (!IsOpen())
return;
m_nEditMode = DbfUtility::addnew;
memset(m_DBFFields.m_pCurRec, 0, m_pTableDef->m_DBFHead.rec_size);
COleVariant varEmpty;
varEmpty.Clear();
for(short i = 0; i < m_DBFFields.GetFieldCount(); i++)
{
FIELD_REC* pFieldRec = m_DBFFields.GetFieldRec(i);
TGSetFieldValue(m_DBFFields.m_pCurRec, pFieldRec, varEmpty);
}
m_DBFFields.m_pCurRec[0] = REC_FLAG_NORMAL;
}
void CDBFCursorset::Edit()
{
if (!IsOpen())
return;
if (m_nEditMode != DbfUtility::noMode)
return;
m_nEditMode = DbfUtility::edit;
}
void CDBFCursorset::Update()
{
if (!IsOpen())
return;
if (m_nEditMode == DbfUtility::noMode)
return;
switch(m_nEditMode)
{
case DbfUtility::edit:
{
m_pTableDef->WriteRecord(m_nCurTableRecN, m_DBFFields.m_pCurRec);
break;
}
case DbfUtility::addnew:
{
m_pTableDef->ReadHeader();
m_pTableDef->m_DBFHead.last_rec++;
m_nCurTableRecN = max(0,m_pTableDef->m_DBFHead.last_rec - 1);
m_pTableDef->WriteRecord(m_nCurTableRecN, m_DBFFields.m_pCurRec);
m_pTableDef->WriteHeader();
m_RecPtr.Add(m_nCurTableRecN);
m_nCurCursorRecN = GetRecordCount() -1;
break;
}
}
m_nEditMode = DbfUtility::noMode;
}
void CDBFCursorset::Remove()
{
if (!IsOpen())
return;
if (m_nEditMode != DbfUtility::noMode)
return;
m_RecPtr.RemoveAt(m_nCurCursorRecN);
if(m_nCurCursorRecN >= m_RecPtr.GetSize() && m_nCurCursorRecN > 0)
m_nCurCursorRecN--;
if(GetRecordCount() > 0)
{
m_pTableDef->ReadRecord(m_RecPtr[m_nCurCursorRecN], m_DBFFields.m_pCurRec);
m_nCurTableRecN = m_RecPtr[m_nCurCursorRecN];
}
}
BOOL CDBFCursorset::IsOpen() const
{
return (m_pTableDef == NULL ? FALSE : m_pTableDef->m_bOpen);
}
void CDBFCursorset::ThrowDBFException(long nTGDBFError)
{
TGThrowDBFException(nTGDBFError);
}
#ifdef _DEBUG
void CDBFCursorset::AssertValid() const
{
CDBFRecordset::AssertValid();
}
void CDBFCursorset::Dump(CDumpContext& dc) const
{
CDBFRecordset::Dump(dc);
dc << "\n";
}
#endif //_DEBUG
void CDBFCursorset::SetRecord(long lRecNumber, const DBF_CHAR* lpBuffer){}
void CDBFCursorset::SortByField(const char* lpszName, BOOL bDesc /* = FALSE */)
{
for(short nIndex = 0;
_stricmp(m_DBFFields.m_pFields[nIndex].field_name, lpszName) != 0 &&
nIndex <= m_DBFFields.m_nFieldCount;
nIndex++)
SortByField(nIndex, bDesc);
}
void CDBFCursorset::SortByField(int nIndex, BOOL bDesc /* = FALSE */)
{
m_nSortedField = nIndex;
m_bDesc = bDesc;
if(GetRecordCount() > 1)
{
FIELD_REC* pFieldRec = m_DBFFields.GetFieldRec(nIndex);
switch(pFieldRec->field_type)
{
case FLD_TYPE_DOUBLE: //FLD_TYPE_BINARY
//FLD_TYPE_DOUBLE
if(pFieldRec->len_info.num_size.len == sizeof(DBF_DOUBLE))
break;
case FLD_TYPE_GENERAL:
case FLD_TYPE_PICTURE:
return;
}
qsort( 0, GetRecordCount() - 1 );
m_pTableDef->ReadRecord(m_RecPtr[m_nCurCursorRecN], m_DBFFields.m_pCurRec);
m_nCurTableRecN = m_RecPtr[m_nCurCursorRecN];
}
}
int CDBFCursorset::compare(const long elem1, const long elem2)
{
// if elem1 < elem2 return TRUE else return FALSE
COleVariant var1, var2;
BOOL bResult;
if(m_bDesc)
{
m_pTableDef->ReadRecord(elem1, m_DBFFields.m_pCurRec);
var2 = GetFieldValue(m_nSortedField);
m_pTableDef->ReadRecord(elem2, m_DBFFields.m_pCurRec);
var1 = GetFieldValue(m_nSortedField);
}
else
{
m_pTableDef->ReadRecord(elem1, m_DBFFields.m_pCurRec);
var1 = GetFieldValue(m_nSortedField);
m_pTableDef->ReadRecord(elem2, m_DBFFields.m_pCurRec);
var2 = GetFieldValue(m_nSortedField);
}
if(var1 == var2)
bResult = FALSE;
else
{
if(var1.vt == VT_EMPTY && var2.vt != VT_EMPTY)
bResult = TRUE;
else if (var2.vt == VT_EMPTY && var1.vt != VT_EMPTY)
bResult = FALSE;
else
{
switch(var1.vt)
{
case VT_BSTR:
{
CTDbfString str1 = var1.bstrVal;
CTDbfString str2 = var2.bstrVal;
bResult = (str1 < str2);
break;
}
case VT_R8:
{
bResult = (var1.dblVal < var2.dblVal);
break;
}
case VT_I4:
{
bResult = (var1.lVal < var2.lVal);
break;
}
case VT_CY:
{
COleCurrency cur1, cur2;
cur1.m_cur = var1.cyVal;
cur2.m_cur = var2.cyVal;
bResult = (cur1 < cur2);
break;
}
case VT_DATE:
{
bResult = (var1.date < var2.date);
break;
}
case VT_BOOL:
{
bResult = (var1.boolVal < var2.boolVal);
break;
}
}
}
}
return bResult;
}
void CDBFCursorset::qsort(int from, int to)
{
int i, j;
long x, tmp;
// int from = 0;
// int to = m_RecPtr.GetSize();
if( from >= to ) return;
i = from; j = to;
x = m_RecPtr[ (i+j) / 2 ];
do
{
while( compare(m_RecPtr[i], x) ) i++ ; // m_RecPtr[i] < x
while( compare(x, m_RecPtr[j]) ) j--; // x < m_RecPtr[j]
if( i <= j )
{
tmp = m_RecPtr[i]; m_RecPtr[i] = m_RecPtr[j] ; m_RecPtr[j] = tmp;
i++; j--;
}
} while( i <= j );
if( (j - from) < (to - i) )
{
qsort( from, j );
qsort( i, to );
} else {
qsort( i, to );
qsort( from, j );
}
}
void CDBFCursorset::SetDelete(BOOL bHideDeleteRec /* = TRUE */)
{
m_bShowDeletedRec = !bHideDeleteRec;
}
BOOL CDBFCursorset::GetDelete()
{
return !m_bShowDeletedRec;
}
void CDBFCursorset::Requery()
{
if (!IsOpen())
return;
m_nEditMode = DbfUtility::noMode;
m_RecPtr.SetSize(m_pTableDef->GetRecordCount());
long nRec = 0;
if(m_bShowDeletedRec)
{
for(long i = 0; i < m_RecPtr.GetSize(); i++)
{
m_RecPtr[nRec] = i;
if(m_lpfnIsInclude != NULL)
{
if((*m_lpfnIsInclude)((DBF_CHAR*)m_RecPtr[nRec],&m_DBFFields))
nRec++;
}
else
nRec++;
}
}
else
{
for(long i = 0; i < m_RecPtr.GetSize(); i++)
{
m_pTableDef->ReadRecord(m_RecPtr[nRec], m_DBFFields.m_pCurRec);
if(REC_FLAG_DELETED != m_DBFFields.m_pCurRec[0])
{
if(m_lpfnIsInclude != NULL)
{
if((*m_lpfnIsInclude)(m_DBFFields.m_pCurRec,&m_DBFFields))
nRec++;
}
else
nRec++;
}
}
}
m_RecPtr.SetSize(nRec);
if(GetRecordCount() > 0)
MoveFirst();
else
{
m_nCurTableRecN = 0;
m_nCurCursorRecN = 0;
}
}
void CDBFCursorset::SetFilter(BOOL (FAR * lpfnIsInclude) (DBF_CHAR*, CDBFFields* pDBFFields))
{
m_lpfnIsInclude = lpfnIsInclude;
}