#include #include "projectModelManager.h" #include "dataBase.h" #include "logger.h" const QSet stringDataTypes = {"VARCHAR", "CHAR", "TEXT", "DATE", "TIME", "TIMESTAMP","JSONB","JSON"}; ProjectModelManager& ProjectModelManager::instance() { //采用静态局部变量的方式,静态局部变量的初始化是在第一次访问时,以后的调用不会多次初始化,并且生命周期和程序一致 static ProjectModelManager instance; return instance; } ProjectModelManager::ProjectModelManager(QObject *parent) : QObject(parent) { _bInitialised = false; } ProjectModelManager::~ProjectModelManager() { m_mapTotalData.clear(); } void ProjectModelManager::initialModel() { if(_bInitialised) return; QStringList lstModel = getModelList(); for(auto &sModel:lstModel) { MapProject mp; QMap mapProject = DataBase::GetInstance()->getProjectFromManager(sModel); QMap::Iterator iter; for(iter = mapProject.begin();iter != mapProject.end(); ++iter) { PropertyModel pm; pm.pBase = new QStandardItemModel(this); pm.pSelect = new QStandardItemModel(this); pm.mapProperty = addNewProject(sModel,iter.key(),pm); pm.nType = iter.value(); pm.formerMeta.sName = sModel; pm.formerProject.sName = iter.key(); pm.dataInfo = DataBase::GetInstance()->getProjectModelGroupInfo(iter.key()); pm.modelSetting = getModelSetting(sModel,iter.key()); mp.insert(iter.key(),pm); } m_mapTotalData.insert(sModel,mp); } _bInitialised = true; } void ProjectModelManager::generate(const QString& sMeta,const QString& sPro) { MapMeta::Iterator iter = m_mapTotalData.find(sMeta); //获取元模下的工程 if(iter != m_mapTotalData.end()) { MapProject mp = iter.value(); MapProject::Iterator ite = mp.find(sPro); //获取工程下的属性组 if(ite != mp.end()) { MapProperty mapProperty = ite.value().mapProperty; int createRes = 0; //动态表生成结果 for(MapProperty::Iterator it = mapProperty.begin();it != mapProperty.end();++it){ //每个属性组单独生成表 int nType = ite.value().nType; QStandardItemModel* pSelectModel = ite->pSelect; QStandardItemModel* pBaseModel = ite->pBase; QList lstSelected = getGroupSub(pSelectModel,it.key()); QList lstBase = getGroupSub(pBaseModel,it.key()); if(!lstSelected.isEmpty()) { bool isPub = it->isPublic; int res = createPropertyTable(sMeta,sPro,it.key(),lstSelected,lstBase,nType,isPub); switch (res){ case int(AlertInfo::success): LOG_INFO("DB", QString("create %1 dynamicTable success").arg(sPro)); break; case int(AlertInfo::fail): LOG_WARN("DB", QString("create %1 dynamicTable fail").arg(sPro)); break; case int(AlertInfo::exist): LOG_WARN("DB", QString("%1 dynamicTable exist").arg(sPro)); break; default: break; } createRes = createRes | res; } } if(!(createRes & int(AlertInfo::fail))) //结果不含失败就成功 { //QMessageBox::information(NULL, QString::fromWCharArray(L"提示"), QString::fromWCharArray(L"创建表成功")); emit modelChange(); } else //创建失败 { //QMessageBox::information(NULL, QString::fromWCharArray(L"提示"), QString::fromWCharArray(L"创建表失败")); } } } } MapProperty ProjectModelManager::addNewProject(const QString& sMeta,const QString& sProject,PropertyModel& model) { MapProperty mt; QStringList lstProperty = getGroupList(sMeta); //返回元模下的属性组名 QStringList lstProPublic = getPublicGroupList(); //返回公共属性组 //lstProperty< mapCheckState = DataBase::GetInstance()->getCheckStateFromManager(sProject); //获取选择状态 for(auto &property:lstProperty) { PropertyPage struProperty; struProperty.isPublic = false; if(mapCheckState.contains(property) && !model.formerMeta.bChanged) //生成的模型中勾选了该属性组且元模未改变过 { QJsonObject obj = mapCheckState[property]; QJsonArray nodesJsonArray = obj["checkState"].toArray(); for (QJsonValueRef nodeJson : nodesJsonArray) { QJsonObject node = nodeJson.toObject(); QString propertyName = node["name"].toString(); int nState = node["checked"].toInt(); QString dataType = node["type"].toString(); QString defaultValue = node["defaultValue"].toString(); QStandardItem* pItem = new QStandardItem(propertyName); setItemAttribute(propertyName,pItem); PropertyState sta; sta.dataType = dataType; if(nState) { QStandardItem* pGroup = nullptr; if(model.pSelect->findItems(property).isEmpty()) { pGroup = new QStandardItem(property); model.pSelect->appendRow(pGroup); //属性的组未存在,将组添加到model } else { pGroup = model.pSelect->findItems(property)[0]; } //QModelIndex index = findIndex(model.pSelect,propertyName); if(pGroup){ pGroup->appendRow(pItem); sta.checkState = true; struProperty.mCheckState.insert(propertyName,sta); } } else { QStandardItem* pGroup = nullptr; if(model.pBase->findItems(property).isEmpty()) { pGroup = new QStandardItem(property); model.pBase->appendRow(pGroup); //属性的组未存在,将组添加到model } else { pGroup = model.pBase->findItems(property)[0]; } if(pGroup){ pGroup->appendRow(pItem); sta.checkState = false; struProperty.mCheckState.insert(propertyName,sta); } } } } else //未勾选属性组或是新建或元模已改变 { QStandardItem* pGroup = nullptr; //新建的不包含属性组 pGroup = new QStandardItem(property); model.pBase->appendRow(pGroup); QStringList lstName = getAttributeList(sMeta,property); for(auto &name:lstName) { QStandardItem* pItem = new QStandardItem(name); setItemAttribute(name,pItem); pGroup->appendRow(pItem); QString dataType = getItemDataType(pItem); PropertyState sta; sta.dataType = dataType; sta.checkState = false; struProperty.mCheckState.insert(name,sta); //初始都是未选择状态 } } mt.insert(property,struProperty); } MapProperty pubMap; for(auto &pro:lstProPublic) //公共属性组 { PropertyPage struProperty; struProperty.isPublic = true; QStandardItem* pGroup = nullptr; pGroup = new QStandardItem(pro); //model.pSelect->appendRow(pGroup); //公共属性组默认都包含 model.pSelect->insertRow(0,pGroup); QStringList lstName = getPublicAttributeList(pro); for(auto &name:lstName) { QStandardItem* pItem = new QStandardItem(name); pItem->setData(QColor(60,140,180,180), Qt::BackgroundRole); setItemAttribute(name,pItem); pGroup->appendRow(pItem); QString dataType = getItemDataType(pItem); PropertyState sta; sta.dataType = dataType; sta.checkState = true; sta.editable = false; struProperty.mCheckState.insert(name,sta); //初始都已经选择 } pubMap.insert(pro,struProperty); } for (auto it = mt.begin(); it != mt.end(); ++it) { //将正常属性添到公共属性后 if(pubMap.contains(it.key())) continue; //公共属性组已有的不重复添加 pubMap.insert(it.key(), it.value()); } return pubMap; } QList ProjectModelManager::getGroupSub(QStandardItemModel* pModel,const QString& str) { QList lst; if(!pModel) return lst; QList items = pModel->findItems(str); if (!items.isEmpty()) { // 存在该文本的项 QStandardItem* item = items[0]; for (int row = 0; row < item->rowCount(); ++row) { // 默认获取第 0 列的子项 QStandardItem* child = item->child(row, 0); if (child) { lst.append(child); } } } return lst; } void ProjectModelManager::deleteData(const QString& sMeta,const QString& sProject) { delete m_mapTotalData[sMeta][sProject].pBase; //手动释放 delete m_mapTotalData[sMeta][sProject].pSelect; m_mapTotalData[sMeta].remove(sProject); } void ProjectModelManager::updateSetting(const QString& sMeta,const QString& sProject) { QJsonObject object; QJsonArray arr; QJsonArray arrUsed; QMap mapSvg = m_mapTotalData[sMeta][sProject].modelSetting.mapSvg; QMap mapUsedSvg = m_mapTotalData[sMeta][sProject].modelSetting.mapUsedSvg; for(auto iter = mapSvg.begin();iter != mapSvg.end();++iter) { QJsonObject obj; obj["name"] = iter.key(); obj["data"] = QString::fromUtf8(iter.value()); arr.push_back(obj); } object["picture"] = arr; for(auto iter = mapUsedSvg.begin();iter != mapUsedSvg.end();++iter) { QJsonObject obj; obj["name"] = iter.key(); obj["data"] = QString::fromUtf8(iter.value()); arrUsed.push_back(obj); } object["usingPicture"] = arrUsed; QJsonObject jsVal = DataBase::GetInstance()->getProjectSetting(sMeta,sProject); if(jsVal.empty()){ DataBase::GetInstance()->insertProjectSetting(sMeta,sProject,object); } else{ DataBase::GetInstance()->updateProjectSetting(sMeta,sProject,object); } } QStringList ProjectModelManager::getProjectModelLst(const QString& sMeta) { //return DataBase::GetInstance()->getProjectWithinBase(sMeta); QStringList lst; QMap mapPro = m_mapTotalData.value(sMeta); for(auto it = mapPro.begin();it != mapPro.end();++it) { lst.append(it.key()); } return lst; } QStringList ProjectModelManager::getModelList() const { QMap modelMap = DataBase::GetInstance()->ModelType(); QSet modelSet; for(auto &model:modelMap) { modelSet.insert(model.modelType); } return QStringList(modelSet.values()); } QStringList ProjectModelManager::getGroupList(const QString& sM) const { QMap modelType = DataBase::GetInstance()->ModelType(); QMap modelGroupMap = DataBase::GetInstance()->ModelGroup(); QMap groupMap = DataBase::GetInstance()->AttributeGroup(); int metaId = 0; for(auto &meta:modelType) { if(sM == meta.modelType) //查找元模对应的id { metaId = meta.id; break; } } QList lstGroupId; for(auto &group:modelGroupMap) //找到元模id对应的属性组id { if(group.modelTypeId == metaId) { lstGroupId.push_back(group.attributeGroupId); } } QStringList groupList; for(auto &id:lstGroupId) //从属性组中找到id对应的组名 { groupList.append(groupMap[id].groupType); } return groupList; } QStringList ProjectModelManager::getPublicGroupList() const { QMap modelAttPublic = DataBase::GetInstance()->ModelAttributePublic(); QMap groupMap = DataBase::GetInstance()->AttributeGroup(); QSet setGroup; for(auto &model:modelAttPublic) { setGroup.insert(model.attributeGroupId); } QStringList groupList; for(auto &id:setGroup) { groupList.append(groupMap[id].groupType); } return groupList; } QStringList ProjectModelManager::getAttributeList(const QString& sM,const QString& sG) const { QMap modelType = DataBase::GetInstance()->ModelType(); //QMap modelGroupMap = DataBase::GetInstance()->ModelGroup(); QMap groupMap = DataBase::GetInstance()->AttributeGroup(); QMap modelAttMap = DataBase::GetInstance()->ModelAttribute(); QMap attMap = DataBase::GetInstance()->Attribute(); int metaId = -1; for(auto &meta:modelType) { if(sM == meta.modelType) //查找元模对应的id { metaId = meta.id; break; } } int groupId = -1; for(auto &attGroup:groupMap) { if(attGroup.groupType == sG) //返回参数属性组名对应的id { groupId = attGroup.id; break; } } QStringList lst; for(auto &mt:modelAttMap) { if(mt.modelTypeId == metaId && mt.attributeGroupId == groupId) { if(attMap[mt.attributeId].isVisible == 2) //2为特殊属性,不加入选择 continue; lst.append(attMap[mt.attributeId].attribute); } } return lst; } QStringList ProjectModelManager::getPublicAttributeList(const QString& group) { QMap modelAttPublic = DataBase::GetInstance()->ModelAttributePublic(); QMap groupMap = DataBase::GetInstance()->AttributeGroup(); QMap attMap = DataBase::GetInstance()->Attribute(); int groupId = -1; for(auto &attGroup:groupMap) { if(attGroup.groupType == group) //返回参数属性组名对应的id { groupId = attGroup.id; break; } } QStringList lst; for(auto &mt:modelAttPublic) { if(mt.attributeGroupId == groupId) { lst.append(attMap[mt.attributeId].attribute); } } return lst; } void ProjectModelManager::setItemAttribute(const QString& name,QStandardItem* p) { QMap attMap = DataBase::GetInstance()->Attribute(); QMap dt = DataBase::GetInstance()->DataType(); for(auto &att:attMap) { QString sType = dt[att.dataTypeId].dataType; //获得属性id对应的属性名 if(name == att.attribute) { p->setData(att.id,Id); p->setData(att.attribute,Attribute); p->setData(att.attributeName,AttributeName); p->setData(sType,DataType); //不直接使用id,拼接完成str p->setData(att.lengthPrecision,LengthPrecision); p->setData(att.scale,Scale); p->setData(att.isNotNull,IsNotNull); p->setData(att.defaultValue,DefaultValue); p->setData(att.valueRange,ValueRange); p->setData(att.isVisible,IsVisible); return; } } } QPair ProjectModelManager::combinePropertySql(const QStandardItem* pItem) { QMap dt = DataBase::GetInstance()->DataType(); int id = pItem->data(Id).toInt(); QString attribute = pItem->data(Attribute).toString(); QString dataType = pItem->data(DataType).toString(); int lengthPrecision = pItem->data(LengthPrecision).toInt(); int scale = pItem->data(Scale).toInt(); QString defaultValue = pItem->data(DefaultValue).toString(); QString valueRange = pItem->data(ValueRange).toString(); int isNotNull = pItem->data(IsNotNull).toInt(); bool needsQuotes = stringDataTypes.contains(dataType); // 处理数据类型及其长度精度 QString dataTypePart = dataType; if (lengthPrecision > 0) { dataTypePart += QString("(%1").arg(lengthPrecision); if (scale > 0) { dataTypePart += QString(",%1").arg(scale); } dataTypePart += ")"; } // 开始拼接SQL QString sql = QString("%1 %2").arg(attribute, dataTypePart); // 处理约束条件 if (isNotNull != -1) { sql += " NOT NULL"; } if (!defaultValue.isEmpty()) { QString defValue = defaultValue; if (needsQuotes && defValue != "null" && defValue != "NULL") { // 转义单引号并包裹 defValue.replace("'", "''"); defValue = QString("'%1'").arg(defValue); } sql += QString(" DEFAULT %1").arg(defValue); } /*if (isPrimaryKey != 0) { sql += " PRIMARY KEY"; }*/ return qMakePair(sql,dataTypePart); } bool ProjectModelManager::ifProjectEqual(const QString& sMeta,const QString& sProject,QMap map) { //todo:判断关联的模型类型 MapProperty curPro = m_mapTotalData[sMeta][sProject].mapProperty; QMap::Iterator iter; for(iter = curPro.begin();iter != curPro.end();++iter) { if(iter->isPublic) //公共组跳过判断 continue; if(!map.contains(iter.key())) //已存在的模型中不包含该属性组 { QMap curCheckState = iter.value().mCheckState; for(auto &val:curCheckState) { if(val.checkState) //该属性组不在模型中且被勾选 return false; } continue; //该属性组不在模型中且未被勾选,不做判断 } else { QJsonObject dbCheckState = map[iter.key()]; //数据库中该属性组的勾选状态 QMap curCheckState = iter.value().mCheckState; //当前程序中的勾选状态 QJsonArray nodesJsonArray = dbCheckState["checkState"].toArray(); if(nodesJsonArray.size() != curCheckState.size()) //属性个数对不上,模型不同 return false; for (QJsonValueRef nodeJson : nodesJsonArray) { QJsonObject node = nodeJson.toObject(); QString propertyName = node["name"].toString(); int nState = node["checked"].toInt(); if(curCheckState[propertyName].checkState != nState) //相同属性选中状态不同 return false; } } } return true; } QString ProjectModelManager::modifyProjectModel(const QString& sMeta,const QString& sProject,QMap mapOld) { QString sRes; MapProperty curPro = m_mapTotalData[sMeta][sProject].mapProperty; QStandardItemModel* pSelectModel = m_mapTotalData[sMeta][sProject].pSelect; QStandardItemModel* pBaseModel = m_mapTotalData[sMeta][sProject].pBase; int nType = m_mapTotalData[sMeta][sProject].nType; QMap::Iterator iter; for(iter = curPro.begin();iter != curPro.end();++iter) //遍历当前模型所有属性组 { QMap curCheckState = iter.value().mCheckState; //当前程序中的属性勾选状态 bool isNull = true; //当前属性组是否未空 for(auto &val:curCheckState) { if(val.checkState){ isNull = false; //当前程序模型有勾选,不为空 break; } } if(isNull){ if(mapOld.contains(iter.key())){ //当前模型勾选为空且库模型中包含此属性组,移除库中该属性组表 QMap map = DataBase::GetInstance()->getProjectTableName(sProject); bool res = DataBase::GetInstance()->deleteTable(map[iter.key()]); if(res){ DataBase::GetInstance()->deleteRecordFromManager(sProject,iter.key()); sRes = QString::fromWCharArray(L"修改模型成功"); } } } else{ QList lstSelected = ProjectModelManager::instance().getGroupSub(pSelectModel,iter.key()); QList lstBase = ProjectModelManager::instance().getGroupSub(pBaseModel,iter.key()); if(mapOld.contains(iter.key())){ //新旧模型中都存在,修改模型 QMap oldSchema; //库中模型 属性名/数据类型 QMap newSchema; //现有模型 QJsonObject obj = mapOld[iter.key()]; QJsonArray nodesJsonArray = obj["checkState"].toArray(); for (QJsonValueRef nodeJson : nodesJsonArray) { QJsonObject node = nodeJson.toObject(); QString propertyName = node["name"].toString(); int nState = node["checked"].toInt(); QString dataType = node["type"].toString(); if(nState) oldSchema.insert(propertyName,dataType); } QMap::Iterator it; for(it = curCheckState.begin(); it != curCheckState.end();++it) { if(it->checkState){ newSchema.insert(it.key(),it->dataType); } } if(oldSchema == newSchema) continue; QMap map = DataBase::GetInstance()->getProjectTableName(sProject); bool res = DataBase::GetInstance()->modifyProjectTable(map[iter.key()],oldSchema,newSchema); QJsonObject objState = getSelectedState(lstSelected,lstBase); DataBase::GetInstance()->updateCheckState(map[iter.key()],objState); if(res) { sRes = QString::fromWCharArray(L"修改模型成功"); } } else{ //非空且库模型中不存在,新增 bool res = createPropertyTable(sMeta,sProject,iter.key(),lstSelected,lstBase,0,iter->isPublic); if(res) { sRes = QString::fromWCharArray(L"修改模型成功"); } } } } return sRes; } bool ProjectModelManager::renameProjectModel(const QString& strCur,QMap datas) { for(auto &data:datas) { QString sTable = data.metaModel + QString("_") + strCur + QString("_")+data.groupName; DataBase::GetInstance()->updateProjectName(sTable,strCur,data.name); DataBase::GetInstance()->alterTableName(data.name,sTable); } return true; } void ProjectModelManager::updateComponentModelName(const QString& strOld,const QString& strNew) { DataBase::GetInstance()->updateComponentModelName(strOld,strNew); } bool ProjectModelManager::ifProjectExsit(const QString& sPro) { for(auto &meta:m_mapTotalData) { if(meta.contains(sPro)) { return true; } } return false; } int ProjectModelManager::createPropertyTable(const QString& sMeta,const QString& sProject,const QString& sGroup,QList lstSelect,QList lstBase,int nLinkType,bool isPublic) { if(!isPublic) { QString sName = sMeta + QString("_") + sProject + QString("_")+sGroup; QStringList fields; fields.append("id SERIAL NOT NULL PRIMARY KEY"); fields.append("global_uuid uuid NOT NULL DEFAULT gen_random_uuid()"); fields.append("attribute_group VARCHAR(64) NOT NULL"); for(auto &item:lstSelect) { QPair pair = combinePropertySql(item); //拼接单句sql fields.append(pair.first); } fields.append("FOREIGN KEY (global_uuid) REFERENCES PUBLIC.component (global_uuid)"); QJsonObject objState = getSelectedState(lstSelect,lstBase); if(!DataBase::GetInstance()->createDynamicTable(sName,fields)) { return int(AlertInfo::fail); } else { DataBase::GetInstance()->insertProjectManager(sName,sProject,sMeta,sGroup,nLinkType,objState); return int(AlertInfo::success); } } else { QString sName = sGroup; QStringList fields; fields.append("id SERIAL NOT NULL PRIMARY KEY"); fields.append("global_uuid uuid NOT NULL DEFAULT gen_random_uuid()"); //fields.append("attribute_group VARCHAR(64) NOT NULL"); for(auto &item:lstSelect) { QString attribute = item->data(Attribute).toString(); if(attribute.contains("global_uuid")) continue; QPair pair = combinePropertySql(item); //拼接单句sql fields.append(pair.first); } QJsonObject objState = getSelectedState(lstSelect,lstBase); if(!DataBase::GetInstance()->ifDynamicTableExist(sName)) { bool val = DataBase::GetInstance()->createDynamicTable(sName,fields); DataBase::GetInstance()->insertProjectManager(sName,sName,"NULL",sGroup,0,objState,true); return val; } else { return int(AlertInfo::exist); } } } QJsonObject ProjectModelManager::getSelectedState(QList select,QList base) { QJsonObject objState; QJsonArray arrState; for(auto &item:select) { QString dataType = item->data(DataType).toString(); int lengthPrecision = item->data(LengthPrecision).toInt(); int scale = item->data(Scale).toInt(); QString defaultValue = item->data(DefaultValue).toString(); int isVisible = item->data(IsVisible).toInt(); QString dataTypePart = dataType; //拼接数据类型 if (lengthPrecision > 0) { dataTypePart += QString("(%1").arg(lengthPrecision); if (scale > 0) { dataTypePart += QString(",%1").arg(scale); } dataTypePart += ")"; } QJsonObject node; //保存已选择状态 node["name"] = item->text(); node["checked"] = 1; node["type"] = dataTypePart; node["defaultValue"] = defaultValue; node["lengthPrecision"] = lengthPrecision; node["isVisible"] = isVisible; arrState.append(node); } for(auto &item:base) { QString dataType = item->data(DataType).toString(); int lengthPrecision = item->data(LengthPrecision).toInt(); int scale = item->data(Scale).toInt(); QString defaultValue = item->data(DefaultValue).toString(); int isVisible = item->data(IsVisible).toInt(); QString dataTypePart = dataType; //拼接数据类型 if (lengthPrecision > 0) { dataTypePart += QString("(%1").arg(lengthPrecision); if (scale > 0) { dataTypePart += QString(",%1").arg(scale); } dataTypePart += ")"; } QJsonObject node; //保存未选择状态 node["name"] = item->text(); node["checked"] = 0; node["type"] = dataTypePart; node["defaultValue"] = defaultValue; node["lengthPrecision"] = lengthPrecision; node["isVisible"] = isVisible; arrState.append(node); } objState["checkState"] = arrState; return objState; } QString ProjectModelManager::getItemDataType(const QStandardItem* pItem) { QString dataType = pItem->data(DataType).toString(); int lengthPrecision = pItem->data(LengthPrecision).toInt(); int scale = pItem->data(Scale).toInt(); QString dataTypePart = dataType; if (lengthPrecision > 0) { dataTypePart += QString("(%1").arg(lengthPrecision); if (scale > 0) { dataTypePart += QString(",%1").arg(scale); } dataTypePart += ")"; } return dataTypePart; } projectModelSetting ProjectModelManager::getModelSetting(const QString& sMeta,const QString& sProject) { projectModelSetting setting; setting.modelName = sProject; QJsonObject obj = DataBase::GetInstance()->getProjectSetting(sMeta,sProject); QJsonArray arr = obj["picture"].toArray(); for (QJsonValueRef jsonObj : arr) { QJsonObject node = jsonObj.toObject(); QString sName = node["name"].toString(); QByteArray bData = QByteArray::fromHex(node["data"].toString().toUtf8()); setting.mapSvg.insert(sName,bData); } QJsonArray arrUsed = obj["usingPicture"].toArray(); for (QJsonValueRef jsonObj : arrUsed) { QJsonObject node = jsonObj.toObject(); QString sName = node["name"].toString(); QByteArray bData = QByteArray::fromHex(node["data"].toString().toUtf8()); setting.mapUsedSvg.insert(sName,bData); } return setting; }