#include "db_sysinfo_api/CDbSysInfo.h" #include "boost/thread.hpp" #include "pub_sysinfo_api/SysInfoApi.h" #include "rdb_api/RdbDefine.h" #include "common/Common.h" #include "pub_logger_api/logger.h" #include "boost/typeof/typeof.hpp" #include "boost/algorithm/string/split.hpp" #include "boost/algorithm/string/classification.hpp" #include "boost/lexical_cast.hpp" #include "boost/format.hpp" #include "boost/asio/ip/host_name.hpp" #include "boost/algorithm/string/predicate.hpp" //< 屏蔽xml_parser编译告警 #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-copy" #endif #include "boost/property_tree/xml_parser.hpp" #ifdef __GNUC__ #pragma GCC diagnostic pop #endif #include "pub_utility_api/FileUtil.h" #include #include using namespace std; using namespace iot_public; using namespace iot_dbms; iot_public::CSysInfoInterfacePtr CDbSysInfo::m_ptrSysInfo = NULL; CDbSysInfo::CDbSysInfo() { } bool CDbSysInfo::initialize() { if ( false == createSysInfoInstance( m_ptrSysInfo ) ) { LOGERROR( "initialize,createSysInfoInstance Failed!" ); return false; } return true; } void CDbSysInfo::release() { m_ptrSysInfo.reset(); m_ptrSysInfo = NULL; } bool CDbSysInfo::reloadAllData() { if ( m_ptrSysInfo == NULL ) { LOGERROR("在初始化之前调用了重新加载数据,逻辑错误"); return false; } return m_ptrSysInfo->reloadAllData(); } static boost::mutex g_mutexMapName2ID; int CDbSysInfo::getAppIdByAppName( const std::string appName ) { static map mapName2ID; boost::mutex::scoped_lock lock( g_mutexMapName2ID ); if ( mapName2ID.count( appName ) == 1 ) { return mapName2ID[appName]; } if ( m_ptrSysInfo == NULL ) { if ( false == createSysInfoInstance( m_ptrSysInfo ) ) { LOGERROR( "createSysInfoInstance Failed!" ); return -1; } } SAppInfo stAppInfo; int nRet = m_ptrSysInfo->getAppInfoByName( appName, stAppInfo ); if ( iotFailed == nRet ) //ret value not right { LOGERROR( "无法获取对应应用信息:%s", appName.c_str() ); return RDBERR_BASE; } mapName2ID[appName] = stAppInfo.nId; return stAppInfo.nId; } static boost::mutex g_mutexMapTableName2ID; int CDbSysInfo::getAppIdByTableName( const std::string& strAppName, const std::string& strTableName ) { static map > mapTableName2ID; boost::mutex::scoped_lock lock( g_mutexMapTableName2ID ); if ( mapTableName2ID.count( strAppName ) == 1 ) { if ( mapTableName2ID[strAppName].count(strTableName) == 1 ) return mapTableName2ID[strAppName][strTableName]; } if ( m_ptrSysInfo == NULL ) { if ( false == createSysInfoInstance( m_ptrSysInfo ) ) { LOGERROR( "createSysInfoInstance Failed!" ); return CN_InvalidAppId; } } // 加载内存库表结构,表名做主键 static std::map mapTableModeInfo; if ( mapTableModeInfo.size() == 0 ) { // 读取平台配置文件 try { boost::property_tree::ptree pt; std::string strFileName = boost::str(boost::format("%s/../../platform/common/database/initscript/iscs6000_table_struct.xml") % iot_public::CFileUtil::getCurModuleDir().c_str()); boost::property_tree::xml_parser::read_xml(strFileName, pt); BOOST_AUTO(table, pt.get_child("DatabaseStruct")); for (BOOST_AUTO(itTable, table.begin()); itTable!=table.end(); itTable++) { std::string sUseType = itTable->second.get(".use_type"); if ("Table" != itTable->first || !boost::contains(sUseType,"rdb")) continue; BOOST_AUTO(rdb, itTable->second.get_child("Rdb")); if ( rdb.size() <= 0 ) continue; BOOST_AUTO(itRdb, rdb.begin()); STableModeInfo stTableInfo; stTableInfo.strName = itTable->second.get(".name"); stTableInfo.nMaxRecordNum = itRdb->second.get("max_record_num"); stTableInfo.strParamTable = sUseType=="rdb" ? "" : stTableInfo.strName; stTableInfo.strDataTable = ""; stTableInfo.nSubsystemFlag = itRdb->second.get("subsystem_flag"); stTableInfo.nDownloadType = 1; stTableInfo.bSelectByLocation = itRdb->second.get("select_by_location")=="yes" ? true : false; stTableInfo.bSelectBySubsystem = itRdb->second.get("select_by_subsystem")=="yes" ? true : false; mapTableModeInfo[stTableInfo.strName] = stTableInfo; } } catch (std::exception &e) { LOGERROR("Loading iscs6000_table_struct.xml, Err: %s", e.what()); return CN_InvalidAppId; } // 读取产品配置文件 try { boost::property_tree::ptree pt; std::string strFileName = boost::str(boost::format("%s/../../product/common/database/initscript/iscs6000_table_struct.xml") % iot_public::CFileUtil::getCurModuleDir().c_str()); boost::property_tree::xml_parser::read_xml(strFileName, pt); BOOST_AUTO(table, pt.get_child("DatabaseStruct")); for (BOOST_AUTO(itTable, table.begin()); itTable!=table.end(); itTable++) { std::string sUseType = itTable->second.get(".use_type"); if ("Table" != itTable->first || !boost::contains(sUseType,"rdb") ) continue; BOOST_AUTO(rdb, itTable->second.get_child("Rdb")); if ( rdb.size() <= 0 ) continue; BOOST_AUTO(itRdb, rdb.begin()); STableModeInfo stTableInfo; stTableInfo.strName = itTable->second.get(".name"); stTableInfo.nMaxRecordNum = itRdb->second.get("max_record_num"); stTableInfo.strParamTable = sUseType=="rdb" ? "" : stTableInfo.strName; stTableInfo.strDataTable = ""; stTableInfo.nSubsystemFlag = itRdb->second.get("subsystem_flag"); stTableInfo.nDownloadType = 1; stTableInfo.bSelectByLocation = itRdb->second.get("select_by_location")=="yes" ? true : false; stTableInfo.bSelectBySubsystem = itRdb->second.get("select_by_subsystem")=="yes" ? true : false; mapTableModeInfo[stTableInfo.strName] = stTableInfo; } } catch (std::exception &e) { LOGINFO("Loading iscs6000_table_struct.xml, Err: %s", e.what()); } } // 根据app名称查找app信息 SAppInfo stAppInfo; if (iotSuccess != m_ptrSysInfo->getAppInfoByName(strAppName, stAppInfo)) { LOGERROR("getAppIdByTableName(): 未找到该应用 strAppName == %s", strAppName.c_str()); return CN_InvalidAppId; } // 查找内存表信息 BOOST_AUTO(itMap, mapTableModeInfo.find(strTableName)); if (mapTableModeInfo.end() == itMap) { LOGERROR("getAppIdByTableName(): 未找到该表 strTableName == %s", strTableName.c_str()); return CN_InvalidAppId; } int nRealAppId = CN_AppId_BASE; const STableModeInfo &stTableInfo = itMap->second; for (std::vector::const_iterator pIter = stAppInfo.vecSubsystemId.begin(); pIter != stAppInfo.vecSubsystemId.end(); ++pIter) { std::bitset<32> setFlag (stTableInfo.nSubsystemFlag); if (setFlag[*pIter - 1]) { nRealAppId = stAppInfo.nId; break; } } mapTableName2ID[strAppName][strTableName] = nRealAppId; return nRealAppId; } int CDbSysInfo::getAppIdBySubsystemId( int nSubsystemId ) { if ( m_ptrSysInfo == NULL ) { if ( false == createSysInfoInstance( m_ptrSysInfo ) ) { LOGERROR( "createSysInfoInstance Failed!" ); return -1; } } SAppInfo objInfo; if ( m_ptrSysInfo->getAppInfoBySubsystemId( nSubsystemId, objInfo ) != 0 ) { return -1; } else { return objInfo.nId; } } bool CDbSysInfo::getAppIdBySubsystemFlag( uint32 unSubsystemFlag, std::set& setAppId ) { if ( m_ptrSysInfo == NULL ) { if ( false == createSysInfoInstance( m_ptrSysInfo ) ) { LOGERROR( "createSysInfoInstance Failed!" ); return false; } } setAppId.clear(); for ( int nBitIndex = 0; nBitIndex < 32; ++nBitIndex ) { if ( ( uint32( 1 ) << nBitIndex & unSubsystemFlag ) != 0 ) { SAppInfo objInfo; if ( m_ptrSysInfo->getAppInfoBySubsystemId( nBitIndex + 1, objInfo ) != 0 ) { continue; } else { //setAppId.insert(nBitIndex+1); setAppId.insert( objInfo.nId ); } } } return true; } static boost::mutex g_mutexSubsystemIdToTableName; bool CDbSysInfo::getAllRdbTableNameBySubsystemId( const int nSubsystemId, std::vector& vecTableName ) { boost::mutex::scoped_lock lock( g_mutexSubsystemIdToTableName ); static std::map mapTableName;// tableName->subsystemFlag if ( mapTableName.size() == 0 ) { // 加载平台配置文件 try { boost::property_tree::ptree pt; std::string strFileName = boost::str(boost::format("%s/../../platform/common/database/initscript/iscs6000_table_struct.xml") % iot_public::CFileUtil::getCurModuleDir().c_str()); boost::property_tree::xml_parser::read_xml(strFileName, pt); BOOST_AUTO(table, pt.get_child("DatabaseStruct")); for (BOOST_AUTO(itTable, table.begin()); itTable!=table.end(); itTable++) { std::string strUseType = itTable->second.get(".use_type"); if ("Table" != itTable->first || !boost::contains(strUseType,"rdb") ) continue; BOOST_AUTO(rdb, itTable->second.get_child("")); for (BOOST_AUTO(itRdb, rdb.begin()); itRdb!=rdb.end(); itRdb++) { if ("Rdb" != itRdb->first ) continue; mapTableName[itTable->second.get(".name")] = itRdb->second.get(".subsystem_flag"); } } } catch (std::exception &e) { LOGERROR("Loading iscs6000_table_struct.xml, Err: %s", e.what()); return false; } // 加载产品配置文件 try { boost::property_tree::ptree pt; std::string strFileName = boost::str(boost::format("%s/../../product/common/database/initscript/iscs6000_table_struct.xml") % iot_public::CFileUtil::getCurModuleDir().c_str()); boost::property_tree::xml_parser::read_xml(strFileName, pt); BOOST_AUTO(table, pt.get_child("DatabaseStruct")); for (BOOST_AUTO(itTable, table.begin()); itTable!=table.end(); itTable++) { std::string strUseType = itTable->second.get(".use_type"); if ("Table" != itTable->first || !boost::contains(strUseType,"rdb") ) continue; BOOST_AUTO(rdb, itTable->second.get_child("")); for (BOOST_AUTO(itRdb, rdb.begin()); itRdb!=rdb.end(); itRdb++) { if ("Rdb" != itRdb->first ) continue; mapTableName[itTable->second.get(".name")] = itRdb->second.get(".subsystem_flag"); } } } catch (std::exception &e) { LOGINFO("Loading iscs6000_table_struct.xml, Err: %s", e.what()); } } // 查找满足要求的表名 for ( BOOST_AUTO(itMap, mapTableName.begin()); itMap!=mapTableName.end(); itMap++ ) { if ( (itMap->second>>(nSubsystemId-1))%2 == 1 ) vecTableName.push_back( itMap->first ); } return true; } static boost::mutex g_mutexTableNameToRdbColumnName; bool CDbSysInfo::getAllRdbColumnNameByTableName( const std::string sTableName, std::vector& verColumnName ) { boost::mutex::scoped_lock lock( g_mutexTableNameToRdbColumnName ); static std::map > mapTableName;// tableName->columnVector if ( mapTableName.size() == 0 ) { // 加载平台配置文件 try { boost::property_tree::ptree pt; std::string strFileName = boost::str(boost::format("%s/../../platform/common/database/initscript/iscs6000_table_struct.xml") % iot_public::CFileUtil::getCurModuleDir().c_str()); boost::property_tree::xml_parser::read_xml(strFileName, pt); BOOST_AUTO(table, pt.get_child("DatabaseStruct")); for (BOOST_AUTO(itTable, table.begin()); itTable!=table.end(); itTable++) { std::string strUseType = itTable->second.get(".use_type"); if ("Table" != itTable->first || !boost::contains(strUseType,"rdb") ) continue; std::vector tmpVecColumn; BOOST_AUTO(column, itTable->second.get_child("")); for ( BOOST_AUTO(itColumn, column.begin()); itColumn!=column.end(); itColumn++ ) { if ( itColumn->first != "Column" ) continue; if ( itColumn->second.get(".use_type") == "db" ) continue; SColumnModeInfo stColumnModeInfo; stColumnModeInfo.strName = itColumn->second.get(".name") ; stColumnModeInfo.strDesc = itColumn->second.get(".description") ; tmpVecColumn.push_back( stColumnModeInfo ); } mapTableName[itTable->second.get(".name")] = tmpVecColumn; } } catch (std::exception &e) { LOGERROR("Loading iscs6000_table_struct.xml, Err: %s", e.what()); return false; } // 加载产品配置文件 try { boost::property_tree::ptree pt; std::string strFileName = boost::str(boost::format("%s/../../product/common/database/initscript/iscs6000_table_struct.xml") % iot_public::CFileUtil::getCurModuleDir().c_str()); boost::property_tree::xml_parser::read_xml(strFileName, pt); BOOST_AUTO(table, pt.get_child("DatabaseStruct")); for (BOOST_AUTO(itTable, table.begin()); itTable!=table.end(); itTable++) { std::string strUseType = itTable->second.get(".use_type"); if ("Table" != itTable->first || !boost::contains(strUseType,"rdb") ) continue; std::vector tmpVecColumn; BOOST_AUTO(column, itTable->second.get_child("")); for ( BOOST_AUTO(itColumn, column.begin()); itColumn!=column.end(); itColumn++ ) { if ( itColumn->first != "Column" ) continue; if ( itColumn->second.get(".use_type") == "db" ) continue; SColumnModeInfo stColumnModeInfo; stColumnModeInfo.strName = itColumn->second.get(".name") ; stColumnModeInfo.strDesc = itColumn->second.get(".description") ; tmpVecColumn.push_back( stColumnModeInfo ); } mapTableName[itTable->second.get(".name")] = tmpVecColumn; } } catch (std::exception &e) { LOGINFO("Loading iscs6000_table_struct.xml, Err: %s", e.what()); } } // 查找满足要求的列名 std::string sDestTableName = sTableName; std::transform( sDestTableName.begin(), sDestTableName.end(), sDestTableName.begin(), ::tolower ); for ( BOOST_AUTO(itMap, mapTableName.begin()); itMap!=mapTableName.end(); itMap++ ) { std::string sTmpTableName = itMap->first; std::transform( sTmpTableName.begin(), sTmpTableName.end(), sTmpTableName.begin(), ::tolower ); if ( sDestTableName == sTmpTableName ) verColumnName = itMap->second; } return true; } static boost::mutex g_mutexMapTableNameInfo; bool CDbSysInfo::getTableModeByTableName( const std::string& strTableName ,STableModeInfo &stTableModelInfo) { boost::mutex::scoped_lock lock( g_mutexMapTableNameInfo ); // 加载内存库表结构,表名做主键 static std::map mapDbTableModeInfo; if ( mapDbTableModeInfo.size() == 0 ) { // 读取平台配置文件 try { boost::property_tree::ptree pt; std::string strFileName = boost::str(boost::format("%s/../../platform/common/database/initscript/iscs6000_table_struct.xml") % iot_public::CFileUtil::getCurModuleDir().c_str()); boost::property_tree::xml_parser::read_xml(strFileName, pt); BOOST_AUTO(table, pt.get_child("DatabaseStruct")); for (BOOST_AUTO(itTable, table.begin()); itTable!=table.end(); itTable++) { std::string sUseType = itTable->second.get(".use_type"); if ("Table" != itTable->first || sUseType == "rdb" || sUseType.empty()) continue; //过滤非关系库表 STableModeInfo stTableInfo; stTableInfo.strName = itTable->second.get(".name"); stTableInfo.strParamTable = sUseType=="rdb" ? "" : stTableInfo.strName; stTableInfo.strDataTable = ""; stTableInfo.nDownloadType = 1; //<< 获取实时表参数 //============================================================================================ if( sUseType == "db" ) { BOOST_AUTO(db, itTable->second.get_child("Db")); BOOST_AUTO(itdb, db.begin()); std::string sIsBackUp = itdb->second.get("is_backup"); //过滤不备份的数据表 if ( sIsBackUp == "no") continue; stTableInfo.nMaxRecordNum = 0; stTableInfo.nSubsystemFlag = 1; stTableInfo.bSelectByLocation = "no"; stTableInfo.bSelectBySubsystem = "no"; continue; //没有Rdb节点 } else { BOOST_AUTO(rdb, itTable->second.get_child("Rdb")); BOOST_AUTO(itRdb, rdb.begin()); stTableInfo.nMaxRecordNum = itRdb->second.get("max_record_num"); stTableInfo.nSubsystemFlag = itRdb->second.get("subsystem_flag"); stTableInfo.bSelectByLocation = itRdb->second.get("select_by_location")=="yes" ? true : false; stTableInfo.bSelectBySubsystem = itRdb->second.get("select_by_subsystem")=="yes" ? true : false; } mapDbTableModeInfo[stTableInfo.strName] = stTableInfo; } } catch (std::exception &e) { LOGERROR("Loading iscs6000_table_struct.xml, Err: %s",e.what()); return false; } // 读取产品配置文件 try { boost::property_tree::ptree pt; std::string strFileName = boost::str(boost::format("%s/../../product/common/database/initscript/iscs6000_table_struct.xml") % iot_public::CFileUtil::getCurModuleDir().c_str()); boost::property_tree::xml_parser::read_xml(strFileName, pt); BOOST_AUTO(table, pt.get_child("DatabaseStruct")); for (BOOST_AUTO(itTable, table.begin()); itTable!=table.end(); itTable++) { std::string sUseType = itTable->second.get(".use_type"); if ("Table" != itTable->first || sUseType == "rdb" || sUseType.empty()) continue; //过滤非关系库表 STableModeInfo stTableInfo; stTableInfo.strName = itTable->second.get(".name"); stTableInfo.strParamTable = sUseType=="rdb" ? "" : stTableInfo.strName; stTableInfo.strDataTable = ""; stTableInfo.nDownloadType = 1; //<< 获取实时表参数 //============================================================================================ if( sUseType == "db" ) { BOOST_AUTO(db, itTable->second.get_child("Db")); BOOST_AUTO(itdb, db.begin()); std::string sIsBackUp = itdb->second.get("is_backup");//过滤不备份的数据表 if ( sIsBackUp == "no") continue; stTableInfo.nMaxRecordNum = 0; stTableInfo.nSubsystemFlag = 1; stTableInfo.bSelectByLocation = "no"; stTableInfo.bSelectBySubsystem = "no"; continue; //没有Rdb节点 } else //db+rdb { BOOST_AUTO(rdb, itTable->second.get_child("Rdb")); BOOST_AUTO(itRdb, rdb.begin()); stTableInfo.nMaxRecordNum = itRdb->second.get("max_record_num"); stTableInfo.nSubsystemFlag = itRdb->second.get("subsystem_flag"); stTableInfo.bSelectByLocation = itRdb->second.get("select_by_location")=="yes" ? true : false; stTableInfo.bSelectBySubsystem = itRdb->second.get("select_by_subsystem")=="yes" ? true : false; } mapDbTableModeInfo[stTableInfo.strName] = stTableInfo; } } catch (std::exception &e) { LOGINFO("Loading iscs6000_table_struct.xml, Err: %s", e.what()); return false; } } // 查找内存表信息 BOOST_AUTO(itMap, mapDbTableModeInfo.find(strTableName)); if (mapDbTableModeInfo.end() == itMap) { LOGWARN("getTableModeByTableName(): 未找到该表 strTableName == %s", strTableName.c_str()); return false; } stTableModelInfo = itMap->second; return true; } static boost::mutex g_mutexGetSubsystemFlagByTableName; bool CDbSysInfo::getSubsystemFlagByTableName( const std::string sTableName, uint32& nSubsystemFlag ) { boost::mutex::scoped_lock lock( g_mutexGetSubsystemFlagByTableName ); static std::map mapTableName;// tableName->subsystemFlag if ( mapTableName.size() == 0 ) { // 加载平台配置文件 try { boost::property_tree::ptree pt; std::string strFileName = boost::str(boost::format("%s/../../platform/common/database/initscript/iscs6000_table_struct.xml") % iot_public::CFileUtil::getCurModuleDir().c_str()); boost::property_tree::xml_parser::read_xml(strFileName, pt); BOOST_AUTO(table, pt.get_child("DatabaseStruct")); for (BOOST_AUTO(itTable, table.begin()); itTable!=table.end(); itTable++) { std::string strUseType = itTable->second.get(".use_type"); if ("Table" != itTable->first || !boost::contains(strUseType,"rdb") ) continue; BOOST_AUTO(rdb, itTable->second.get_child("")); for (BOOST_AUTO(itRdb, rdb.begin()); itRdb!=rdb.end(); itRdb++) { if ("Rdb" != itRdb->first ) continue; mapTableName[itTable->second.get(".name")] = itRdb->second.get(".subsystem_flag"); } } } catch (std::exception &e) { LOGERROR("Loading iscs6000_table_struct.xml, Err: %s", e.what()); return false; } // 加载产品配置文件 try { boost::property_tree::ptree pt; std::string strFileName = boost::str(boost::format("%s/../../product/common/database/initscript/iscs6000_table_struct.xml") % iot_public::CFileUtil::getCurModuleDir().c_str()); boost::property_tree::xml_parser::read_xml(strFileName, pt); BOOST_AUTO(table, pt.get_child("DatabaseStruct")); for (BOOST_AUTO(itTable, table.begin()); itTable!=table.end(); itTable++) { std::string strUseType = itTable->second.get(".use_type"); if ("Table" != itTable->first || !boost::contains(strUseType,"rdb") ) continue; BOOST_AUTO(rdb, itTable->second.get_child("")); for (BOOST_AUTO(itRdb, rdb.begin()); itRdb!=rdb.end(); itRdb++) { if ("Rdb" != itRdb->first ) continue; mapTableName[itTable->second.get(".name")] = itRdb->second.get(".subsystem_flag"); } } } catch (std::exception &e) { LOGINFO("Loading iscs6000_table_struct.xml, Err: %s", e.what()); } } // 查找表名 std::map::iterator it = mapTableName.find(sTableName); if ( it != mapTableName.end() ) { nSubsystemFlag = it->second; return true; } return false; }