PowerModeler/source/dbStructureModel.cpp

380 lines
13 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "dbStructureModel.h"
#include "mainwindow.h"
#include "sqlQueryExecutor.h"
#include "logger.h"
// #include <QSqlDatabase>
// #include <QSqlQuery>
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<DBStructureNode*>(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<DBStructureNode*>(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<DBStructureNode*>(index.internalPointer());
switch (role)
{
case Qt::DisplayRole:
return node->columnData(DBStructureNode::ColumnName);
case Qt::DecorationRole:
return node->icon();
default:
return node->data(role);
}
}
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& dbType)
{
beginInsertRows(QModelIndex(), m_rootNode->childCount(), m_rootNode->childCount()); //链接节点是根节点的(m_rootNode)的子节点根节点的索引是QModelIndex()
DBStructureNode* connectionNode = new DBStructureNode(ConnectionNode, name, m_rootNode);
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::addDataGroup(const QString& connection, int modelID, QVector<int> 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<DBStructureNode*> tables;
while(query.next())
{
QString tableName = query.value(2).toString();
tables << new DBStructureNode(TableNode, tableName, connNode);
}*/
const QVector<Model> 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});
}
}