874 lines
24 KiB
C++
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;
|
|
}
|