#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; iAddField(&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; i0) { 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 inline int Compare(K n1, K n2) { if(n1>n2) return 1; else if(n1