Files
geomative/GeomativeStudio/cpp/Operator/UpdateDataBase.cpp
T
coco df489d5640 a
2026-07-03 16:05:30 +08:00

874 lines
24 KiB
C++

// 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<int> vtIndexCol;
std::vector<int> 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<CString> 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<CString>& 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<CString>& 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<CString> 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<CString> 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;
}