#include "dbStructureModel.h" #include "mainwindow.h" #include "sqlQueryExecutor.h" #include "logger.h" // #include // #include DBStructureModel::DBStructureModel(QObject* parent) : QAbstractItemModel(parent) , m_rootNode(new DBStructureNode(RootNode, "Root")) , m_pMainWindow(nullptr) { } DBStructureModel::~DBStructureModel() { delete m_rootNode; } void DBStructureModel::setMainWindow(MainWindow* window) { m_pMainWindow = window; } DBStructureNode* DBStructureModel::getNode(const QModelIndex& index) const { if(index.isValid()) return static_cast(index.internalPointer()); else return m_rootNode; } DBStructureNode* DBStructureModel::getConnectionNode(const QString& name) const { for(int i = 0; i < m_rootNode->childCount(); ++i) { DBStructureNode* node = m_rootNode->child(i); if(node->type() == ConnectionNode && node->name() == name) return node; } return nullptr; } DBStructureNode* DBStructureModel::getModelNode(DBStructureNode* connNode, int modelID) const { if(!connNode) return nullptr; for(int i = 0; i < connNode->childCount(); ++i) { DBStructureNode* node = connNode->child(i); if(node->type() == TableNode && node->data(Qt::UserRole + NodeDataRole::ID).toInt() == modelID) return node; } return nullptr; } QModelIndex DBStructureModel::index(int row, int column, const QModelIndex& parent) const { if(!hasIndex(row, column, parent)) return QModelIndex(); DBStructureNode* parentNode = getNode(parent); DBStructureNode* childNode = parentNode->child(row); if(childNode) return createIndex(row, column, childNode); else return QModelIndex(); } QModelIndex DBStructureModel::parent(const QModelIndex& index) const { if(!index.isValid()) return QModelIndex(); DBStructureNode* childNode = static_cast(index.internalPointer()); DBStructureNode* parentNode = childNode->parentNode(); if(parentNode == m_rootNode) return QModelIndex(); return createIndex(parentNode->row(), 0 ,parentNode); } int DBStructureModel::rowCount(const QModelIndex& parent) const { DBStructureNode* parentNode = getNode(parent); return parentNode->childCount(); } int DBStructureModel::columnCount(const QModelIndex& parent) const { return DBStructureNode::ColumnCount; } QVariant DBStructureModel::data(const QModelIndex& index, int role) const { if(!index.isValid()) return QVariant(); DBStructureNode* node = static_cast(index.internalPointer()); switch (role) { case Qt::DisplayRole: case Qt::EditRole: return node->columnData(DBStructureNode::ColumnName); case Qt::DecorationRole: return node->icon(); default: return node->data(role); } } bool DBStructureModel::setData(const QModelIndex& index, const QVariant& value, int role) { if (role != Qt::EditRole) return false; DBStructureNode* node = static_cast(index.internalPointer()); node->setName(value.toString()); emit dataChanged(index, index, {role}); return true; } QVariant DBStructureModel::headerData(int section, Qt::Orientation orientation, int role) const { if(orientation == Qt::Horizontal && role == Qt::DisplayRole) { switch(section) { case DBStructureNode::ColumnName: return "Name"; default: return QVariant(); } } return QVariant(); } void DBStructureModel::addConnection(const QString& name, const QString& connID) { beginInsertRows(QModelIndex(), m_rootNode->childCount(), m_rootNode->childCount()); //链接节点是根节点的(m_rootNode)的子节点,根节点的索引是QModelIndex() DBStructureNode* connectionNode = new DBStructureNode(ConnectionNode, name, m_rootNode); connectionNode->setData(Qt::UserRole + NodeDataRole::ID, connID); m_rootNode->appendChild(connectionNode); endInsertRows(); //该语句之后会触发rowsInserted(const QModelIndex &parent, int first, int last)信号,通知视图刷新对应行 } void DBStructureModel::removeConnection(const QString& name) { DBStructureNode* connNode = getConnectionNode(name); if(!connNode) return; beginRemoveRows(QModelIndex(), connNode->row(), connNode->row()); m_rootNode->removeChild(connNode); endRemoveRows(); } QModelIndex DBStructureModel::getConnNodeIndex(const QString& name) { DBStructureNode* connNode = getConnectionNode(name); if(!connNode) return QModelIndex(); else return index(connNode->row(), 0, QModelIndex()); } void DBStructureModel::addDataModel(const QString& connection, Model& model) { QModelIndex connIndex = getConnNodeIndex(connection); if(!connIndex.isValid()) { LOG_ERROR("DBStructureModel", QString::fromWCharArray(L"获取ModelIndex失败,节点名称:%1").arg(connection)); return; } DBStructureNode* connNode = getConnectionNode(connection); if(!connNode) { LOG_ERROR("DBStructureModel", QString::fromWCharArray(L"获取Node对象失败,节点名称:%1").arg(connection)); return; } beginInsertRows(connIndex, connNode->childCount(), connNode->childCount()); DBStructureNode* modelNode = new DBStructureNode(TableNode, model.name, connNode); modelNode->setData(Qt::UserRole + NodeDataRole::ID, model.id); for(int groupID : model.groups) { //QString groupName = SqlQueryExecutor::instance().getAttributeGroupName(connection, groupID); AttributeGroup group = SqlQueryExecutor::instance().getAttributeGroupData(connection, groupID); if(group.name.isEmpty()) continue; DBStructureNode* groupNode = new DBStructureNode(GroupNode, group.name, modelNode); groupNode->setData(Qt::UserRole + NodeDataRole::ID, groupID); groupNode->setData(Qt::UserRole + NodeDataRole::Type, group.isPublic); modelNode->appendChild(groupNode); } connNode->appendChild(modelNode); endInsertRows(); } void DBStructureModel::removeDataModel(DBStructureNode* modelNode) { //可以不对node在进行一系列的检查,因为该函数调取之前已有相关逻辑 int modelID = modelNode->data(Qt::UserRole + NodeDataRole::ID).toInt(); //先从数据库中删除 DBStructureNode* connNode = modelNode->parentNode(); if(!(connNode && connNode->type() == ConnectionNode)) { if(m_pMainWindow) { QString error = QString::fromWCharArray(L"删除失败,未找到所在链接节点信息"); m_pMainWindow->showMessageDialog(type_information, QString::fromWCharArray(L"失败"), error); } return; } bool result = SqlQueryExecutor::instance().removeModel(connNode->name(), modelID); if(!result) { if(m_pMainWindow) { QString error = QString::fromWCharArray(L"删除失败,详情可见日志文件"); m_pMainWindow->showMessageDialog(type_information, QString::fromWCharArray(L"失败"), error); } return; } else //从列表中删除 { beginRemoveRows(index(connNode->row(), 0, QModelIndex()), modelNode->row(), modelNode->row()); connNode->removeChild(modelNode); endRemoveRows(); } } void DBStructureModel::updateDataModelName(const QString& connection, int modelID, const QString& name) { DBStructureNode* connNode = getConnectionNode(connection); if(!connNode) { LOG_ERROR("DBStructureModel", QString::fromWCharArray(L"更改模型名称时获取ConnectionNode失败,节点名称:%1").arg(connection)); return; } DBStructureNode* modelNode = getModelNode(connNode, modelID); if(!connNode) { LOG_ERROR("DBStructureModel", QString::fromWCharArray(L"更改模型名称时获取ModelNode失败,节点ID:%1").arg(modelID)); return; } QModelIndex connIndex = index(connNode->row(), 0, QModelIndex()); QModelIndex modelIndex = index(modelNode->row(), 0, connIndex); setData(modelIndex, name); } void DBStructureModel::addDataGroup(const QString& connection, int modelID, QVector groups) { DBStructureNode* connNode = getConnectionNode(connection); if(!connNode) { LOG_ERROR("DBStructureModel", QString::fromWCharArray(L"添加属性组时获取ConnectionNode失败,节点名称:%1").arg(connection)); return; } DBStructureNode* modelNode = getModelNode(connNode, modelID); if(!connNode) { LOG_ERROR("DBStructureModel", QString::fromWCharArray(L"添加属性组时获取ModelNode失败,节点ID:%1").arg(modelID)); return; } QModelIndex connIndex = index(connNode->row(), 0, QModelIndex()); QModelIndex modelIndex = index(modelNode->row(), 0, connIndex); beginInsertRows(modelIndex, modelNode->childCount(), modelNode->childCount() + groups.count() - 1); for(int groupID : groups) { //QString groupName = SqlQueryExecutor::instance().getAttributeGroupName(connection, groupID); AttributeGroup group = SqlQueryExecutor::instance().getAttributeGroupData(connection, groupID); if(group.name.isEmpty()) continue; DBStructureNode* groupNode = new DBStructureNode(GroupNode, group.name, modelNode); groupNode->setData(Qt::UserRole + NodeDataRole::ID, groupID); groupNode->setData(Qt::UserRole + NodeDataRole::Type, group.isPublic); modelNode->appendChild(groupNode); } endInsertRows(); } void DBStructureModel::removeDataGroup(DBStructureNode* groupNode) { int groupID = groupNode->data(Qt::UserRole + NodeDataRole::ID).toInt(); //先从数据库中删除 DBStructureNode* modelNode = groupNode->parentNode(); if(!(modelNode && modelNode->type() == TableNode)) { if(m_pMainWindow) { QString error = QString::fromWCharArray(L"删除失败,未找到所在链接节点信息"); m_pMainWindow->showMessageDialog(type_information, QString::fromWCharArray(L"失败"), error); } return; } int modelID = modelNode->data(Qt::UserRole + NodeDataRole::ID).toInt(); DBStructureNode* connNode = modelNode->parentNode(); if(!(connNode && connNode->type() == ConnectionNode)) { if(m_pMainWindow) { QString error = QString::fromWCharArray(L"删除失败,未找到所在链接节点信息"); m_pMainWindow->showMessageDialog(type_information, QString::fromWCharArray(L"失败"), error); } return; } bool result = SqlQueryExecutor::instance().removeAttributeGroup(connNode->name(), modelID, groupID); if(!result) { if(m_pMainWindow) { QString error = QString::fromWCharArray(L"删除失败,详情可见日志文件"); m_pMainWindow->showMessageDialog(type_information, QString::fromWCharArray(L"失败"), error); } return; } else //从列表中删除 { QModelIndex connIndex = index(connNode->row(), 0, QModelIndex()); beginRemoveRows(index(modelNode->row(), 0, connIndex), groupNode->row(), groupNode->row()); modelNode->removeChild(groupNode); endRemoveRows(); } } void DBStructureModel::refreshStructure_Connection(const QString& connection) { DBStructureNode* connNode = getConnectionNode(connection); if(!connNode) return; //先删除当前链接节点下的节点 if(connNode->childCount() > 0) { beginRemoveRows(index(connNode->row(), 0, QModelIndex()), 0, connNode->childCount() - 1); connNode->removeAllChildren(); endRemoveRows(); //该语句之后会触发rowsRemoved(const QModelIndex &parent, int first, int last)信号,通知视图刷新对应行 } QSqlDatabase db = QSqlDatabase::database(connection); if(!db.isOpen()) { if(connNode->status() == Connect) { connNode->setStatus(Disconnect); QModelIndex topLeft = index(connNode->row(), 0, QModelIndex()); QModelIndex bottomRight = index(connNode->row(), 0, QModelIndex()); emit dataChanged(topLeft, bottomRight, {Qt::DecorationRole}); } return; } //重新加载数据节点 /*QString strSql = "SELECT * FROM basic.attribute_group ORDER BY id ASC"; QSqlQuery query(db); if(!query.exec(strSql)) return; QVector tables; while(query.next()) { QString tableName = query.value(2).toString(); tables << new DBStructureNode(TableNode, tableName, connNode); }*/ const QVector models = SqlQueryExecutor::instance().getModels(connection); beginInsertRows(index(connNode->row(), 0, QModelIndex()), 0, models.count() - 1); for(const Model& model : models) { DBStructureNode* modelNode = new DBStructureNode(TableNode, model.name, connNode); modelNode->setData(Qt::UserRole + NodeDataRole::ID, model.id); for(int groupID : model.groups) { //QString groupName = SqlQueryExecutor::instance().getAttributeGroupName(connection, groupID); AttributeGroup group = SqlQueryExecutor::instance().getAttributeGroupData(connection, groupID); if(group.name.isEmpty()) continue; DBStructureNode* groupNode = new DBStructureNode(GroupNode, group.name, modelNode); groupNode->setData(Qt::UserRole + NodeDataRole::ID, groupID); groupNode->setData(Qt::UserRole + NodeDataRole::Type, group.isPublic); modelNode->appendChild(groupNode); } connNode->appendChild(modelNode); } endInsertRows(); if(connNode->status() == Disconnect) { connNode->setStatus(Connect); QModelIndex topLeft = index(connNode->row(), 0, QModelIndex()); QModelIndex bottomRight = index(connNode->row(), 0, QModelIndex()); emit dataChanged(topLeft, bottomRight, {Qt::DecorationRole}); } } void DBStructureModel::refreshStructure_Model(const QString& connection, int modelID) { DBStructureNode* connNode = getConnectionNode(connection); if(!connNode) { LOG_ERROR("DBStructureModel", QString::fromWCharArray(L"刷新模型节点时获取ConnectionNode失败,节点名称:%1").arg(connection)); return; } QModelIndex connIndex = index(connNode->row(), 0, QModelIndex()); DBStructureNode* modelNode = getModelNode(connNode, modelID); if(!connNode) { LOG_ERROR("DBStructureModel", QString::fromWCharArray(L"刷新模型节点时获取ModelNode失败,节点ID:%1").arg(modelID)); return; } //先删除 if(modelNode->childCount() > 0) { beginRemoveRows(index(modelNode->row(), 0, connIndex), 0, modelNode->childCount() - 1); modelNode->removeAllChildren(); endRemoveRows(); //该语句之后会触发rowsRemoved(const QModelIndex &parent, int first, int last)信号,通知视图刷新对应行 } //读取最新数据重新添加 QVector groups = SqlQueryExecutor::instance().getModelGroups(connection, modelID); beginInsertRows(index(modelNode->row(), 0, connIndex), 0, groups.count() - 1); for(int groupID : groups) { //QString groupName = SqlQueryExecutor::instance().getAttributeGroupName(connection, groupID); AttributeGroup group = SqlQueryExecutor::instance().getAttributeGroupData(connection, groupID); if(group.name.isEmpty()) continue; DBStructureNode* groupNode = new DBStructureNode(GroupNode, group.name, modelNode); groupNode->setData(Qt::UserRole + NodeDataRole::ID, groupID); groupNode->setData(Qt::UserRole + NodeDataRole::Type, group.isPublic); modelNode->appendChild(groupNode); } endInsertRows(); }