MapRecordSet.cpp
上传用户:bjslfz
上传日期:2022-07-25
资源大小:4430k
文件大小:8k
源码类别:

文件操作

开发平台:

C/C++

  1. #include "stdafx.h"
  2. #include "global.h"
  3. #include "MapField.h"
  4. #include "MapFields.h"
  5. #include "MapTableDesc.h"
  6. #include "MapRecordSet.h"
  7. CMapRecordSet::CMapRecordSet()
  8. {
  9. m_CacheSize = 50;
  10. bBOF = FALSE;
  11. bEOF = FALSE;
  12. m_bDbfOpen = FALSE;
  13. iCursorPos = -1;
  14. }
  15. CMapRecordSet::~CMapRecordSet()
  16. {
  17. Clear();
  18. }
  19. long CMapRecordSet::GetRecordCount()
  20. {
  21. return m_Header.no_recs; 
  22. }
  23. CMapFields* CMapRecordSet::GetFields(long lIndex)
  24. {
  25. long lCount;
  26.     CMapFields *fields = NULL;
  27. CMapFields *pFields;
  28. lCount = m_Fields.GetSize() - 1; 
  29.     if ( lIndex < 0 || lIndex > lCount )
  30. return fields;
  31. pFields = m_Fields.GetAt(lIndex);
  32. return pFields;
  33. }
  34. CMapTableDesc* CMapRecordSet::GetTableDesc()
  35. {
  36. return &m_TableDesc;
  37. }
  38. BOOL CMapRecordSet::GetBOF()
  39. {
  40. return bBOF; 
  41. }
  42. BOOL CMapRecordSet::GetEOF()
  43. {
  44. return bEOF;
  45. }
  46. int  CMapRecordSet::GetCacheSize()
  47. {
  48. return m_CacheSize;
  49. }
  50. BOOL CMapRecordSet::SetCacheSize(int& CacheSize)
  51. {
  52. if ( CacheSize < 0 || CacheSize > MAX_CACH_SIZE )
  53. return FALSE;
  54. return TRUE;
  55. }
  56. /*************************************************
  57.   描述:         打开DBF文件
  58.   输入:         文件名
  59.   输出:        成功返回TRUE 失败返回FALSE
  60. *************************************************/
  61. BOOL CMapRecordSet::openDBF(CString& csFileName)
  62. {
  63. unsigned int  iTemp;
  64. unsigned long ulReocrdCount;
  65. unsigned short ulLength,ulRecLength;
  66. short i,sFieldCount;
  67. char*  pszBuffer;
  68. FIELD_ELEMENT *pField,*pOldField;
  69.     CFileException fe;
  70. //打开主文件
  71. if ( !fDbf.Open(csFileName, CFile::modeRead|CFile::shareDenyWrite,&fe))
  72. return FALSE;
  73. m_bDbfOpen = TRUE;
  74. fDbf.Seek(0L, CFile::begin);
  75. //读入文件头 
  76. if ( fDbf.Read(&m_Header,sizeof(m_Header)) != sizeof(m_Header))
  77.      return FALSE;
  78. ulReocrdCount = m_Header.no_recs; 
  79. ulLength = m_Header.head_len;
  80.     ulRecLength = m_Header.rec_len; 
  81.    
  82. //计算字段个数
  83. sFieldCount = (ulLength - sizeof(DBF_HEADER)-1)/sizeof(FIELD_ELEMENT);
  84. iTemp = sFieldCount * sizeof(FIELD_ELEMENT) + 1;
  85. pszBuffer = new char[iTemp];
  86. if ( pszBuffer == NULL )
  87. return FALSE;
  88.     //读入字段描述部分数据(表结构)
  89. if ( fDbf.Read(pszBuffer,iTemp) != iTemp)
  90.     {     
  91.      delete []pszBuffer;
  92. return FALSE;
  93. }
  94. for ( i = 0 ; i < sFieldCount ; i++ )
  95. {
  96. pField = new FIELD_ELEMENT;
  97. if ( pField == NULL )
  98. {
  99. delete []pszBuffer;
  100.     m_TableDesc.Clear();     
  101. return FALSE; 
  102.         } 
  103. memcpy(pField,pszBuffer+i*sizeof(FIELD_ELEMENT),sizeof(FIELD_ELEMENT));
  104. if ( i == 0 )
  105.          pField->ulOffset = 0;
  106.         else
  107. pField->ulOffset = pOldField->ulOffset + pOldField->ucFieldLength; 
  108. //判断字段类型
  109. if ( pField->cFieldType != 'N' && pField->cFieldType != 'F' )
  110.         {   
  111. pField->ucFieldLength += pField->ucFieldDecimal*256; 
  112.             pField->ucFieldDecimal = 0;           
  113. }
  114. pOldField = pField;   
  115.         m_TableDesc.Add(pField);
  116.     }   
  117.     //读入记录到记录集缓冲区
  118.     ReadRecord(0);
  119.     fDbf.Close();
  120. delete []pszBuffer;
  121. return TRUE;
  122. }
  123. /*************************************************
  124.   描述:         读入数据记录 
  125.   输入:         记录的索引(从0开始)
  126.   输出:        无
  127. *************************************************/
  128. void CMapRecordSet::ReadRecord(unsigned long lRecordID)
  129. {
  130. int    j,iRecordOffset;
  131. char   *pszBuffer;
  132. char   szBuff[255];
  133. double dbValue;
  134. FIELD_ELEMENT *pField;
  135. CMapField *pMapField;
  136. CMapFields *pMapFields;
  137. VARIANT varValue;
  138. if( lRecordID < 0 || lRecordID >= m_Header.no_recs)
  139.         return; //无效的索引值
  140.     if ( iCursorPos != lRecordID) //要读取的记录未在缓存中
  141.     {
  142. //计算记录相对文件头的偏移量
  143. iRecordOffset = lRecordID*m_Header.rec_len + m_Header.head_len;
  144. pszBuffer = new char[ m_Header.rec_len];
  145.         fDbf.Seek(iRecordOffset , CFile::begin);   
  146. if ( fDbf.Read(pszBuffer,m_Header.rec_len) != m_Header.rec_len)
  147. {     
  148.      delete []pszBuffer;
  149. return ;
  150. }
  151.         
  152.     Clear();
  153. pMapFields = new CMapFields(); 
  154. for ( j = 0 ; j < m_TableDesc.GetFieldCount() ; j++)
  155. {
  156. pMapField = new CMapField;
  157. pField = m_TableDesc.GetDesc(j); 
  158. pMapField->SetName( pField->szFieldName );
  159. pMapField->SetType(pField->cFieldType);
  160. memset(szBuff , 0 , 255);
  161. //略过该记录是否删除标记字节pszBuffer+1
  162. strncpy(szBuff, pszBuffer+1+pField->ulOffset , pField->ucFieldLength);
  163. if ( pField->cFieldType == 'N' || pField->cFieldType == 'F' )
  164. {
  165. ::VariantInit(&varValue);
  166. dbValue = atof(szBuff );
  167. if ( pField->ucFieldDecimal == 0 )
  168. {   
  169. varValue.bVal = VT_I4;   
  170. varValue.lVal = (int)dbValue;
  171. pMapField->SetType(fdInteger);
  172. }
  173. else
  174. {
  175. varValue.bVal = VT_R8;
  176. varValue.dblVal = dbValue;
  177. pMapField->SetType(fdDouble);
  178.     }
  179. pMapField->SetValue(varValue);
  180. }
  181. else if ( pField->cFieldType == 'C' )
  182. {
  183. pMapField->SetValueAsString(szBuff);
  184. pMapField->SetType(fdString);
  185. }
  186. else
  187. pMapField->SetType(fdInvaild);
  188. pMapFields->Add(pMapField);  
  189.              
  190. }
  191. Clear(); //清空缓冲区加入新记录
  192. m_Fields.Add(pMapFields);
  193. delete []pszBuffer;
  194. iCursorPos = lRecordID;
  195. }
  196. }
  197. /*************************************************
  198.   描述:         移动到记录集头部
  199.   输入:         无
  200.   输出:        无
  201. *************************************************/
  202. void CMapRecordSet::MoveFirst()
  203. {
  204.  if ( !m_bDbfOpen ) //数据库文件未打开
  205.  return;
  206.  bBOF = TRUE;
  207.  bEOF = FALSE;
  208.  iCursorPos = -1;
  209.  ReadRecord(0);
  210.   
  211. }
  212. /*************************************************
  213.   描述:         移动到记录集尾部
  214.   输入:         无
  215.   输出:        无
  216. *************************************************/
  217. void CMapRecordSet::MoveLast()
  218. {
  219.      if ( !m_bDbfOpen ) 
  220.  return;
  221.  bEOF = TRUE;
  222.  ReadRecord(m_Header.no_recs - 1);  
  223. }
  224. /*************************************************
  225.   描述:         移动到下一条记录
  226.   输入:         无
  227.   输出:        无
  228. *************************************************/
  229. void CMapRecordSet::MoveNext()
  230. {
  231.  if ( !m_bDbfOpen ) 
  232.  return;
  233.  
  234.  if ( m_Header.no_recs == 1 )
  235.      {
  236.  bBOF = TRUE;
  237.  bEOF = TRUE;
  238.  return;
  239.      }   
  240.  if ( iCursorPos < m_Header.no_recs-1)
  241.      {
  242.  bBOF = FALSE;
  243.  ReadRecord(iCursorPos + 1);
  244.      } 
  245.  else
  246.         bEOF = TRUE; 
  247. }
  248. /*************************************************
  249.   描述:         移动到上一条记录
  250.   输入:         无
  251.   输出:        无
  252. *************************************************/
  253. void CMapRecordSet::MovePrev()
  254. {
  255. if ( !m_bDbfOpen ) //数据库文件未打开
  256.  return;
  257.  
  258. if ( m_Header.no_recs == 1 )
  259.     {
  260.  bBOF = TRUE;
  261.  bEOF = TRUE;
  262.  return;
  263.     }   
  264. if ( iCursorPos > 0 )
  265.     {
  266.  bEOF = FALSE;
  267.  ReadRecord(iCursorPos - 1);
  268. else
  269.         bBOF = TRUE; 
  270. }
  271. /*************************************************
  272.   描述:         移动iNumRecords条记录
  273.   输入:         移动的记录数、移动相对位置
  274.   输出:        无
  275. *************************************************/
  276. BOOL CMapRecordSet::Move(int iNumRecords , RECORDSTART Start )
  277. {
  278. int iPos;
  279. /*if ( bEOF && iNumRecords > 0 ) //已经到记录集末尾
  280. return FALSE;
  281. if ( bBOF && iNumRecords < 0 ) //已经到记录集头
  282. return FALSE;
  283. if ( iNumRecords == 0 )
  284. return TRUE;*/
  285. switch ( Start )
  286.     {
  287. case BookmarkCurrent:
  288. iPos = iCursorPos; 
  289. break;
  290.         case BookmarkLast:
  291. iPos = m_Header.no_recs - 1;
  292. break;
  293.         default: // BookmarkFirst
  294. iPos = 0; 
  295. break;
  296. }
  297. if ( iNumRecords > 0 ) //向后移动
  298.     {
  299. if ( m_Header.no_recs <= (unsigned long)(iPos + iNumRecords))
  300. return FALSE;
  301. else
  302.         {
  303. ReadRecord(iPos + iNumRecords);
  304. return TRUE;
  305. }
  306. }
  307. else
  308.     {
  309.     if (  (iPos + iNumRecords) < 0 )
  310. return FALSE;
  311. else
  312.         {
  313. ReadRecord(iPos + iNumRecords);
  314. return TRUE;
  315. }
  316.     }
  317. }
  318. /*************************************************
  319.   描述:         清空记录缓冲区
  320.   输入:         无
  321.   输出:        无
  322. *************************************************/
  323. void CMapRecordSet::Clear()
  324. {
  325. int i;
  326. CMapFields *pMapFields;
  327. for ( i = m_Fields.GetSize() - 1 ; i >=0  ; i-- )
  328. {
  329. pMapFields = m_Fields.GetAt(i);
  330. delete pMapFields;
  331. }
  332. m_Fields.RemoveAll(); 
  333. }