756 lines
14 KiB
C++
756 lines
14 KiB
C++
#include "stdafx.h"
|
|
#include "DBFMemCursorset.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
// CDBFMemCursorset
|
|
IMPLEMENT_DYNAMIC(CDBFMemCursorset, CDBFRecordset )
|
|
|
|
CDBFMemCursorset::CDBFMemCursorset(CDBFTableDef* pDBFTable)
|
|
{
|
|
m_bDesc = FALSE;
|
|
|
|
m_bShowDeletedRec = TRUE;
|
|
|
|
m_pTableData = NULL;
|
|
|
|
m_pEditRec = NULL;
|
|
|
|
m_lLoadRecord = 0;
|
|
|
|
m_lpfnIsInclude = NULL;
|
|
|
|
m_nCurCursorRecN = -1;
|
|
|
|
m_bBOF = TRUE;
|
|
m_bEOF = TRUE;
|
|
}
|
|
|
|
CDBFMemCursorset::~CDBFMemCursorset()
|
|
{
|
|
if (IsOpen())
|
|
Close();
|
|
}
|
|
|
|
BOOL CDBFMemCursorset::Open(LPCTSTR lpszFileName, UINT nOpenFlag)
|
|
{
|
|
|
|
|
|
CString strFileName;
|
|
|
|
if(lpszFileName == NULL)
|
|
strFileName = GetDefaultDBName();
|
|
else
|
|
strFileName = lpszFileName;
|
|
|
|
if (strFileName.GetLength() < 4)
|
|
return FALSE;
|
|
|
|
// Re-Opening is invalid.
|
|
if (IsOpen())
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
m_pTableDef = new CDBFTableDef;
|
|
m_pTableDef->m_bOpen = FALSE;
|
|
|
|
m_pTableDef->Open(strFileName, nOpenFlag);
|
|
|
|
if(!IsOpen())
|
|
return FALSE;
|
|
|
|
m_DBFFields = m_pTableDef->m_DBFFields;
|
|
m_DBFHead = m_pTableDef->m_DBFHead;
|
|
|
|
UINT lFileSize = (UINT)m_pTableDef->m_DBFile.GetLength();
|
|
m_pTableData = new DBF_UCHAR[lFileSize];
|
|
|
|
m_pTableDef->m_DBFile.Seek(0, CFile::begin);
|
|
|
|
#if _MSC_VER > 1200
|
|
DBF_CHECK_ERROR(
|
|
m_pTableDef->m_DBFile.Read(m_pTableData, lFileSize) == lFileSize, TG_DBF_ERROR_DBFILE_MEMORYLOAD);
|
|
#else
|
|
DBF_CHECK_ERROR(
|
|
m_pTableDef->m_DBFile.ReadHuge(m_pTableData, lFileSize) == lFileSize, TG_DBF_ERROR_DBFILE_MEMORYLOAD);
|
|
#endif // _MSC_VER > 1200
|
|
|
|
m_lLoadRecord = m_pTableDef->GetRecordCount();
|
|
|
|
Requery();
|
|
return TRUE;
|
|
}
|
|
|
|
void CDBFMemCursorset::Close()
|
|
{
|
|
CDBFRecordset::Close();
|
|
|
|
m_bDesc = FALSE;
|
|
m_bShowDeletedRec = TRUE;
|
|
|
|
m_nCurCursorRecN = -1;
|
|
|
|
m_bBOF = TRUE;
|
|
m_bEOF = TRUE;
|
|
|
|
if(m_pTableData != NULL) { delete[] m_pTableData; m_pTableData = NULL; }
|
|
|
|
m_lLoadRecord = 0;
|
|
|
|
if(m_pEditRec != NULL) { delete[] m_pEditRec; m_pEditRec = NULL; }
|
|
|
|
|
|
m_RecPtr.RemoveAll();
|
|
for(int i = 0; i < m_NewRecPtr.GetSize(); i++)
|
|
{
|
|
DBF_UCHAR* pNewRec = (DBF_UCHAR*)m_NewRecPtr[i];
|
|
delete[] pNewRec;
|
|
}
|
|
m_NewRecPtr.RemoveAll();
|
|
}
|
|
|
|
BOOL CDBFMemCursorset::IsBOF() const
|
|
{
|
|
assert(IsOpen());
|
|
return (m_nCurCursorRecN == 0);
|
|
}
|
|
|
|
BOOL CDBFMemCursorset::IsEOF() const
|
|
{
|
|
assert(IsOpen());
|
|
return (m_nCurCursorRecN >= m_RecPtr.GetSize() - 1);
|
|
}
|
|
|
|
long CDBFMemCursorset::GetRecordCount()
|
|
{
|
|
assert(IsOpen());
|
|
return m_RecPtr.GetSize();
|
|
}
|
|
|
|
long CDBFMemCursorset::GetAbsolutePosition()
|
|
{
|
|
assert(IsOpen());
|
|
return m_nCurCursorRecN;
|
|
}
|
|
|
|
void CDBFMemCursorset::SetAbsolutePosition(long lPosition)
|
|
{
|
|
assert(IsOpen());
|
|
if (lPosition<0 || lPosition>=GetRecordCount())
|
|
return;
|
|
|
|
DBF_LONG lCursorRecN = lPosition;
|
|
|
|
// Call Move.
|
|
m_DBFFields.m_pCurRec = GetRecord(lCursorRecN);
|
|
m_nCurCursorRecN = lCursorRecN;
|
|
m_bBOF = m_bEOF = FALSE;
|
|
|
|
}
|
|
|
|
void CDBFMemCursorset::MoveNext()
|
|
{
|
|
if (IsEOF())
|
|
return;
|
|
m_nEditMode = DbfUtility::noMode;
|
|
|
|
DBF_LONG lCursorRecN = m_nCurCursorRecN;
|
|
|
|
lCursorRecN++;
|
|
|
|
if(lCursorRecN < GetRecordCount())
|
|
{
|
|
// Call Move.
|
|
m_DBFFields.m_pCurRec = GetRecord(lCursorRecN);
|
|
m_nCurCursorRecN = lCursorRecN;
|
|
m_bBOF = m_bEOF = FALSE;
|
|
}
|
|
else
|
|
{
|
|
m_bEOF = TRUE;
|
|
m_bBOF = GetRecordCount() > 0;
|
|
}
|
|
}
|
|
|
|
void CDBFMemCursorset::MovePrev()
|
|
{
|
|
if (IsBOF())
|
|
return;
|
|
|
|
m_nEditMode = DbfUtility::noMode;
|
|
|
|
DBF_LONG lCursorRecN = m_nCurCursorRecN;
|
|
|
|
lCursorRecN--;
|
|
|
|
if(lCursorRecN >= 0)
|
|
{
|
|
// Call Move.
|
|
m_DBFFields.m_pCurRec = GetRecord(lCursorRecN);
|
|
m_nCurCursorRecN = lCursorRecN;
|
|
m_bBOF = m_bEOF = FALSE;
|
|
}
|
|
else
|
|
{
|
|
m_bBOF = TRUE;
|
|
m_bEOF = GetRecordCount() > 0;
|
|
}
|
|
}
|
|
|
|
void CDBFMemCursorset::MoveFirst()
|
|
{
|
|
if (GetRecordCount() < 1)
|
|
return;
|
|
|
|
m_nEditMode = DbfUtility::noMode;
|
|
|
|
DBF_LONG lCursorRecN = 0;
|
|
|
|
// Call Move.
|
|
m_DBFFields.m_pCurRec = GetRecord(lCursorRecN);
|
|
m_nCurCursorRecN = lCursorRecN;
|
|
m_bBOF = m_bEOF = FALSE;
|
|
|
|
}
|
|
|
|
void CDBFMemCursorset::MoveLast()
|
|
{
|
|
if (GetRecordCount() < 1)
|
|
return;
|
|
|
|
m_nEditMode = DbfUtility::noMode;
|
|
|
|
DBF_LONG lCursorRecN = GetRecordCount() - 1;
|
|
|
|
// Call Move.
|
|
m_DBFFields.m_pCurRec = GetRecord(lCursorRecN);
|
|
m_nCurCursorRecN = lCursorRecN;
|
|
m_bBOF = m_bEOF = FALSE;
|
|
|
|
}
|
|
|
|
void CDBFMemCursorset::Move(long lOffsetRec)
|
|
{
|
|
if(!IsOpen())
|
|
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_DBFFields.m_pCurRec = GetRecord(lCursorRecN);
|
|
m_nCurCursorRecN = lCursorRecN;
|
|
}
|
|
|
|
void CDBFMemCursorset::CancelUpdate()
|
|
{
|
|
assert(IsOpen());
|
|
if (m_nEditMode == DbfUtility::noMode || m_pEditRec == NULL)
|
|
return;
|
|
m_DBFFields.m_pCurRec = GetRecord(m_nCurCursorRecN);
|
|
|
|
if(m_pEditRec != NULL)
|
|
delete[] m_pEditRec;
|
|
|
|
m_nEditMode = DbfUtility::noMode;
|
|
}
|
|
|
|
void CDBFMemCursorset::AddNew()
|
|
{
|
|
assert(IsOpen());
|
|
if (m_nEditMode != DbfUtility::noMode || m_pEditRec != NULL)
|
|
return;
|
|
|
|
m_nEditMode = DbfUtility::addnew;
|
|
|
|
if(m_pEditRec != NULL)
|
|
delete[] m_pEditRec;
|
|
|
|
m_pEditRec = new DBF_CHAR[m_DBFHead.rec_size];
|
|
|
|
memset(m_pEditRec, 0, 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_pEditRec, pFieldRec, varEmpty);
|
|
}
|
|
|
|
m_pEditRec[0] = REC_FLAG_NORMAL;
|
|
|
|
m_DBFFields.m_pCurRec = m_pEditRec;
|
|
}
|
|
|
|
void CDBFMemCursorset::Edit()
|
|
{
|
|
assert(IsOpen());
|
|
if (m_nEditMode != DbfUtility::noMode || m_nEditMode != NULL)
|
|
return;
|
|
|
|
m_nEditMode = DbfUtility::edit;
|
|
|
|
if(m_pEditRec != NULL)
|
|
delete[] m_pEditRec;
|
|
|
|
m_pEditRec = new DBF_CHAR[m_DBFHead.rec_size];
|
|
|
|
memcpy(m_pEditRec, m_DBFFields.m_pCurRec, m_DBFHead.rec_size);
|
|
|
|
m_DBFFields.m_pCurRec = m_pEditRec;
|
|
}
|
|
|
|
void CDBFMemCursorset::Update()
|
|
{
|
|
assert(IsOpen());
|
|
if (m_nEditMode == DbfUtility::noMode || m_pEditRec == NULL)
|
|
return;
|
|
|
|
switch(m_nEditMode)
|
|
{
|
|
case DbfUtility::edit:
|
|
{
|
|
SetRecord(m_nCurCursorRecN, m_pEditRec);
|
|
delete [] m_pEditRec;
|
|
break;
|
|
}
|
|
case DbfUtility::addnew:
|
|
{
|
|
m_DBFHead.last_rec++;
|
|
m_NewRecPtr.Add(m_pEditRec);
|
|
m_RecPtr.Add(m_pEditRec);
|
|
m_nCurCursorRecN = max(0,GetRecordCount() - 1);
|
|
SetRecord(m_nCurCursorRecN, m_pEditRec);
|
|
m_bBOF = m_bEOF = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
m_pEditRec = NULL;
|
|
|
|
m_DBFFields.m_pCurRec = GetRecord(m_nCurCursorRecN);
|
|
|
|
m_nEditMode = DbfUtility::noMode;
|
|
}
|
|
|
|
void CDBFMemCursorset::Delete()
|
|
{
|
|
assert(IsOpen());
|
|
if (m_nEditMode != DbfUtility::noMode)
|
|
return;
|
|
|
|
m_DBFFields.m_pCurRec[0] = REC_FLAG_DELETED;
|
|
SetRecord(m_nCurCursorRecN, m_DBFFields.m_pCurRec);
|
|
}
|
|
|
|
BOOL CDBFMemCursorset::IsDeleted()
|
|
{
|
|
assert(IsOpen());
|
|
return (m_DBFFields.m_pCurRec[0] == REC_FLAG_DELETED);
|
|
}
|
|
|
|
void CDBFMemCursorset::Undelete()
|
|
{
|
|
assert(IsOpen());
|
|
if (m_nEditMode != DbfUtility::noMode)
|
|
return;
|
|
|
|
m_DBFFields.m_pCurRec[0] = REC_FLAG_NORMAL;
|
|
SetRecord(m_nCurCursorRecN, m_DBFFields.m_pCurRec);
|
|
}
|
|
|
|
void CDBFMemCursorset::Remove()
|
|
{
|
|
assert(IsOpen());
|
|
|
|
if (m_nEditMode != DbfUtility::noMode)
|
|
return;
|
|
m_DBFHead.last_rec--;
|
|
m_RecPtr.RemoveAt(m_nCurCursorRecN);
|
|
|
|
if(m_nCurCursorRecN >= GetRecordCount() && m_nCurCursorRecN > 0)
|
|
m_nCurCursorRecN--;
|
|
|
|
m_DBFFields.m_pCurRec = GetRecord(m_nCurCursorRecN);
|
|
}
|
|
|
|
BOOL CDBFMemCursorset::IsOpen() const
|
|
{
|
|
|
|
return (m_pTableDef == NULL ? FALSE : m_pTableDef->m_bOpen);
|
|
}
|
|
|
|
void CDBFMemCursorset::ThrowDBFException(long nTGDBFError)
|
|
{
|
|
|
|
|
|
TGThrowDBFException(nTGDBFError);
|
|
}
|
|
|
|
#ifdef _DEBUG
|
|
void CDBFMemCursorset::AssertValid() const
|
|
{
|
|
CDBFRecordset::AssertValid();
|
|
}
|
|
|
|
void CDBFMemCursorset::Dump(CDumpContext& dc) const
|
|
{
|
|
|
|
|
|
CDBFRecordset::Dump(dc);
|
|
|
|
dc << "\n";
|
|
}
|
|
#endif //_DEBUG
|
|
|
|
DBF_CHAR* CDBFMemCursorset::GetRecord(long lRecNumber)
|
|
{
|
|
if (lRecNumber > m_RecPtr.GetSize())
|
|
return NULL;
|
|
return (DBF_CHAR*)m_RecPtr[lRecNumber];
|
|
}
|
|
|
|
void CDBFMemCursorset::GetRecord(long lRecNumber, DBF_CHAR* lpBuffer){}
|
|
|
|
void CDBFMemCursorset::SetRecord(long lRecNumber, const DBF_CHAR* lpBuffer)
|
|
{
|
|
if (lRecNumber > m_RecPtr.GetSize())
|
|
return;
|
|
memcpy(m_RecPtr[lRecNumber],lpBuffer,m_DBFHead.rec_size);
|
|
}
|
|
|
|
void CDBFMemCursorset::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 CDBFMemCursorset::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:
|
|
if(pFieldRec->len_info.num_size.len == sizeof(DBF_DOUBLE))
|
|
break;
|
|
case FLD_TYPE_GENERAL:
|
|
case FLD_TYPE_PICTURE:
|
|
return;
|
|
}
|
|
|
|
qsort( 0, m_RecPtr.GetSize() - 1 );
|
|
|
|
m_DBFFields.m_pCurRec = GetRecord(m_nCurCursorRecN);
|
|
}
|
|
}
|
|
|
|
int CDBFMemCursorset::compare(const void *elem1, const void *elem2)
|
|
{
|
|
// if elem1 < elem2 return TRUE else return FALSE
|
|
COleVariant var1, var2;
|
|
BOOL bResult;
|
|
|
|
if(m_bDesc)
|
|
{
|
|
m_DBFFields.m_pCurRec = (DBF_CHAR*)elem1;
|
|
var2 = GetFieldValue(m_nSortedField);
|
|
m_DBFFields.m_pCurRec = (DBF_CHAR*)elem2;
|
|
var1 = GetFieldValue(m_nSortedField);
|
|
}
|
|
else
|
|
{
|
|
m_DBFFields.m_pCurRec = (DBF_CHAR*)elem1;
|
|
var1 = GetFieldValue(m_nSortedField);
|
|
m_DBFFields.m_pCurRec = (DBF_CHAR*)elem2;
|
|
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 CDBFMemCursorset::qsort(int from, int to)
|
|
{
|
|
int i, j;
|
|
void *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 CDBFMemCursorset::SetDelete(BOOL bHideDeleteRec /* = TRUE */)
|
|
{
|
|
m_bShowDeletedRec = !bHideDeleteRec;
|
|
}
|
|
|
|
BOOL CDBFMemCursorset::GetDelete()
|
|
{
|
|
return !m_bShowDeletedRec;
|
|
}
|
|
|
|
void CDBFMemCursorset::Requery()
|
|
{
|
|
assert(IsOpen());
|
|
m_nEditMode = DbfUtility::noMode;
|
|
|
|
m_RecPtr.SetSize(m_lLoadRecord + m_NewRecPtr.GetSize());
|
|
|
|
long nRec = 0;
|
|
|
|
if(m_bShowDeletedRec)
|
|
{
|
|
for(long i = 0; i < m_lLoadRecord; i++)
|
|
{
|
|
m_RecPtr[nRec] = m_pTableData + m_DBFHead.data_offset + m_DBFHead.rec_size * i;
|
|
|
|
if(m_lpfnIsInclude != NULL)
|
|
{
|
|
if((*m_lpfnIsInclude)((DBF_CHAR*)m_RecPtr[nRec],&m_DBFFields))
|
|
nRec++;
|
|
}
|
|
else
|
|
nRec++;
|
|
}
|
|
|
|
for(long j = 0; j < m_NewRecPtr.GetSize(); j++)
|
|
{
|
|
m_RecPtr[nRec] = m_NewRecPtr[j];
|
|
if(m_lpfnIsInclude != NULL)
|
|
{
|
|
if((*m_lpfnIsInclude)((DBF_CHAR*)m_RecPtr[nRec],&m_DBFFields))
|
|
nRec++;
|
|
}
|
|
else
|
|
nRec++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for(long i = 0; i < m_lLoadRecord; i++)
|
|
{
|
|
if(REC_FLAG_DELETED != *(DBF_CHAR*)(m_pTableData + m_DBFHead.data_offset + m_DBFHead.rec_size * i))
|
|
{
|
|
m_RecPtr[nRec] = m_pTableData + m_DBFHead.data_offset + m_DBFHead.rec_size * i;
|
|
|
|
if(m_lpfnIsInclude != NULL)
|
|
{
|
|
if((*m_lpfnIsInclude)((DBF_CHAR*)m_RecPtr[nRec],&m_DBFFields))
|
|
nRec++;
|
|
}
|
|
else
|
|
nRec++;
|
|
}
|
|
}
|
|
|
|
for(i = 0; i < m_NewRecPtr.GetSize(); i++)
|
|
{
|
|
if(REC_FLAG_DELETED != *(DBF_CHAR*)(m_NewRecPtr[i]))
|
|
{
|
|
m_RecPtr[nRec] = m_NewRecPtr[i];
|
|
|
|
if(m_lpfnIsInclude != NULL)
|
|
{
|
|
if((*m_lpfnIsInclude)((DBF_CHAR*)m_RecPtr[nRec],&m_DBFFields))
|
|
nRec++;
|
|
}
|
|
else
|
|
nRec++;
|
|
}
|
|
}
|
|
}
|
|
|
|
m_RecPtr.SetSize(nRec);
|
|
|
|
m_DBFHead.last_rec = m_RecPtr.GetSize();
|
|
|
|
if(GetRecordCount() > 0)
|
|
MoveFirst();
|
|
else
|
|
m_nCurCursorRecN = 0;
|
|
}
|
|
|
|
BOOL CDBFMemCursorset::Save()
|
|
{
|
|
CFile* pDBFile = &m_pTableDef->m_DBFile;
|
|
/* if (!SaveFile.Open(lpszPathName, CFile::modeCreate |
|
|
CFile::modeReadWrite | CFile::shareDenyNone))
|
|
{
|
|
// ReportSaveLoadException(lpszPathName, &fe,
|
|
// TRUE, AFX_IDP_INVALID_FILENAME);
|
|
return FALSE;
|
|
}
|
|
*/
|
|
DBF_CHAR* pRec;
|
|
pDBFile->Seek(m_DBFHead.data_offset, CFile::begin);
|
|
|
|
for(long i = 0; i < m_lLoadRecord; i++)
|
|
{
|
|
pRec = (DBF_CHAR*)(m_pTableData + m_DBFHead.data_offset + m_DBFHead.rec_size * i);
|
|
pDBFile->Write(pRec, m_DBFHead.rec_size);
|
|
}
|
|
|
|
for(long j = 0; j < m_NewRecPtr.GetSize(); j++)
|
|
{
|
|
pRec = (DBF_CHAR*) m_NewRecPtr[j];
|
|
pDBFile->Write(pRec, m_DBFHead.rec_size);
|
|
}
|
|
|
|
char eof = REC_EOF;
|
|
|
|
pDBFile->Write(&eof, 1);
|
|
|
|
COleDateTime curDate = COleDateTime::GetCurrentTime();
|
|
if(m_DBFHead.dbf_id == 0x30) // Visual FoxPro
|
|
{
|
|
#if ADS == 15
|
|
m_DBFHead.last_update[0] = atof(curDate.Format(_T("%y")));
|
|
#else
|
|
m_DBFHead.last_update[0] = _tstoi(curDate.Format(_T("%y")));
|
|
#endif
|
|
|
|
}
|
|
else
|
|
m_DBFHead.last_update[0] = curDate.GetYear() - TG_DBF_CENTURY;
|
|
|
|
m_DBFHead.last_update[1] = curDate.GetMonth();
|
|
m_DBFHead.last_update[2] = curDate.GetDay();
|
|
m_DBFHead.last_rec = i + j;
|
|
|
|
pDBFile->Seek(0, CFile::begin);
|
|
|
|
pDBFile->Write(&m_DBFHead, sizeof(DBF_HEAD));
|
|
|
|
for(i = 0; i < m_DBFFields.GetFieldCount(); i++)
|
|
pDBFile->Write(m_DBFFields.GetFieldRec(i), sizeof(FIELD_REC));
|
|
char end = 0x0D;
|
|
pDBFile->Write(&end, 1);
|
|
|
|
pDBFile->SetLength(m_DBFHead.data_offset + m_DBFHead.last_rec * m_DBFHead.rec_size + 1);
|
|
|
|
m_pTableDef->m_DBFHead.last_rec = m_DBFHead.last_rec;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CDBFMemCursorset::SetFilter(BOOL (FAR * lpfnIsInclude) (DBF_CHAR*, CDBFFields* pDBFFields))
|
|
{
|
|
m_lpfnIsInclude = lpfnIsInclude;
|
|
} |