/******************************************************************
 模塊名稱:數(shù)據(jù)庫操作類;
 實現(xiàn)功能:提供接口,實現(xiàn)數(shù)據(jù)的索引,和操作。
 研究人員:長壽夢;
 最后更新:2010-05-12

 預(yù)先操作:
 【1】在stdafx.h中添加
    #import "C:\Program Files\Common Files\System\ado\msado15.dll" no_namespace rename("EOF","adoEOF")
 【2】在主進(jìn)程的InitInstance()中添加
         if(!AfxOleInit())
        {
         AfxMessageBox("OLE初始化錯誤");
         return FALSE;
         }

 【3】在.cpp文件中要包含"CPFile.h"
********************************************************************
*/


/*****************************************************************
CPFile.h
*****************************************************************
*/

class CPData  
{
public:
    
    
//默認(rèn)初始化構(gòu)造函數(shù)
    CPData();
    
    
//傳入連接的構(gòu)造函數(shù)
    CPData(_ConnectionPtr pConnection);
    
    
//析構(gòu)函數(shù)
    virtual ~CPData();
public:
    
    
//連接數(shù)據(jù)庫
    BOOL Connect(CString strUser,CString strPassword,CString strFileName="ConnectionParam.udl",int nOptions=-1,CString strConStr="Provider=sqloledb.1;Data Source=(local);Database=VLan");
    
    
//關(guān)閉數(shù)據(jù)庫的連接
    void DisConnect();
    
    
//數(shù)據(jù)庫查詢語句,用來對數(shù)據(jù)庫的各種字段進(jìn)行查詢
    
//如果成功返回TRUE,否則返回FALSE.查詢的結(jié)果存儲在類的共有成員變量m_pRecordset中
    
//查詢結(jié)果的行數(shù)和列數(shù)分別保存在共有成員變量m_nResultRow和m_nResultCol中
    BOOL Select(CString strSql);
    
    
//查詢語句,負(fù)責(zé)對僅僅查詢一個字段的情況進(jìn)行處理
    
//結(jié)果存放在CStringArray類型的變量pResult中
    BOOL Select(CString strSql,CStringArray& Result);
    
    
//對多個字段進(jìn)行查詢
    BOOL SelectMulitCol(CString strSql,CStringArray& Result);
    
    
//打開表
    BOOL OpenTable(CString strTable);
    
    
//打開表
    BOOL OpenTable(CString strTable,CStringArray& Result);
    
    
//進(jìn)行其它的更新操作
    BOOL Execute(CString strSql);
public:
    BOOL ExecuteTrans(CStringArray
& aSql);    
    
    
//關(guān)閉結(jié)果集合
    void CloseRecordset();
    
    
//得到操作結(jié)果的列數(shù)
    long GetResultCol();
    
    
//得到操作結(jié)果的條數(shù)
    long GetResultRow();
    
    
//得到操作結(jié)果
    _RecordsetPtr GetResult();
private:
    
    
//數(shù)據(jù)庫操作返回的結(jié)果條數(shù)
    long m_nResultRow;
    
    
//返回的_RecordsetPtr中列數(shù)
    long m_nResultCol;
    
    
//連接指針
    _ConnectionPtr m_pConnection;
    
    
//命令執(zhí)行指針
    _CommandPtr m_pCommand;
    
    
//結(jié)果集指針
    _RecordsetPtr m_pRecordset;
}
;

/**************************************************************
CPFile.cpp
*************************************************************
*/


//////////////////////////////////////////////////////////////////////
// 構(gòu)造函數(shù)
//////////////////////////////////////////////////////////////////////
//默認(rèn)的構(gòu)造函數(shù)
CPData::CPData()
{
    
//初始化
    m_nResultRow = 0;
    m_nResultCol
=0;
    m_pConnection 
= NULL;
    
//創(chuàng)建對象
    m_pRecordset.CreateInstance(_uuidof(Recordset));
    m_pCommand.CreateInstance(_uuidof(Command)); 
}


//傳入?yún)?shù)的構(gòu)造函數(shù)
CPData::CPData(_ConnectionPtr pConnection)
{
    m_pConnection 
= pConnection; 
    m_nResultRow 
= 0;
    m_nResultCol
=0;
    
//創(chuàng)建對象
    m_pRecordset.CreateInstance(_uuidof(Recordset));
    m_pCommand.CreateInstance(_uuidof(Command)); 
    
}

//////////////////////////////////////////////////////////////////////
// 析構(gòu)函數(shù)
//////////////////////////////////////////////////////////////////////
CPData::~CPData()

    
if(m_pRecordset->State!=adStateClosed)
        m_pRecordset
->Close();
    m_pRecordset 
= NULL;

    
if(m_pCommand->State!=adStateClosed)
        m_pCommand
->Release();
    m_pCommand 
= NULL;

    
if(m_pConnection->State!=adStateClosed) 
        m_pConnection
->Close();
    m_pConnection 
= NULL; 
}


/////////////////////////////////////////////////////////////////////
///簡單操作函數(shù)
////////////////////////////////////////////////////////////////////


//得到操作結(jié)果的行數(shù)
long CPData::GetResultRow()
{
    
return this->m_nResultRow;
}


//得到操作結(jié)果的列數(shù)
long CPData::GetResultCol()
{
    
return this->m_nResultCol;
}


//得到操作結(jié)果
_RecordsetPtr CPData::GetResult()
{
    
return this->m_pRecordset;
}


///////////////////////////////////////////////////////////////////////
///連接操作
///////////////////////////////////////////////////////////////////////


//連接到數(shù)據(jù)庫
//1.連接字符串可以自己構(gòu)造,也可以從文件中讀出
BOOL CPData::Connect(CString strUser,CString strPassword,CString strFileName,int nOptions,CString strConStr)
{
    
try
        m_pConnection.CreateInstance(__uuidof(Connection));
        HRESULT hr;
        
//如果用文件方式配置數(shù)據(jù)源,進(jìn)行配置
        if(strFileName.Compare("")!=0&&CPFile::IsFileExist(strFileName))
        
{
            CString con 
= "File Name="+strFileName;
            m_pConnection
->ConnectionString =(_bstr_t)con;
            hr
=m_pConnection->Open("","","",nOptions);    
        }

        
else
        
{
            
//自己配置連接字符串
            m_pConnection->ConnectionString = (_bstr_t)strConStr;
            hr
=m_pConnection->Open("",_bstr_t(strUser),_bstr_t(strPassword),nOptions);  
        }

        
//進(jìn)行連接
        
//連接失敗
        if(FAILED(hr))
        
{   
            AfxMessageBox(
"連接失敗!");
            
return FALSE;
        }

    }

    
catch(_com_error&e)
    
{
        AfxMessageBox(e.Description()
+"B");
        
return FALSE;
    }
 
    
return TRUE;
}


//斷開連接
void CPData::DisConnect()
{
    
if(m_pConnection->State!=adStateClosed)
        m_pConnection
->Close(); 
}


///////////////////////////////////////////////////////////////////////
///更新操作
///////////////////////////////////////////////////////////////////////

BOOL CPData::Execute(CString strSql)
{
    
try
    
{
        _variant_t vNULL;
        vNULL.vt 
= VT_ERROR;
        
        
///定義為無參數(shù)
        vNULL.scode = DISP_E_PARAMNOTFOUND;
        
        
///非常關(guān)鍵的一句,將建立的連接賦值給它
        m_pCommand->ActiveConnection = m_pConnection;
        
        
///命令字串
        m_pCommand->CommandText = (_bstr_t)strSql;
        
        
///執(zhí)行命令,取得記錄集
        m_pRecordset = m_pCommand->Execute(&vNULL,&vNULL,adCmdText);
        
        
//確實,vNULL中的intVal是執(zhí)行操作所影響的行數(shù)
        m_nResultRow = 0;
        m_nResultRow 
= vNULL.intVal;  
    }

    
catch(_com_error&e)
    
{
        m_nResultRow 
= 0;  
        
return FALSE;
    }

    
return TRUE;
}


///////////////////////////////////////////////////////////////////////
///查詢操作
///////////////////////////////////////////////////////////////////////

BOOL CPData::Select(CString strSql)
{
    
try
    
{
        m_nResultCol
=0;
        m_nResultRow
=0;  
        m_pRecordset
->CursorLocation=adUseClient;    //設(shè)置游標(biāo)位置,設(shè)置為客戶端形式,否則GetRecordCount()返回值不對
        m_pRecordset->Open(_variant_t(strSql),_variant_t((IDispatch *)m_pConnection,true),adOpenDynamic,adLockOptimistic,adCmdText);
        m_nResultCol 
= m_pRecordset->Fields->GetCount();//得到查詢結(jié)果的列數(shù)
        m_nResultRow = m_pRecordset->GetRecordCount();  //得到查詢結(jié)果的行數(shù)
    }

    
catch(_com_error&e)
    
{  
        AfxMessageBox(e.Description()
+"D");
        
return FALSE;
    }

    
return TRUE;
}


//查詢語句,負(fù)責(zé)對僅僅查詢一個字段的情況進(jìn)行處理
//結(jié)果存放在CStringArray類型的變量pResult中
BOOL CPData::Select(CString strSql,CStringArray& Result)
{
    
if(Select(strSql)!=0)
    
{
        Result.RemoveAll();
        
for(int i=0;i<m_nResultRow;i++)
        
{
            _variant_t value;
            value
=m_pRecordset->Fields->Item[(long)0]->Value;   
            
if(value.vt==3||value.vt==14)
            
{
                CString strTrans;
                strTrans.Format(
"%ld",value.intVal);
                Result.Add(strTrans);
            }

            
else
                Result.Add(value.bstrVal);
//
            m_pRecordset->MoveNext();
        }

        m_pRecordset
->Close();
        
return TRUE;
    }

    
else
    
{
        m_pRecordset
->Close();
        
return FALSE;
    }

}


BOOL CPData::SelectMulitCol(CString strSql,CStringArray
& Result)
{
    
if(Select(strSql)!=0)
    
{
        Result.RemoveAll();
        _variant_t value;
        
for(int i=0;i<m_nResultRow;i++)
        
{   
            
for(int j=0;j<m_nResultCol;j++)
            
{
                value
=m_pRecordset->Fields->Item[(long)(/*i*m_nResultCol+*/j)]->Value;
                
if(value.vt==3||value.vt==14)
                
{
                    CString strTrans;
                    strTrans.Format(
"%ld",value.intVal);
                    Result.Add(strTrans);
                }

                
else
                    
if(value.vt==7)
                    
{
                        COleDateTime time 
= value.date;
                        CString strTemp;
                        strTemp.Format(
"%d-%d-%d %s",time.GetYear(),time.GetMonth(),time.GetDay(),time.Format("%H:%M:%S"));
                        Result.Add(strTemp);
                    }

                    
else
                        Result.Add(value.bstrVal);
//
            }

            m_pRecordset
->MoveNext();
        }

        m_pRecordset
->Close();
        
return TRUE;
    }

    
else
    

        m_pRecordset
->Close();
        
return FALSE;
    }

}


//打開整張表
BOOL CPData::OpenTable(CString strTable)
{
    
try
    
{
        m_nResultCol
=0;
        m_nResultRow
=0;  
        m_pRecordset
->CursorLocation=adUseClient;    //設(shè)置游標(biāo)位置,設(shè)置為客戶端形式,否則GetRecordCount()返回值不對
        m_pRecordset->Open(_variant_t(strTable),_variant_t((IDispatch *)m_pConnection,true),adOpenDynamic,adLockOptimistic,adCmdTable);
        m_nResultCol 
= m_pRecordset->Fields->GetCount();//得到查詢結(jié)果的列數(shù)
        m_nResultRow = m_pRecordset->GetRecordCount();  //得到查詢結(jié)果的行數(shù)
    }

    
catch(_com_error&e)
    
{  
        AfxMessageBox(e.Description()
+"E");
        
return FALSE;
    }

    
return TRUE;
}


BOOL CPData::OpenTable(CString strTable,CStringArray
& Result)
{
    
if(OpenTable(strTable)!=0)
    
{
        Result.RemoveAll();
        _variant_t value;
        
for(int i=0;i<m_nResultRow;i++)
        
{   
            
for(int j=0;j<m_nResultCol;j++)
            
{
                value
=m_pRecordset->Fields->Item[(long)(/*i*m_nResultCol+*/j)]->Value;
                
if(value.vt==3||value.vt==14)
                
{
                    CString strTrans;
                    strTrans.Format(
"%ld",value.intVal);
                    Result.Add(strTrans);
                }

                
else
                    
if(value.vt==7)
                    
{
                        COleDateTime time 
= value.date;
                        CString strTemp;
                        strTemp.Format(
"%d-%d-%d %s",time.GetYear(),time.GetMonth(),time.GetDay(),time.Format("%H:%M:%S"));
                        Result.Add(strTemp);
                    }

                    
else
                        Result.Add(value.bstrVal);
//
            }

            m_pRecordset
->MoveNext();
        }

        m_pRecordset
->Close();
        
return TRUE;
    }

    
else
    
{
        
return FALSE;
    }

}


/////////////////////////////////////////////////////////////////////////////
///關(guān)閉結(jié)果集
/////////////////////////////////////////////////////////////////////////////

void CPData::CloseRecordset()
{
    
if(m_pRecordset->State != adStateClosed)
        m_pRecordset
->Close();
}

BOOL CPData::ExecuteTrans(CStringArray
& aSql)
{
    
try{
        
int nNum = aSql.GetSize();
        m_pConnection
->BeginTrans(); 
        
for(int i=0;i<nNum;i++)
        
{
            CString strSql 
= aSql.GetAt(i);  
            m_pConnection
->Execute((_bstr_t)aSql.GetAt(i),NULL,adCmdText);
        }

        m_pConnection
->CommitTrans(); 
        
return TRUE;
    }

    
catch(_com_error& e)
    
{
        m_pConnection
->RollbackTrans();  
        AfxMessageBox(e.Description()
+"F");
        
return FALSE;
    }
 
}