📄 odbcdbgridfile.cpp
字号:
// OdbcDBGridFILE.cpp: implementation of the COdbcDBGridFILE class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "demo2.h"
#include "OdbcDBGridFILE.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
COdbcDBGridFILE::COdbcDBGridFILE(CGridCtrl *pGrid , CDatabase *pDatabase, CString strSql, CString strFilePath)
{
m_pGrid = pGrid;
m_pDatabase = pDatabase;
m_strFilePath = strFilePath;
m_strSql = strSql;
m_hFile = NULL;
m_hFilemap = NULL;
m_pvFile = NULL;
m_cpWrite = NULL;
m_iCurrentCount = 1;
m_iTotalCount = 0;
m_pRowFileInfo = NULL;
m_iMapFileSize = 8 * 1024 * 1024;
m_iOnceReadRows = 500;
m_iColumns = 0;
}
COdbcDBGridFILE::~COdbcDBGridFILE()
{
}
int COdbcDBGridFILE::GetSelectTotalCount()
{
int iResult = 0;
CString strValue = "";
CString strSql = "select count(*) from ( "+ m_strSql + ") chensl";
if(m_pDatabase == NULL)
{
AfxMessageBox("odbc dbgrid 中的数据库指针为空");
return -1;
}
if(m_pDatabase->IsOpen() == FALSE)
{
AfxMessageBox("odbc dbgrid 中的数据库处于关闭状态");
return -1;
}
m_Set.m_pDatabase = m_pDatabase;
m_Set.Open(CRecordset::forwardOnly, (LPCTSTR)strSql);
m_Set.GetFieldValue((short)0, strValue);
m_Set.Close();
iResult = atoi((LPCTSTR)strValue);
return iResult;
}
int COdbcDBGridFILE::InitMapFile()
{
int i = 0;
m_pRowFileInfo = new SRowInfo[m_iTotalCount];
if(m_pRowFileInfo == NULL)
{
AfxMessageBox("分配用于存储每行记录的信息的结构失败");
return -1;
}
for(i = 0; i < m_iTotalCount; i++)
{
m_pRowFileInfo[i].bWritten = FALSE;
m_pRowFileInfo[i].pAddress = NULL;
}
m_hFile = ::CreateFile((LPCTSTR)m_strFilePath, GENERIC_READ | GENERIC_WRITE ,
0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
if(m_hFile == INVALID_HANDLE_VALUE)
{
AfxMessageBox("创建文件失败");
return -1;
}
m_hFilemap = ::CreateFileMapping(m_hFile, NULL, PAGE_READWRITE, 0, m_iMapFileSize, NULL);
if(m_hFilemap == NULL)
{
AfxMessageBox("创建文件映射失败");
::CloseHandle(m_hFile);
return -1;
}
::CloseHandle(m_hFile);
m_pvFile = ::MapViewOfFile(m_hFilemap,FILE_MAP_WRITE,0,0,0);
if(m_pvFile == NULL)
{
AfxMessageBox("映射文件失败");
::CloseHandle(m_hFilemap);
::CloseHandle(m_hFile);
return -1;
}
::CloseHandle(m_hFilemap);
m_cpWrite = (char *)m_pvFile;
return 0;
}
int COdbcDBGridFILE::InitGrid()
{
if(m_pGrid == NULL)
{
AfxMessageBox("发生错误,指向dbgrid控件的指针为空");
return -1;
}
m_iTotalCount = GetSelectTotalCount();
m_pGrid->SetVirtualMode(TRUE);
m_pGrid->SetRowCount(m_iTotalCount + 1);
m_pGrid->SetFixedRowCount(1);
m_iColumns = this->GetSelectSqlColumns();
if(m_Set.Open(CRecordset::forwardOnly, m_strSql) == 0)
{
AfxMessageBox("为查询语句打开记录集时失败");
return -1;
}
m_pGrid->SetColumnCount(m_iColumns + 1);
m_pGrid->SetFixedColumnCount(1);
this->InitMapFile();
return 0;
}
int COdbcDBGridFILE::FetchData()
{
int i;
CString strValue = "", strTemp = "";
char cpTemp[2048];
int iInitCount = m_iCurrentCount;
while( (!m_Set.IsEOF()) && ((m_iCurrentCount - iInitCount) < m_iOnceReadRows))
{
strTemp = "";
for(i = 0; i < m_iColumns; i++)
{
m_Set.GetFieldValue(i, strValue);
if(strValue.GetLength() == 0)
{
strTemp = strTemp + "null,";
}
else
{
strTemp = strTemp + strValue + ",";
}
}
sprintf(cpTemp, "%d=%s\r\n", m_iCurrentCount, (LPCTSTR)strTemp);
m_pRowFileInfo[m_iCurrentCount - 1].bWritten = TRUE;
m_pRowFileInfo[m_iCurrentCount - 1].pAddress = m_cpWrite;
if(((int)(m_cpWrite - (char *)m_pvFile)) >= m_iMapFileSize - 500)
{
// waitDlg.ShowWait("由于数据量很大,正在重新分配内存,请稍等....");
return -1;
}
strcpy(m_cpWrite, cpTemp);
m_cpWrite += strlen(cpTemp);
m_iCurrentCount++;
TRACE("the current rows is %d\r\n", m_iCurrentCount );
m_Set.MoveNext();
}
*m_cpWrite = '\0';
return 0;
}
int COdbcDBGridFILE::SetGridText(GV_DISPINFO *pDispInfo)
{
CString strTemp = "", strText = "";
if(pDispInfo->item.row == 0)//显示第一行的列名
{
if(pDispInfo->item.col > 0)
{
this->GetFieldInfo(pDispInfo->item.col - 1, strText);
pDispInfo->item.strText = strText;
}
}
else if(pDispInfo->item.col == 0)//显示行号
{
pDispInfo->item.strText.Format(_T("%d"),pDispInfo->item.row);
}
else
{
if(GetAGridData(pDispInfo->item.row, pDispInfo->item.col, strText) == 0)
{
pDispInfo->item.strText = strText;
}
else
{
pDispInfo->item.strText = "";
return -1;
}
}
return 0;
}
int COdbcDBGridFILE::GetAGridData(int iRow, int iCol, CString &strOut)
{
CString strTemp, strField;
int iCount = 1, i = 0;
char cpToken[] = ",";
char *cpTemp1 = NULL, *cpTemp2 = NULL;
char cpRow[1024];
strTemp.Format("%d=", iRow);
while(m_pRowFileInfo[iRow - 1].bWritten == FALSE)
{
// waitDlg.ShowWait("正在获取数据,请稍等....");
if(FetchData() != 0)
{
DealMapFileSizeLess();
return -1;
}
}
// waitDlg.ShowWindow(SW_HIDE);
cpTemp2 = strstr(m_pRowFileInfo[iRow - 1].pAddress, "\r\n");
if(cpTemp2)
{
cpTemp1 = m_pRowFileInfo[iRow - 1].pAddress + strTemp.GetLength();
strncpy(cpRow, cpTemp1, (int)(cpTemp2 - cpTemp1));
strcpy(cpRow + (int)(cpTemp2 - cpTemp1), "\0");
char *cpResult = strtok(cpRow, cpToken);
while(cpResult != NULL)
{
if(iCount == iCol)
{
strOut.Format("%s", cpResult);
if(strOut == "null")
{
strOut = "";
}
break;
}
cpResult = strtok( NULL, cpToken );
iCount++;
}
}
return 0;
}
int COdbcDBGridFILE::Release()
{
if(m_cpWrite != NULL)
{
m_cpWrite = NULL;
}
if(m_pRowFileInfo != NULL)
{
delete []m_pRowFileInfo; m_pRowFileInfo = NULL;
}
m_Set.Close();
if(m_pvFile)
{
::UnmapViewOfFile(m_pvFile);
}
m_iCurrentCount = 1;
return 0;
}
int COdbcDBGridFILE::DealMapFileSizeLess()
{
m_iMapFileSize += 10 * 1024 * 1024;
m_pGrid->DeleteAllItems();
this->Release();
this->InitGrid();
// waitDlg.ShowWindow(SW_HIDE);
return 0;
}
int COdbcDBGridFILE::GetSelectSqlColumns()
{
int i = 0;
CString strValue = "";
if(m_pDatabase == NULL)
{
AfxMessageBox("odbc dbgrid 中的数据库指针为空");
return -1;
}
if(m_pDatabase->IsOpen() == FALSE)
{
AfxMessageBox("odbc dbgrid 中的数据库处于关闭状态");
return -1;
}
m_Set.m_pDatabase = m_pDatabase;
m_Set.Open(CRecordset::forwardOnly, (LPCTSTR)m_strSql);
try
{
for(i = 0; i < 500; i++)
{
m_Set.GetFieldValue((short)i, strValue);
}
}
catch(CDBException *e)
{
m_Set.Close();
if(e->m_nRetCode == AFX_SQL_ERROR_FIELD_NOT_FOUND)
{
e->Delete();
return i;
}
else
{
e->ReportError();
e->Delete();
return -1;
}
}
return -1;
}
int COdbcDBGridFILE::GetFieldInfo(int iFieldIndex, CString &strFieldName)
{
CODBCFieldInfo info;
m_Set.GetODBCFieldInfo((short)iFieldIndex, info);
strFieldName = info.m_strName;
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -