// THvacCfgLayStd.cpp #include "..\stdAfx.h" #include "EarThwormDef.h" #include "THvacCfgLayStd.h" // 风管系统增加图层标准选择功能 // 避免因接口改动造成影响范围过大,故定义为全局变量。 // 新版数据库(HvacConfig.mdb)中的THVacCfg表结构变更, // 原直接使用_T("WPipeCfg")宏的地方,全部更改为 // g_sTHvacLayStd.GetCurStdTab()方式,可兼容旧版数据库 CTHvacCfgLayStd g_sTHvacLayStd; CTHvacCfgLayStd::CTHvacCfgLayStd() { m_sCurStdName = _T("默认"); m_bInited = FALSE; m_pAdoSer = NULL; } CTHvacCfgLayStd::~CTHvacCfgLayStd() { Release(); } // 取得数据库中最大的索引 int CTHvacCfgLayStd::MakeNewStdIndex() const { // 生成一个随机数 srand((unsigned int)time(NULL)); int nIndex = rand() % 200; // 从数据库中取得最大的索引 + 1 CUIISQLiteServer* pAdoSer = m_pAdoSer; if(NULL != pAdoSer) { CString sSQL, sValue; sSQL.Format(_T("SELECT MAX([STDINDEX]) FROM %s"), _T("WPipeCfg")); if(pAdoSer->GetSelData(sSQL, sValue)) { nIndex = _ttoi(sValue) + 1; } } return nIndex; } // 根据索引生成一个新的表名 inline CString CTHvacCfgLayStd::MakeTabName(int nIndex) const { CString sName; sName.Format(_T("HvacCfg_Std%d"), nIndex); return sName; } // 添加一个标准到映射中 void CTHvacCfgLayStd::AddStdToMap(LPCTSTR pszKey, LPSDUCTLAYSTD pNewLayStd) { if(NULL == pszKey || NULL == pNewLayStd) return; LPSDUCTLAYSTD pLayStd = NULL; if(!m_mapLayStds.Lookup(pszKey, (void*&)pLayStd)) { pLayStd = new SDUCTLAYSTD; m_mapLayStds.SetAt(pszKey, pLayStd); } pLayStd->sLayStdName = pNewLayStd->sLayStdName; pLayStd->sTableName = pNewLayStd->sTableName; pLayStd->bIsCurr = pNewLayStd->bIsCurr; pLayStd->nIndex = pNewLayStd->nIndex; } // 释放内存 void CTHvacCfgLayStd::Release() { POSITION pos = m_mapLayStds.GetStartPosition(); CString sKey; LPSDUCTLAYSTD pLayStd = NULL; while(NULL != pos) { m_mapLayStds.GetNextAssoc(pos, sKey, (void*&)pLayStd); if(NULL != pLayStd) { DELETE_PTR(pLayStd); pLayStd = NULL; } } m_mapLayStds.RemoveAll(); m_bInited = FALSE; } // 判断图层标准是否有效(用以兼容以前版本的数据库) BOOL CTHvacCfgLayStd::IsLayStdEnable(CUIISQLiteServer* pDB) { CUIISQLiteServer* pAdoSer = pDB; if(NULL == pAdoSer) pAdoSer = g_sTHvacLayStd.m_pAdoSer; if(NULL == pAdoSer) return FALSE; // 取得THvacCfg的表头 CUIIValueTable table; CString sSQL(_T("SELECT * FROM WPipeCfg")); pAdoSer->GetSelData(sSQL, table); CStringArray arFieldName; table.GetLableRecord(arFieldName); // 旧版数据库中的THvacCfg表为风管系统表 共9个字段。 // 新版数据库里增加图层标准,THvacCfg为图层标准管理表,共4个字段 // 原有的风管系统表更名为 THvacCfg_Std* if(4 == arFieldName.GetSize()) return TRUE; return FALSE; } // 初始化 void CTHvacCfgLayStd::Init() { // 已经初始化了 不需要再重新初始化 if(m_bInited) return; Release(); if(!IsLayStdEnable()) return; // 取得数据库指针 CUIISQLiteServer* pAdoSer = m_pAdoSer; if(NULL == pAdoSer) return; // 将当前表置为空 m_sCurStdName.Empty(); // 取得所有的数据 CUIIValueTable table; CString sSQL; sSQL.Format(_T("SELECT * FROM %s"), _T("WPipeCfg")); int nSize = pAdoSer->GetSelData(sSQL, table); CStringArray arFields; SDUCTLAYSTD layStd; for(int i = 0; i < nSize; i++) { table.GetValueRecord(i, arFields); if(4 == arFields.GetSize()) { layStd.sLayStdName = arFields[0]; layStd.sTableName = arFields[1]; layStd.bIsCurr = _ttoi(arFields[2]); layStd.nIndex = _ttoi(arFields[3]); // 取得当前标准 if(layStd.bIsCurr && m_sCurStdName.IsEmpty()) { m_sCurStdName = layStd.sLayStdName; } // 添加到映射 AddStdToMap(layStd.sLayStdName, &layStd); } } // 设置初始化标志 m_bInited = TRUE; } // 重新初始化 void CTHvacCfgLayStd::Reinit() { m_bInited = FALSE; Init(); } // 取得当前图层标准名 LPCTSTR CTHvacCfgLayStd::GetCurStdName() { // 当前标准为空时 从映射中查找 if(m_sCurStdName.IsEmpty()) { POSITION pos = m_mapLayStds.GetStartPosition(); LPSDUCTLAYSTD pLayStd = NULL; CString sFirstName; while(NULL != pos) { m_mapLayStds.GetNextAssoc(pos, m_sCurStdName, (void*&)pLayStd); if(NULL != pLayStd) { // 记录映射中的第一图层标准 if(sFirstName.IsEmpty()) sFirstName = pLayStd->sLayStdName; // 取得当前标准 if(pLayStd->bIsCurr) { m_sCurStdName = pLayStd->sLayStdName; break; } } } // 查找失败时 以映射中的第一个标准为默认标准 if(m_sCurStdName.IsEmpty() && !sFirstName.IsEmpty()) m_sCurStdName = sFirstName; else m_sCurStdName = _T("默认"); } return m_sCurStdName; } // 取得所有的图层标准名 int CTHvacCfgLayStd::GetAllStdNames(CStringArray& arStdNames) const { if(!IsLayStdEnable()) return 0; POSITION pos = m_mapLayStds.GetStartPosition(); LPSDUCTLAYSTD pLayStd = NULL; CString sStdName; while(NULL != pos) { m_mapLayStds.GetNextAssoc(pos, sStdName, (void*&)pLayStd); if(NULL != pLayStd) { arStdNames.Add(pLayStd->sLayStdName); } } return (int)arStdNames.GetSize(); } // 取得当前图层标准的数据表名 LPCTSTR CTHvacCfgLayStd::GetCurStdTab() const { LPSDUCTLAYSTD pLayStd = NULL; if(m_mapLayStds.Lookup(m_sCurStdName, (void*&)pLayStd)) { return pLayStd->sTableName; } return _T("WPipeCfg"); } // 取得图层标准对应的数据表名 LPCTSTR CTHvacCfgLayStd::GetStdTabName(LPCTSTR pszStdName) const { if(NULL == pszStdName) return _T(""); LPSDUCTLAYSTD pLayStd = NULL; if(m_mapLayStds.Lookup(pszStdName, (void*&)pLayStd)) { return pLayStd->sTableName; } return _T(""); } // 设置新的当前图层标准 BOOL CTHvacCfgLayStd::SetCurStd(LPCTSTR pszStdName) { if(NULL == pszStdName || !IsLayStdEnable()) return FALSE; // 设置数据映射中的当前标准 LPSDUCTLAYSTD pStdOld = NULL; LPSDUCTLAYSTD pStdNew = NULL; m_mapLayStds.Lookup(m_sCurStdName, (void*&)pStdOld); // 当前标准 m_mapLayStds.Lookup(pszStdName, (void*&)pStdNew); // 新的标准 if(NULL == pStdOld || NULL == pStdNew) return FALSE; pStdOld->bIsCurr = FALSE; pStdNew->bIsCurr = TRUE; // 修改数据库中的当前标准 CUIISQLiteServer* pAdoSer = m_pAdoSer; if(NULL == pAdoSer) return FALSE; // 将当前标准的标志设为FALSE CString sSQL; sSQL.Format(_T("UPDATE [%s] SET [CURRSTD] = 0 WHERE [STDNAME] = '%s'"), _T("WPipeCfg"), m_sCurStdName); pAdoSer->ExecuteSQL(sSQL); // 将新的标准的标志设为TRUE sSQL.Format(_T("UPDATE [%s] SET [CURRSTD] = 1 WHERE [STDNAME] = '%s'"), _T("WPipeCfg"), pszStdName); pAdoSer->ExecuteSQL(sSQL); // 设置当前标准名称 m_sCurStdName = pszStdName; return TRUE; } // 判断是否当前标准 BOOL CTHvacCfgLayStd::IsCurStd(LPCTSTR pszStdName) const { if(NULL == pszStdName) return FALSE; return 0 == m_sCurStdName.CompareNoCase(pszStdName); } // 判断标准是否存在 BOOL CTHvacCfgLayStd::IsStdExist(LPCTSTR pszStdName) const { if(NULL == pszStdName) return FALSE; LPSDUCTLAYSTD pLayStd = NULL; if(m_mapLayStds.Lookup(pszStdName, (void*&)pLayStd)) { return TRUE; } return FALSE; } // 添加一个新标准 BOOL CTHvacCfgLayStd::AddNewStandard(LPCTSTR pszStdName) { if(NULL == pszStdName || !IsLayStdEnable()) return FALSE; if(IsStdExist(pszStdName)) return FALSE; // 取得数据库指针 CUIISQLiteServer* pAdoSer = m_pAdoSer; if(NULL == pAdoSer) return FALSE; // 生成新的图层标准参数 SDUCTLAYSTD layStd; layStd.nIndex = MakeNewStdIndex(); layStd.sLayStdName = pszStdName; layStd.sTableName = MakeTabName(layStd.nIndex); layStd.bIsCurr = FALSE; // 创建新数据表并拷贝当前标准的数据 CString sSQL; sSQL.Format(_T("SELECT * INTO [%s] FROM [%s]"), layStd.sTableName, GetCurStdTab()); if(!pAdoSer->ExecuteSQL(sSQL)) return FALSE; // 插入图层标准到THVacCfg表中 sSQL.Format(_T("INSERT INTO [%s] ([STDNAME], [TABLENAME], [CURRSTD], [STDINDEX])\ VALUES ('%s', '%s', %d, %d)"), _T("WPipeCfg"), layStd.sLayStdName, layStd.sTableName, layStd.bIsCurr, layStd.nIndex); if(!pAdoSer->ExecuteSQL(sSQL)) return FALSE; // 将新的图层标准加入到映射 AddStdToMap(pszStdName, &layStd); return TRUE; } // 从另一个数据库中添加新标准 int CTHvacCfgLayStd::AddNewStandardFormDB(CUIISQLiteServer* pDBSrc, LPCTSTR pszStdName) { if(NULL == pDBSrc || !IsLayStdEnable()) return 0; // 取得数据库指针 CUIISQLiteServer* pAdoSer = m_pAdoSer; if(NULL == pAdoSer) return 0; int nCount = 0; if(IsLayStdEnable(pDBSrc)) // 新版数据库 { // 取得源数据库中的所有标准名称和表名 CUIIValueTable table; CString sSQL, sName; sSQL.Format(_T("SELECT * FROM %s"), _T("WPipeCfg")); int nSize = pDBSrc->GetSelData(sSQL, table); // 遍历进行表和数据的拷贝 CStringArray arFields; SDUCTLAYSTD layStd; for(int i = 0; i < nSize; i++) { table.GetValueRecord(i, arFields); if(4 == arFields.GetSize()) { // 生成标准名称 sName = arFields.GetAt(0); while(IsStdExist(sName)) sName += _T("2"); // 生成新的图层标准参数 layStd.nIndex = MakeNewStdIndex(); layStd.sLayStdName = sName; layStd.sTableName = MakeTabName(layStd.nIndex); layStd.bIsCurr = FALSE; // 创建新数据表并拷贝当前标准的数据 sSQL.Format(_T("SELECT * INTO [%s] FROM [%s] limit 0,1"), layStd.sTableName, GetCurStdTab()); if(!pAdoSer->ExecuteSQL(sSQL)) continue; // 从另一个数据库中拷贝数据 if(!CopyTable(pDBSrc, arFields.GetAt(1), pAdoSer, layStd.sTableName)) continue; // 插入图层标准到THVacCfg表中 sSQL.Format(_T("INSERT INTO [%s] ([STDNAME], [TABLENAME], [CURRSTD], [STDINDEX])\ VALUES ('%s', '%s', %d, %d)"), _T("WPipeCfg"), layStd.sLayStdName, layStd.sTableName, layStd.bIsCurr, layStd.nIndex); if(!pAdoSer->ExecuteSQL(sSQL)) continue; // 将新的图层标准加入到映射 AddStdToMap(sName, &layStd); nCount++; } } } else // 旧版数据库 直接拷贝_T("WPipeCfg")表即可 { if(0 == _tcslen(pszStdName)) return 0; if(IsStdExist(pszStdName)) return 0; // 生成新的图层标准参数 SDUCTLAYSTD layStd; layStd.nIndex = MakeNewStdIndex(); layStd.sLayStdName = pszStdName; layStd.sTableName = MakeTabName(layStd.nIndex); layStd.bIsCurr = FALSE; // 创建新数据表并拷贝当前标准的数据 CString sSQL; sSQL.Format(_T("SELECT * INTO [%s] FROM [%s] limit 0,1"), layStd.sTableName, GetCurStdTab()); if(!pAdoSer->ExecuteSQL(sSQL)) return 0; // 从另一个数据库中拷贝数据 if(!CopyTable(pDBSrc, _T("WPipeCfg"), pAdoSer, layStd.sTableName)) return 0; // 插入图层标准到THVacCfg表中 sSQL.Format(_T("INSERT INTO [%s] ([STDNAME], [TABLENAME], [CURRSTD], [STDINDEX])\ VALUES ('%s', '%s', %d, %d)"), _T("WPipeCfg"), layStd.sLayStdName, layStd.sTableName, layStd.bIsCurr, layStd.nIndex); if(!pAdoSer->ExecuteSQL(sSQL)) return 0; // 将新的图层标准加入到映射 AddStdToMap(pszStdName, &layStd); nCount = 1; } return nCount; } // 删除一个标准 BOOL CTHvacCfgLayStd::RemoveStandard(LPCTSTR pszStdName) { if(NULL == pszStdName) return FALSE; // 不允许删除当前标准 if(IsCurStd(pszStdName)) return FALSE; // 取得表名 CString sTableName = GetStdTabName(pszStdName); if(sTableName.IsEmpty()) return FALSE; // 取得数据库指针 CUIISQLiteServer* pAdoSer = m_pAdoSer; if(NULL == pAdoSer) return FALSE; // 删除表 CString sSQL; sSQL.Format(_T("DELETE FROM [%s] WHERE [STDNAME] = '%s'"), _T("WPipeCfg"), pszStdName); if(!pAdoSer->ExecuteSQL(sSQL)) return FALSE; sSQL.Format(_T("DROP TABLE [%s]"), sTableName); pAdoSer->ExecuteSQL(sSQL); // 删除映射中的数据 LPSDUCTLAYSTD lpLayStd = NULL; if(m_mapLayStds.Lookup(pszStdName, (void*&)lpLayStd)) { if(NULL != lpLayStd) DELETE_PTR(lpLayStd); m_mapLayStds.RemoveKey(pszStdName); } return TRUE; } // 拷贝数据表 BOOL CTHvacCfgLayStd::CopyTable(CUIISQLiteServer* pSrcDB, LPCTSTR pszSrcTab, CUIISQLiteServer* pDstDB, LPCTSTR pszDstTab) { if(NULL == pSrcDB || NULL == pDstDB) return FALSE; if(NULL == pszSrcTab || NULL == pszDstTab) return FALSE; CString sSQL; // 删除目标表中的所有数据 sSQL.Format(_T("DELETE FROM %s"), pszDstTab); if(!pDstDB->ExecuteSQL(sSQL)) return FALSE; // 取得源表中的所有数据 CUIIValueTable table; sSQL.Format(_T("SELECT * FROM %s"), pszSrcTab); int nSize = pSrcDB->GetSelData(sSQL, table); // 取得表头 CStringArray arTitle; table.GetLableRecord(arTitle); int nTitleCount = arTitle.GetSize(); // 格式化SQL字段 CString sSQLFmt; sSQLFmt.Format(_T("INSERT INTO [%s] ("), pszDstTab); CString sTemp; int i = 0; for(i = 0; i < nTitleCount; i++) { sTemp.Format(_T("[%s], "), arTitle[i]); sSQLFmt += sTemp; } sSQLFmt.TrimRight(_T(", ")); sSQLFmt += _T(") VALUES ("); // 遍历插入数据 CStringArray arFields; for(i = 0; i < nSize; i++) { table.GetValueRecord(i , arFields); if(nTitleCount == arFields.GetSize()) { // 格式化SQL值 sSQL = sSQLFmt; for(int j = 0; j < nTitleCount; j++) { sTemp.Format(_T("\'%s\', "), arFields[j]); sSQL += sTemp; } sSQL.TrimRight(_T(", ")); sSQL += _T(")"); // 插入数据 pDstDB->ExecuteSQL(sSQL); } } return TRUE; }