// UpdateDataBase.cpp: implementation of the CUpdateDataBase class. // ////////////////////////////////////////////////////////////////////// #include "geomative.h" #include "UpdateDataBase.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif extern SYSTEMTIME g_sysCurTime; extern int g_iUILanguage; ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CUpdateDataBase::CUpdateDataBase(_ConnectionPtr pConnection, CString strVer) { m_strPreVersion = _T(""); m_vtUpdateDBInfo.clear(); m_pConnection = pConnection; m_pLog = fopen("LOG\\update_db.log", "ab+"); m_strCurVer = strVer; if (NULL == m_pLog) { CString strLog = _T(""); if (LANG_ZHCN == g_iUILanguage) { strLog.Format(_T("打开 update_db.log 失败! 错误码 = %d"), GetLastError()); AfxMessageBox(strLog); } else { strLog.Format(_T("Open update_db.log failed! error = %d"), GetLastError()); MessageBoxEx(NULL, strLog, STRING_MESSAGEBOXEX_TITLE, MB_OK, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)); } } } CUpdateDataBase::~CUpdateDataBase() { } bool CUpdateDataBase::QueryPreVersion() { if (!CheckNecessaryVersion()) { return false; } CString szSql= _T("select version from versioninfo"); _RecordsetPtr pRecPro = NULL; pRecPro.CreateInstance(_uuidof(Recordset)); pRecPro->Open(szSql.AllocSysString(), _variant_t((IDispatch*)m_pConnection, true), adOpenStatic, adLockOptimistic, adCmdText); if ((long)VAL_ZERO != pRecPro->GetRecordCount()) { m_strPreVersion = pRecPro->GetCollect(_T("version")).vt == VT_NULL ? _T("") : (LPCTSTR)(_bstr_t)pRecPro->GetCollect(_T("version")); } else { CString strTmp = _T(""); pRecPro->Close(); if (LANG_ZHCN == g_iUILanguage) { strTmp.Format(_T("[%d]获取版本信息失败!!!"), __LINE__); AfxMessageBox(strTmp.GetBuffer(0)); } else { strTmp.Format(_T("[%d]Get version info failed!!!"), __LINE__); MessageBoxEx(NULL, strTmp, STRING_MESSAGEBOXEX_TITLE, MB_OK, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)); } PrintLog(strTmp); return false; } pRecPro->Close(); CString strTmp = _T(""); strTmp.Format(_T("[%d] query version is %s"), m_strPreVersion.GetBuffer(0)); return true; } bool CUpdateDataBase::CheckNecessaryVersion() { CString szSql= _T("select version from versioninfo"); _RecordsetPtr pRecPro = NULL; pRecPro.CreateInstance(_uuidof(Recordset)); pRecPro->Open(szSql.AllocSysString(), _variant_t((IDispatch*)m_pConnection, true), adOpenStatic, adLockOptimistic, adCmdText); //如果查询到之前的版本信息,则不做任何操作,返回真 if ((long)VAL_ZERO != pRecPro->GetRecordCount()) { pRecPro->Close(); return true; } //如果之前没有版本信息,则认为是1.5版本,插入相应的版本号 pRecPro->Close(); _CommandPtr pCmdUpd = NULL; pCmdUpd.CreateInstance(_uuidof(Command)); pCmdUpd->ActiveConnection = m_pConnection; try { m_pConnection->BeginTrans(); szSql.Empty(); szSql.Format(_T("insert into versioninfo(ID,version) values(1,'%s')"), _T("1.5.28")); pCmdUpd->CommandText = szSql.AllocSysString(); pCmdUpd->Execute(NULL, NULL, adCmdText); m_pConnection->CommitTrans(); return true; } catch (_com_error e) { m_pConnection->RollbackTrans(); AfxMessageBox((LPCTSTR)e.Description()); CString strLogInfo = _T(""); strLogInfo.Format(_T("[%d] write necessary version failed, error_msg = %s"), __LINE__, (LPCTSTR)e.Description()); PrintLog(strLogInfo); return false; } } bool CUpdateDataBase::WriteVersionToDB() { CString strSql = _T(""); CString strTmp = _T(""); if (m_strCurVer.IsEmpty()) { if (LANG_ZHCN == g_iUILanguage) { strTmp.Format(_T("[%d] 版本参数为空!"), __LINE__); AfxMessageBox(strTmp.GetBuffer(0)); } else { strTmp.Format(_T("[%d] Version param is null!!!"), __LINE__); MessageBoxEx(NULL, strTmp, STRING_MESSAGEBOXEX_TITLE, MB_OK, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)); } PrintLog(strTmp); return false; } _CommandPtr pCmdUpd = NULL; pCmdUpd.CreateInstance(_uuidof(Command)); pCmdUpd->ActiveConnection = m_pConnection; try { strSql.Format(_T("update versioninfo a set a.version = '%s' where a.id = 1;"), m_strCurVer.GetBuffer(0)); m_pConnection->BeginTrans(); pCmdUpd->CommandText = strSql.AllocSysString(); pCmdUpd->Execute(NULL, NULL, adCmdText); m_pConnection->CommitTrans(); return true; strTmp.Empty(); strTmp.Format(_T("[%d] write version is %s"), m_strPreVersion.GetBuffer(0)); PrintLog(strTmp); return true; } catch (_com_error e) { m_pConnection->RollbackTrans(); AfxMessageBox((LPCTSTR)e.Description()); CString strLogInfo = _T(""); strLogInfo.Format(_T("[%d] write version %s failed, error_msg = %s"), __LINE__, m_strCurVer.GetBuffer(0), (LPCTSTR)e.Description()); PrintLog(strLogInfo); return false; } } STColInfo CUpdateDataBase::GetColumnInfo(int nType) { STColInfo stCol; stCol.strColName = m_opXml.GetChildAttrib(_T("name")); CString strVal = _T(""); strVal = m_opXml.GetChildAttrib(_T("modify_type")); if (!strVal.IsEmpty()) { stCol.nModifyType = atoi(strVal.GetBuffer(0)); strVal.Empty(); } //增加表的操作 if ((1 == nType) || (3 == nType && 1 == stCol.nModifyType) ) { strVal = m_opXml.GetChildAttrib(_T("is_primary_key")); if (!strVal.IsEmpty()) { stCol.nIsPrimaryKey = atoi(strVal.GetBuffer(0)); } strVal = m_opXml.GetChildAttrib(_T("value_type")); if (!strVal.IsEmpty()) { stCol.nValueType = atoi(strVal.GetBuffer(0)); } strVal = m_opXml.GetChildAttrib(_T("attribute_value")); if (!strVal.IsEmpty()) { stCol.nAttrType = atoi(strVal.GetBuffer(0)); } strVal = m_opXml.GetChildAttrib(_T("index")); if (!strVal.IsEmpty()) { stCol.nIndex = atoi(strVal.GetBuffer(0)); } strVal = m_opXml.GetChildAttrib(_T("is_foreign_key")); if (!strVal.IsEmpty()) { stCol.nIsForeignKey = atoi(strVal.GetBuffer(0)); if (1 == stCol.nIsForeignKey) { stCol.strRefTableName = m_opXml.GetChildAttrib(_T("refer_table_name")); stCol.strRefTableCol = m_opXml.GetChildAttrib(_T("refer_table_col")); } } strVal = m_opXml.GetChildAttrib(_T("is_empty")); if (!strVal.IsEmpty()) { stCol.nIsEmpty = atoi(strVal.GetBuffer(0)); } strVal = m_opXml.GetChildAttrib(_T("is_compress")); if (!strVal.IsEmpty()) { stCol.nIsCompress = atoi(strVal.GetBuffer(0)); } } else if (3 == nType && 3 == stCol.nModifyType) { strVal = m_opXml.GetChildAttrib(_T("value_type")); if (!strVal.IsEmpty()) stCol.nValueType = atoi(strVal.GetBuffer(0)); else stCol.nValueType = 0; strVal = m_opXml.GetChildAttrib(_T("attribute_value")); if (!strVal.IsEmpty()) stCol.nAttrType = atoi(strVal.GetBuffer(0)); else stCol.nAttrType = 0; strVal = m_opXml.GetChildAttrib(_T("index_modify")); if (!strVal.IsEmpty()) stCol.nIndex = atoi(strVal.GetBuffer(0)); else stCol.nIndex = 255; strVal = m_opXml.GetChildAttrib(_T("foreign_key_modify")); if (!strVal.IsEmpty()) { stCol.nIsForeignKey = atoi(strVal.GetBuffer(0)); if (1 == stCol.nIsForeignKey) { stCol.strRefTableName = m_opXml.GetChildAttrib(_T("refer_table_name")); stCol.strRefTableCol = m_opXml.GetChildAttrib(_T("refer_table_col")); } } else stCol.nIsForeignKey = 255; strVal = m_opXml.GetChildAttrib(_T("empty_modify")); if (!strVal.IsEmpty()) stCol.nIsEmpty = atoi(strVal.GetBuffer(0)); else stCol.nIsEmpty = 255; } return stCol; } bool CUpdateDataBase::GetDBUpdatesInfo() { //此时的必须是解析到pre_version的元素上 m_opXml.IntoElem(); bool bFind = false; CString strTmp = _T(""); while(m_opXml.FindElem(_T("table"))) { bFind = true; STTableInfo stTbale; stTbale.strTableName = m_opXml.GetAttrib(_T("name")); stTbale.nModifyType = atoi(m_opXml.GetAttrib(_T("modify_type")).GetBuffer(0)); //获取table 的name 和 modify_type if (stTbale.strTableName.IsEmpty() || stTbale.nModifyType < 1 || stTbale.nModifyType > 3) { strTmp.Empty(); strTmp.Format(_T("[%d] Get Table name or modifytype error, table_name = %s, modify_type = %d"), __LINE__, stTbale.strTableName.GetBuffer(0), stTbale.nModifyType); PrintLog(strTmp); m_vtUpdateDBInfo.clear(); return false; } //如果是删除数据库表,则只需获得数据库表名即可。 if (2 == stTbale.nModifyType) { m_vtUpdateDBInfo.push_back(stTbale); continue; } //查询子元素column bool bPrimaryKey = false; while(m_opXml.FindChildElem(_T("column"))) { STColInfo stColumn = GetColumnInfo(stTbale.nModifyType); if (stColumn.strColName.IsEmpty()) { strTmp.Empty(); strTmp.Format(_T("[%d] column name is empty in modify_type:%d"), __LINE__, stTbale.nModifyType); PrintLog(strTmp); m_vtUpdateDBInfo.clear(); return false; } if (1 == stColumn.nIsPrimaryKey) { bPrimaryKey = true; } stTbale.vtColInfo.push_back(stColumn); } //如果是增加数据表,但是又没有配置主键,则报错 if ((1 == stTbale.nModifyType) && !bPrimaryKey) { strTmp.Empty(); strTmp.Format(_T("[%d] can not found primary key in add table"), __LINE__); m_vtUpdateDBInfo.clear(); return false; } m_vtUpdateDBInfo.push_back(stTbale); } return true; }; bool CUpdateDataBase::ParserUpdateDBXml() { //如果没有这个文件,则说明不需要更新数据库 bool bRes = m_opXml.Load(_T("updates\\database_modify.xml")); CString strTmp = _T(""); if (!bRes) { strTmp.Format(_T("[%d] load database_modify.xml failed, error_msg = %s"), __LINE__, m_opXml.GetError().GetBuffer(0)); PrintLog(strTmp); return true; } m_opXml.ResetPos(); if (!m_opXml.FindElem(_T("current_version"))) { strTmp.Format(_T("[%d] find element current_version failed, error_msg = %s"), __LINE__, m_opXml.GetError().GetBuffer(0)); PrintLog(strTmp); return false; } CString strVer = m_opXml.GetAttrib(_T("value")); if (strVer.IsEmpty()) { strTmp.Format(_T("[%d] current version info is empty"), __LINE__); PrintLog(strTmp); return false; } if (0 != m_strCurVer.Compare(strVer.GetBuffer(0))) { strTmp.Format(_T("[%d] current version is not equal to xml's version info, curVer = %s, xmlCurVer = %s"), __LINE__, m_strCurVer.GetBuffer(0), strVer.GetBuffer(0)); PrintLog(strTmp); return true; } strTmp.Empty(); m_opXml.IntoElem(); //查询之前的版本信息的更改记录 if (!QueryPreVersion()) { return false; } // if (!m_opXml.FindElem(_T("pre_version"))) // { // strTmp.Format(_T("[%d] find element pre_version failed, error_msg = %s"), __LINE__, m_opXml.GetError().GetBuffer(0)); // PrintLog(strTmp); // return false; // } // CString strPreVer = m_opXml.GetAttrib(_T("value")); CString strPreVer = _T("NULL"); while(0 != m_strPreVersion.Compare(strPreVer.GetBuffer(0))) { if (!m_opXml.FindElem(_T("pre_version"))) { strTmp.Empty(); strTmp.Format(_T("[%d] can not found version = %s modify information"), __LINE__, m_strPreVersion.GetBuffer(0)); PrintLog(strTmp); return true; } strPreVer = m_opXml.GetAttrib(_T("value")); } if (!GetDBUpdatesInfo()) { return false; } return true; } void CUpdateDataBase::PrintLog(CString& strLog) { if (NULL == m_pLog) { if (LANG_ZHCN == g_iUILanguage) AfxMessageBox(_T("无法写入device_log,日志文件点为空")); else MessageBoxEx(NULL, _T("Can't write device_log, log File point is NULL"), _T("LOG_ERROR"), MB_OK, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)); return; } CString strOutPut = _T(""); strOutPut.Format(_T("%04d-%02d-%02d %02d:%02d:%02d.%03d %s \r\n"),g_sysCurTime.wYear, g_sysCurTime.wMonth, g_sysCurTime.wDay, g_sysCurTime.wHour, g_sysCurTime.wMinute, g_sysCurTime.wSecond, g_sysCurTime.wMilliseconds, strLog.GetBuffer(0)); fwrite(strOutPut.GetBuffer(0), 1, strOutPut.GetLength(), m_pLog); fflush(m_pLog); } bool CUpdateDataBase::AddDBTable( STTableInfo stTable) { CString strSql = _T(""); CString strTmp = _T(""); strSql.Format(_T("create table %s ("), stTable.strTableName.GetBuffer(0)); std::vector vtIndexCol; std::vector vtForeignCol; vtIndexCol.clear(); vtForeignCol.clear(); //生成创建表的SQL语句 int i = 0; for (i = 0; i < stTable.vtColInfo.size(); i++) { STColInfo stCol = stTable.vtColInfo[i]; strTmp.Empty(); //添加列名和属性 if (1 == stCol.nValueType || 2 == stCol.nValueType) { strTmp.Format(_T("%s %s(%d)"), stCol.strColName.GetBuffer(0), chValueType[stCol.nValueType-1], stCol.nAttrType); if (1 == stCol.nIsCompress) { strTmp += " with compression"; } } else { if (1 == stCol.nIsCompress) { CString strLog = _T(""); strLog.Format(_T("[%d] can not set compress in value_type = %d"), __LINE__, stCol.nValueType); PrintLog(strLog); } strTmp.Format(_T("%s %s"), stCol.strColName.GetBuffer(0), chValueType[stCol.nValueType-1]); } strSql += strTmp; //添加其他属性 if (1 == stCol.nIsPrimaryKey) { strSql += _T(" primary key"); } if (1 == stCol.nIsForeignKey) { // strSql += _T(" foreign key"); vtForeignCol.push_back(i); } if (0 == stCol.nIsEmpty) { strSql += _T(" not null"); } else if(1 == stCol.nIsEmpty) { strSql += _T(" null"); } if (1 == stCol.nIndex || 2 == stCol.nIndex) { vtIndexCol.push_back(i); } if (i != (stTable.vtColInfo.size()-1)) strSql += _T(",\r"); else strSql += _T(");"); } //创建索引 std::vector vtExtSql; vtExtSql.clear(); for (i = 0; i < vtIndexCol.size(); i++ ) { CString strIndexSql = _T(""); STColInfo stIndexCol = stTable.vtColInfo[vtIndexCol[i]]; if (1 == stIndexCol.nIndex) strIndexSql.Format(_T("create index i%s on %s (%s);"), stIndexCol.strColName.GetBuffer(0), stTable.strTableName.GetBuffer(0), stIndexCol.strColName.GetBuffer(0)); else strIndexSql.Format(_T("create unique index i%s on %s (%s);"), stIndexCol.strColName.GetBuffer(0), stTable.strTableName.GetBuffer(0), stIndexCol.strColName.GetBuffer(0)); vtExtSql.push_back(strIndexSql); } //创建外键约束 for (i = 0; i < vtForeignCol.size(); i++ ) { CString strAddConsSql = _T(""); strAddConsSql.Format(_T("alter table %s add constraint FK_%s foreign key (%s) references %s (%s) on update cascade on delete cascade;"), stTable.strTableName.GetBuffer(0), stTable.vtColInfo[vtForeignCol[i]].strColName.GetBuffer(0), stTable.vtColInfo[vtForeignCol[i]].strColName.GetBuffer(0), stTable.vtColInfo[vtForeignCol[i]].strRefTableName.GetBuffer(0), stTable.vtColInfo[vtForeignCol[i]].strRefTableCol.GetBuffer(0)); vtExtSql.push_back(strAddConsSql); } _CommandPtr pCmdUpd = NULL; pCmdUpd.CreateInstance(_uuidof(Command)); pCmdUpd->ActiveConnection = m_pConnection; //执行数据库操作 try { m_pConnection->BeginTrans(); pCmdUpd->CommandText = strSql.AllocSysString(); pCmdUpd->Execute(NULL, NULL, adCmdText); for (i = 0; i < vtExtSql.size(); i++) { pCmdUpd->CommandText = vtExtSql[i].AllocSysString(); pCmdUpd->Execute(NULL, NULL, adCmdText); } m_pConnection->CommitTrans(); return true; } catch (_com_error e) { m_pConnection->RollbackTrans(); AfxMessageBox((LPCTSTR)e.Description()); CString strLogInfo = _T(""); strLogInfo.Format(_T("[%d] create table %s failed, error_msg = %s"), __LINE__, stTable.strTableName.GetBuffer(0), (LPCTSTR)e.Description()); PrintLog(strLogInfo); return false; } } bool CUpdateDataBase::DeleteDBTable(STTableInfo stTable) { _CommandPtr pCmdUpd = NULL; pCmdUpd.CreateInstance(_uuidof(Command)); pCmdUpd->ActiveConnection = m_pConnection; try { m_pConnection->BeginTrans(); CString strSql = _T(""); strSql.Format(_T("drop table %s;"), stTable.strTableName.GetBuffer(0)); pCmdUpd->CommandText = strSql.AllocSysString(); pCmdUpd->Execute(NULL, NULL, adCmdText); m_pConnection->CommitTrans(); return true; } catch (_com_error e) { m_pConnection->RollbackTrans(); AfxMessageBox((LPCTSTR)e.Description()); CString strLogInfo = _T(""); strLogInfo.Format(_T("[%d] drop table %s failed, error_msg = %s"), __LINE__, stTable.strTableName.GetBuffer(0), (LPCTSTR)e.Description()); PrintLog(strLogInfo); return false; } } bool CUpdateDataBase::AddTableCol(CString strTable, STColInfo stCol, std::vector& vtSql) { CString strSql = _T(""); CString strTmp =_T(""); strSql.Format(_T("alter table %s add "), strTable.GetBuffer(0)); //添加列名和属性 if (1 == stCol.nValueType || 2 == stCol.nValueType) { strTmp.Format(_T("%s %s(%d)"), stCol.strColName.GetBuffer(0), chValueType[stCol.nValueType-1], stCol.nAttrType); if (1 == stCol.nIsCompress) { strTmp += " with compression"; } } else { if (1 == stCol.nIsCompress) { CString strLog = _T(""); strLog.Format(_T("[%d] can not set compress in value_type = %d"), __LINE__, stCol.nValueType); PrintLog(strLog); } strTmp.Format(_T("%s %s"), stCol.strColName.GetBuffer(0), chValueType[stCol.nValueType-1]); } strSql += strTmp; //添加其他属性 if (1 == stCol.nIsPrimaryKey) { strSql += _T(" primary key"); } if (0 == stCol.nIsEmpty) { strSql += _T(" not null;"); } vtSql.push_back(strSql); strSql.Empty(); if (1 == stCol.nIndex) { strSql.Format(_T("create index i%s on %s (%s);"), stCol.strColName.GetBuffer(0), strTable.GetBuffer(0), stCol.strColName.GetBuffer(0)); vtSql.push_back(strSql); } else if (2 == stCol.nIndex) { strSql.Format(_T("create unique index i%s on %s (%s);"), stCol.strColName.GetBuffer(0), strTable.GetBuffer(0), stCol.strColName.GetBuffer(0)); vtSql.push_back(strSql); } if (1 == stCol.nIsForeignKey) { strSql.Empty(); strSql.Format(_T("alter table %s add constraint FK_%s foreign key(%s) references %s(%s) on update cascade on delete cascade;"), strTable.GetBuffer(0), stCol.strColName.GetBuffer(0), stCol.strColName.GetBuffer(0), stCol.strRefTableName.GetBuffer(0), stCol.strRefTableCol.GetBuffer(0)); vtSql.push_back(strSql); } return true; } bool CUpdateDataBase::ModifyTableCol(CString strTable, STColInfo stCol, std::vector& vtSql) { CString strSql = _T(""); strSql.Format(_T("alter table %s alter column %s"), strTable.GetBuffer(0), stCol.strColName.GetBuffer(0)); CString strTmp = _T(""); if (stCol.nValueType > 0 && stCol.nValueType < 13) { if (stCol.nValueType < 3) { if (stCol.nAttrType < 1) { if (LANG_ZHCN == g_iUILanguage) { strTmp.Format(_T("列属性的长度为列中的错误,长度= %d"), stCol.nAttrType); AfxMessageBox(strTmp); } else { strTmp.Format(_T("The length of column's attribute is error in column, length = %d"), stCol.nAttrType); MessageBoxEx(NULL, strTmp, STRING_MESSAGEBOXEX_TITLE, MB_OK, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)); } return false; } strTmp.Format(_T(" %s(%d)"), chValueType[stCol.nValueType-1], stCol.nAttrType); } else strTmp.Format(_T(" %s"), chValueType[stCol.nValueType-1]); //暂时只支持添加可以为空的属性 if (1 == stCol.nIsEmpty) strTmp += _T(" null;"); else strTmp +=_T(";"); strSql += strTmp; vtSql.push_back(strSql); } strSql.Empty(); //删除索引 if (0 == stCol.nIndex) { strSql.Format(_T("drop index i%s on %s;"), stCol.strColName.GetBuffer(0), strTable.GetBuffer(0)); vtSql.push_back(strSql); } else { //为保证增加索引成功,先删除索引 // strSql.Format(_T("drop index i%s on %s;"), stCol.strColName.GetBuffer(0), strTable.GetBuffer(0)); // vtSql.push_back(strSql); //增加索引 if (1 == stCol.nIndex) { strSql.Format(_T("create index i%s on %s (%s);"), stCol.strColName.GetBuffer(0), strTable.GetBuffer(0), stCol.strColName.GetBuffer(0)); vtSql.push_back(strSql); } else if (2 == stCol.nIndex) { strSql.Format(_T("create unique index i%s on %s (%s);"), stCol.strColName.GetBuffer(0), strTable.GetBuffer(0), stCol.strColName.GetBuffer(0)); vtSql.push_back(strSql); } } //增加外键约束 if (1 == stCol.nIsForeignKey) { strSql.Empty(); strSql.Format(_T("alter table %s add constraint FK_%s foregin key(%s) references %s(%s) on update cascade on delete cascade;"), strTable.GetBuffer(0), stCol.strColName.GetBuffer(0), stCol.strColName.GetBuffer(0), stCol.strRefTableName.GetBuffer(0), stCol.strRefTableCol.GetBuffer(0)); vtSql.push_back(strSql); } //删除外键约束 else if (0 == stCol.nIsForeignKey) { strSql.Empty(); strSql.Format(_T("alter table %s drop constraint FK_%s;"), strTable.GetBuffer(0), stCol.strColName.GetBuffer(0)); vtSql.push_back(strSql); } return true; } bool CUpdateDataBase::ModifyDBTable(STTableInfo stTable) { _CommandPtr pCmdUpd = NULL; pCmdUpd.CreateInstance(_uuidof(Command)); pCmdUpd->ActiveConnection = m_pConnection; try { m_pConnection->BeginTrans(); for (int i = 0; i < stTable.vtColInfo.size(); i++) { if (1 == stTable.vtColInfo[i].nModifyType) { std::vector vtAddColSql; vtAddColSql.clear(); if (AddTableCol(stTable.strTableName, stTable.vtColInfo[i], vtAddColSql)) { for (int j = 0; j < vtAddColSql.size(); j++) { pCmdUpd->CommandText = vtAddColSql[j].AllocSysString(); pCmdUpd->Execute(NULL, NULL, adCmdText); } } } else if (2 == stTable.vtColInfo[i].nModifyType) { CString strDelSql = _T(""); strDelSql.Format(_T("alter table %s drop %s;"),stTable.strTableName.GetBuffer(0), stTable.vtColInfo[i].strColName.GetBuffer(0)); pCmdUpd->CommandText = strDelSql.AllocSysString(); pCmdUpd->Execute(NULL, NULL, adCmdText); } else if (3 == stTable.vtColInfo[i].nModifyType) { std::vector vtModifySql; vtModifySql.clear(); if (ModifyTableCol(stTable.strTableName, stTable.vtColInfo[i], vtModifySql)) { for (int j = 0; j < vtModifySql.size(); j++) { pCmdUpd->CommandText = vtModifySql[j].AllocSysString(); pCmdUpd->Execute(NULL, NULL, adCmdText); } } } } m_pConnection->CommitTrans(); return true; } catch (_com_error e) { m_pConnection->RollbackTrans(); AfxMessageBox((LPCTSTR)e.Description()); CString strLogInfo = _T(""); strLogInfo.Format(_T("[%d] ModifyDBTable table %s failed, error_msg = %s"), __LINE__, stTable.strTableName.GetBuffer(0), (LPCTSTR)e.Description()); PrintLog(strLogInfo); return false; } } int CUpdateDataBase::UpdateDBInfo() { CString strTmp = _T(""); if (!ParserUpdateDBXml()) { if (LANG_ZHCN == g_iUILanguage) AfxMessageBox(_T("获取数据库更新信息错误")); else MessageBoxEx(NULL, _T("Get Database update information error"), STRING_MESSAGEBOXEX_TITLE, MB_OK, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)); return enResFail; } if (0 == m_vtUpdateDBInfo.size()) { strTmp.Format(_T("[%d] there is no change database record")); PrintLog(strTmp); return enResNoUpdate; } for (int i = 0; i < m_vtUpdateDBInfo.size(); i++) { if (1 == m_vtUpdateDBInfo[i].nModifyType) { if (!AddDBTable(m_vtUpdateDBInfo[i])) { return enResFail; } } else if (2 == m_vtUpdateDBInfo[i].nModifyType) { if (!DeleteDBTable(m_vtUpdateDBInfo[i])) { return enResFail; } } else if (3 == m_vtUpdateDBInfo[i].nModifyType) { if (!ModifyDBTable(m_vtUpdateDBInfo[i])) { return enResFail; } } } return (true == WriteVersionToDB()) ? enResSuccess : enResFail; }