Files
envi-code/SourceCode/Code2026/tg_shs/shs_dbf/DbfTools.cpp
T

676 lines
12 KiB
C++
Raw Normal View History

2026-09-28 15:28:50 +08:00
#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 TDBFUTILITY_IMPEXP 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 TDBFUTILITY_IMPEXP 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