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

676 lines
12 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "stdafx.h"
#include "adsdef.h"
#include "dbftools.h"
#include "io.h"
/////////////////////////////////////////////////////////////////
// CodeBase -- Database classs
CodeBase::CodeBase()
{
m_pDbfTable = NULL;
read_only = 0;
}
CodeBase::~CodeBase()
{
if (m_pDbfTable != NULL)
{
if (m_pDbfTable->IsOpen())
m_pDbfTable->Close();
delete m_pDbfTable;
m_pDbfTable = NULL;
}
}
DbfTable* CodeBase::Open(const TCHAR *szFile)
{
// add by gjm 2010/07/09
CTDbfString _sfile(szFile);
if (_access(_sfile.toLPCSTR(), 00) != 0) //exist ?
return NULL;
if (_access(_sfile.toLPCSTR(), 06) != 0) // read and write ?
return NULL;
// end
m_pDbfTable = new DbfTable;
// sg add 091013,支持只读方式打开
int nOpenFlag = TG_DBF_USE_SHARED;
if (read_only == 1)
nOpenFlag = TG_DBF_USE_READ_ONLY;
if (!m_pDbfTable->Open(szFile, nOpenFlag))
{
delete m_pDbfTable;
m_pDbfTable = NULL;
return NULL;
}
return m_pDbfTable;
}
DbfTable* CodeBase::Create(const TCHAR *szFile, const FieldInfo *pFieldArray,
int nCount)
{
// 1、创建数据库
CDBFTableDef *pNewTable = new CDBFTableDef;
// 创建数据表,并填入表头信息
if (!pNewTable->CreateTable(szFile))
{
delete pNewTable;
pNewTable = NULL;
return NULL;
}
// 增加表列信息
for (int i=0; i<nCount; i++)
{
// 表列信息(DBFField:name、type、len、dec)
FieldInfo field = pFieldArray[i];
// 表列信息(field_name、field_type、field_offset、len_info.char_len、
FIELD_REC fieldRec;
memset(&fieldRec, 0, sizeof(FIELD_REC));
int nLen = field.m_strName.GetLength();
#if (ADS < 17)
strncpy(fieldRec.field_name, field.m_strName.toLPCSTR(), nLen);
#else
strncpy(fieldRec.field_name, field.m_strName.toLPCSTR(), nLen);
#endif
fieldRec.field_name[nLen] = EOS; // field_name
#if (ADS < 17)
fieldRec.field_type = field.m_chType; // field_type
#else
fieldRec.field_type = field.m_chType; // field_type
#endif
switch(field.m_chType)
{
case FLD_TYPE_NUMERIC: // int、double
fieldRec.len_info.num_size.len = field.m_nLen;
fieldRec.len_info.num_size.dec = field.m_nDec;
break;
case FLD_TYPE_CHARACTER: // string
case FLD_TYPE_DATE: // date
case FLD_TYPE_LOGICAL: // bool
fieldRec.len_info.char_len = field.m_nLen;
break;
default:
break;
}
pNewTable->AddField(&fieldRec);
}
// 更新数据表
pNewTable->UpdateTable();
// 2、关闭数据库
pNewTable->Close();
delete pNewTable;
pNewTable = NULL;
// 3、打开
return Open(szFile);
}
/////////////////////////////////////////////////////////////////
// DbfTable -- Recordset class
int DbfTable::GetFieldNum()
{
int nNum = GetFieldCount();
return nNum;
}
FieldInfo* DbfTable::GetFieldInfo()
{
FieldInfo *pFields = NULL;
int nCount = GetFieldNum();
pFields = new FieldInfo[nCount];
for (int i=0; i<nCount; i++)
{
pFields[i] = (FieldInfo&)m_DBFFields[i];
}
return pFields;
}
FieldContent* DbfTable::GetFieldContent(int n)
{
FieldContent *pContent = (FieldContent*)m_DBFFields.GetFieldRec(n);
if (pContent != NULL)
{
CTDbfString csContent;
GetFieldValue(n, csContent);
*pContent = (const TCHAR*)(csContent.toCString()); // 赋值
return pContent;
}
return NULL;
}
FieldContent* DbfTable::GetFieldContent(const TCHAR *szFieldName)
{
CString csName = szFieldName;
csName.MakeUpper(); // 全部转化为大写字母
int nCount = GetFieldNum();
for (int i=0; i<nCount; i++)
{
DBFField field = m_DBFFields[i];
CString csTmp = field.m_strName.toCString();
csTmp.MakeUpper(); // 全部转化为大写字母
if (_tcscmp(csTmp, csName) == 0) // 查找指定列名的列
{
FieldContent *pContent = (FieldContent*)m_DBFFields.GetFieldRec(i);
if (pContent != NULL)
{
CTDbfString csContent;
GetFieldValue(i, csContent);
*pContent = (const TCHAR*)(csContent.toCString()); // 赋值
return pContent;
}
return NULL;
}
}
return NULL;
}
long DbfTable::GetRecordCount(int bSkipDeleted)
{
if (!bSkipDeleted) // 计算全部记录,包括被删除记录
return CDBFRecordset::GetRecordCount();
long lCount = 0; // 只计算有效记录
for (MoveFirst(); !IsEOF(); MoveNext())
lCount ++;
return lCount;
}
long DbfTable::GetPosition()
{
long lPosition = GetAbsolutePosition();
return lPosition;
}
int DbfTable::IsEOF()
{
BOOL bRet = CDBFRecordset::IsEOF();
return bRet;
}
int DbfTable::IsBOF()
{
BOOL bRet = CDBFRecordset::IsBOF();
return bRet;
}
int DbfTable::IsDeleted()
{
BOOL bRet = CDBFRecordset::IsDeleted();
return bRet;
}
void DbfTable::AppendBegin()
{
CDBFRecordset::AddNew();
m_bIsAdd = true;
}
void DbfTable::AppendEnd()
{
CDBFRecordset::Update();
m_bIsAdd = false;
}
void DbfTable::Close()
{
CDBFRecordset::Close();
}
void DbfTable::Delete()
{
CDBFRecordset::Delete();
}
BOOL DbfTable::Pack()
{
CDBFRecordset::Edit();
CDBFRecordset::Update();
return TRUE;
}
int DbfTable::MoveFirst(int bSkipDeleted)
{
int nRet = 1;
CDBFRecordset::MoveFirst();
if (IsDeleted() && bSkipDeleted)
nRet = MoveNext(bSkipDeleted);
return nRet;
}
int DbfTable::MoveLast(int bSkipDeleted)
{
int nRet = 1;
CDBFRecordset::MoveFirst();
if (IsDeleted() && bSkipDeleted)
nRet = MovePrev(bSkipDeleted);
return nRet;
}
int DbfTable::MoveNext(int bSkipDeleted)
{
while (1)
{
CDBFRecordset::MoveNext();
if (IsEOF() || !bSkipDeleted)
break;
if (!IsDeleted())
break;
}
return (!IsEOF());
}
int DbfTable::MovePrev(int bSkipDeleted)
{
while(1)
{
CDBFRecordset::MovePrev();
if (IsBOF() || !bSkipDeleted)
break;
if (!IsDeleted())
break;
}
return (!IsBOF());
}
void DbfTable::Move(long offset, int bSkipDeleted)
{
if (offset)
{
long nStep = offset/abs(offset);
if (IsBOF() && offset>0)
{
MoveFirst(bSkipDeleted);
offset--;
}
if (IsEOF() && offset<0)
{
MoveLast(bSkipDeleted);
offset++;
}
for (long i=offset; i!=0L; i-=nStep)
{
if (nStep > 0)
MoveNext(bSkipDeleted);
else
MovePrev(bSkipDeleted);
}
}
}
int DbfTable::MoveTo(long nRecNo)
{
CDBFRecordset::Move(nRecNo);
return 1;
}
int DbfTable::MoveTo(const TCHAR *szKey, const TCHAR *szValue, int nMethod,
int bSkipDeleted)
{
for (MoveFirst(bSkipDeleted); !IsEOF(); MoveNext(bSkipDeleted))
{
CString sValue;
GET_FIELD(this, szKey, sValue);
int bEqual = 0;
if (nMethod == CMP_SENSITIVE)
bEqual = (_tcscmp(szValue, sValue)==0);
else
bEqual = (_tcsicmp(szValue, sValue)==0);
if (bEqual)
return 1;
}
return 0;
}
int DbfTable::MoveFirst(const TCHAR *szKey, const TCHAR *szValue, int nMethod,
int bSkipDeleted)
{
return MoveTo(szKey, szValue, nMethod, bSkipDeleted);
}
int DbfTable::MoveNext(const TCHAR *szKey, const TCHAR *szValue, int nMethod,
int bSkipDeleted)
{
for (MoveNext(bSkipDeleted); !IsEOF(); MoveNext(bSkipDeleted))
{
CString sValue;
GET_FIELD(this, szKey, sValue);
int bEqual = 0;
if (nMethod == CMP_SENSITIVE)
bEqual = (_tcscmp(szValue, sValue)==0);
else
bEqual = (_tcsicmp(szValue, sValue)==0);
if (bEqual)
return 1;
}
return 0;
}
void DbfTable::EditMode()
{
if (!m_bIsAdd)
Edit();
}
void DbfTable::EditUpdate()
{
if (!m_bIsAdd)
Update();
}
/////////////////////////////////////////////////////////////////
// FieldInfo -- Field Class
FieldInfo::FieldInfo(const TCHAR *n, int t, int l, int d)
{
InitClear();
m_strName = n;
m_chType = t;
m_nLen = l;
m_nDec = d;
}
FieldInfo & FieldInfo::operator = (const FieldInfo &src)
{
m_strName = src.m_strName;
m_chType = src.m_chType;
m_nLen = src.m_nLen;
m_nDec = src.m_nDec;
return *this;
}
void FieldInfo::InitClear()
{
m_strName = _T("");
m_chType = _T('\0');
m_nLen = 0;
m_nDec = 0;
}
void FieldInfo::ReleaseArray(FieldInfo *p)
{
if (p != NULL)
{
delete p;
p = NULL;
}
}
///////////////////////////////////////////////
// FieldContent -- FieldContent Class
CString FieldContent::csValue = _T("");
TCHAR FieldContent::GetFieldType() const
{
return field_type;
}
int FieldContent::CompareTo(const FieldContent &otherOne) const
{
if (GetFieldType() != otherOne.GetFieldType())
return 0;
TCHAR cType = GetFieldType();
if (cType == FLD_TYPE_NUMERIC)
{
if (len_info.num_size.dec == _T('0')) // int
{
int n1 = *this,
n2 = otherOne;
if (n1 > n2)
return 1;
else if (n1 < n2)
return -1;
else
return 0;
}
else // double
{
double n1 = *this,
n2 = otherOne;
if (n1 > n2)
return 1;
else if (n1 < n2)
return -1;
else
return 0;
}
}
else if (cType==FLD_TYPE_CHARACTER || cType==FLD_TYPE_DATE || cType==FLD_TYPE_LOGICAL) // string、date、bool
{
const TCHAR *s1 = *this,
*s2 = otherOne;
return _tcscmp(s1, s2);
}
return 0;
}
FieldContent::operator int () const
{
return _ttoi(csValue);
}
FieldContent::operator double () const
{
#if ADS == 15
return atof(csValue);
#else
return _tstof(csValue);
#endif
}
FieldContent::operator float () const
{
#if ADS == 15
double dValue = atof(csValue);
#else
double dValue = _tstof(csValue);
#endif
return (float)dValue;
}
FieldContent::operator const TCHAR * () const
{
return (const TCHAR *)csValue;
}
FieldContent & FieldContent::operator = (int i)
{
csValue.Format(_T("%d"), i);
return *this;
}
FieldContent & FieldContent::operator = (double d)
{
csValue.Format(_T("%f"), d);
return *this;
}
FieldContent & FieldContent::operator = (const TCHAR *str)
{
csValue = str;
return *this;
}
#ifdef __AFXDISP_H__
// 能正确转换的类型: int, double, string, date
COleVariant FieldContent::AsVariant() const
{
COleVariant res;
TCHAR cType = GetFieldType();
if (cType == FLD_TYPE_NUMERIC) // int、double
{
if (len_info.num_size.dec == _T('0')) // int
{
res = (long)_ttoi(csValue);
}
else // double
{
#if ADS == 15
res = atof(csValue);
#else
res = _tstof(csValue);
#endif
}
}
else if (cType == FLD_TYPE_CHARACTER) // string
{
const TCHAR *s1 = *this;
res = s1;
}
else if (cType == FLD_TYPE_LOGICAL) // int
{
res = (long)_ttoi(csValue);
}
return res;
}
FieldContent & FieldContent::operator = (const COleVariant &src)
{
int nOleType = V_VT(&src);
switch(nOleType)
{
case VT_BSTR:
{
CString cs = V_BSTR(&src);
const TCHAR *sz = cs;
*this = sz;
}
break;
case VT_DATE:
{
COleDateTime oleDate = V_DATE(&src);
int nYear = oleDate.GetYear(),
nMonth = oleDate.GetMonth(),
nDay = oleDate.GetDay();
long nDate = nYear*10000 + nMonth*100 + nDay;
CString sDate;
sDate.Format(_T("%ld"), nDate);
*this = (const TCHAR *)sDate;
}
break;
case VT_I4:
{
long n1 = V_I4(&src);
*this = (int)n1;
}
break;
case VT_I2:
{
short n1 = V_I2(&src);
*this = (int)n1;
}
break;
case VT_R8:
{
double n1 = V_R8(&src);
*this = n1;
}
break;
case VT_R4:
{
float n1 = V_R4(&src);
*this = (double)n1;
}
break;
}
return *this;
}
template <class K>
inline int Compare(K n1, K n2)
{
if(n1>n2) return 1;
else if(n1<n2) return -1;
else return 0;
}
int CompareVariant(const COleVariant &var1, const COleVariant &var2)
{
int nType1 = V_VT(&var1),
nType2 = V_VT(&var2);
int nRes = 0;
if (nType1 == nType2)
{
if (nType1 == VT_BSTR)
{
CString s1 = V_BSTR(&var1);
CString s2 = V_BSTR(&var2);
nRes = _tcscmp(s1, s2);
}
else if (nType1 == VT_DATE)
{
double d1 = V_DATE(&var1),
d2 = V_DATE(&var2);
int nD1 = (int)d1,
nD2 = (int)d2;
nRes = Compare(nD1, nD2);
}
else if (nType1 == VT_I4)
{
long n1 = V_I4(&var1),
n2 = V_I4(&var2);
nRes = Compare(n1, n2);
}
else if (nType1 == VT_I2)
{
short n1 = V_I2(&var1),
n2 = V_I2(&var2);
nRes = Compare(n1, n2);
}
else if (nType1 == VT_R8)
{
double n1 = V_R8(&var1),
n2 = V_R8(&var2);
nRes = Compare(n1, n2);
}
else if (nType1 == VT_R4)
{
float n1 = V_R4(&var1),
n2 = V_R4(&var2);
nRes = Compare(n1, n2);
}
}
return nRes;
}
// 比较两行的大小
int CompareBookmark(COleVariant *g_lstSortFieldContents,
const long *bookmark1, const long *bookmark2)
{
COleVariant &var1 = g_lstSortFieldContents[(int)(*bookmark1)],
&var2 = g_lstSortFieldContents[(int)(*bookmark2)];
return CompareVariant(var1, var2);
}
#endif