save/delete model function added

This commit is contained in:
baiYue 2025-03-07 19:24:19 +08:00
parent e18ff1a59a
commit 8ed3fb8f97
7 changed files with 238 additions and 63 deletions

View File

@ -24,14 +24,14 @@ struct attribute //属性表(元模属性字段)
{
int id = 0;
QString attribute; //属性名
QString dataType; //数据类型
int dataType; //数据类型
int lengthPrecision=0; //长度限制(varchar)
int scale=0; //小数点位数
QString defaultValue; //默认值
QString valueRange; //数值范围
int attributeGroup=0; //属性组
int isNotNull=0; //是否非空
int isPrimaryKey=0; //是否主键
int isIndex=0; //是否index
};
struct modelAttribute //模型-属性对应表(元模在此表查找)
@ -185,9 +185,10 @@ public:
//***********工程模
bool createProjectManager(); //生成记录表,包含工程模名称,属性组名,启用和关闭的属性字段(json类型)[一个属性组建一个表]
bool insertProjectManager(const QString& name,const QString& tag,const QString& metaModel,const QString& groupName,int linkType,QJsonObject checkState);
bool getProjectManager();
QStringList getProjectFromManager(const QString& sMeta); //返回元模下已创建的工程名
QMap<QString,QJsonObject> getCheckStateFromManager(const QString& sProject); //获取当前工程模型所有属性的选择状态 <属性名,选择状态>
bool createDynamicTable(const QString&, const QStringList&);
bool deleteProjectModel(const QString&);
private:
QMap<int,attributeGroup> _attributeGroup; //属性组的组
QMap<int,dataType> _dataType; //数据类型组

View File

@ -42,7 +42,7 @@ enum Attribute //元模属性字段对照
ValueRange = Qt::UserRole + 7,
AttributeGroup = Qt::UserRole + 8,
IsNotNull = Qt::UserRole + 9,
IsPrimaryKey = Qt::UserRole + 10
IsIndex = Qt::UserRole + 10
};
//Q_ENUM_NS(GraphicsItemType)

View File

@ -47,6 +47,12 @@ void DataBase::initial()
} else {
qDebug()<<"baseDB failed";
}
//元模
getAttributeGroup();
getDataType();
getAttribute();
getModelAttribute();
getModelConnectivity();
}
/*bool DataBase::createProjectDB()
@ -883,7 +889,7 @@ bool DataBase::getAttributeGroup()
if(db.open())
{
QSqlQuery qry(db);
bool success = qry.exec("SELECT * FROM attribute_group");
bool success = qry.exec("SELECT * FROM basic.attribute_group");
if (!success) {
qDebug()<<qry.lastError().text();
}
@ -916,7 +922,7 @@ bool DataBase::getDataType()
if(db.open())
{
QSqlQuery qry(db);
bool success = qry.exec("SELECT * FROM data_type");
bool success = qry.exec("SELECT * FROM basic.data_type");
if (!success) {
qDebug()<<qry.lastError().text();
}
@ -949,7 +955,7 @@ bool DataBase::getAttribute()
if(db.open())
{
QSqlQuery qry(db);
bool success = qry.exec("SELECT * FROM attribute");
bool success = qry.exec("SELECT * FROM basic.attribute");
if (!success) {
qDebug()<<qry.lastError().text();
}
@ -959,16 +965,16 @@ bool DataBase::getAttribute()
{
int id = qry.value(0).toInt();
QString att = qry.value(1).toString(); //属性名
QString dt = qry.value(2).toString(); //类型名
int dt = qry.value(2).toInt(); //类型号
int len = qry.value(3).toInt(); //类型长度
int scale = qry.value(4).toInt(); //类型精度
QString dv = qry.value(5).toString(); //默认值
QString vr = qry.value(6).toString(); //范围
int ag = qry.value(7).toInt(); //属性组
int inn = qry.value(8).toInt(); //非空
int ipk = qry.value(9).toInt(); //是否主键
int ii = qry.value(9).toInt(); //是否index
if(!_dataType.contains(id))
if(!_attribute.contains(id))
{
attribute attribute;
attribute.id = id;
@ -980,7 +986,7 @@ bool DataBase::getAttribute()
attribute.valueRange = vr;
attribute.attributeGroup = ag;
attribute.isNotNull = inn;
attribute.isPrimaryKey = ipk;
attribute.isIndex = ii;
_attribute.insert(id,attribute);
}
@ -997,7 +1003,7 @@ bool DataBase::getModelAttribute()
if(db.open())
{
QSqlQuery qry(db);
bool success = qry.exec("SELECT * FROM model_attribute");
bool success = qry.exec("SELECT * FROM basic.model_attribute");
if (!success) {
qDebug()<<qry.lastError().text();
}
@ -1030,7 +1036,7 @@ bool DataBase::getModelConnectivity()
if(db.open())
{
QSqlQuery qry(db);
bool success = qry.exec("SELECT * FROM model_connectivity");
bool success = qry.exec("SELECT * FROM basic.model_connectivity");
if (!success) {
qDebug()<<qry.lastError().text();
}
@ -1077,7 +1083,7 @@ bool DataBase::createProjectManager()
meta_model VARCHAR(64) NOT NULL,
group_name VARCHAR(64) NOT NULL,
link_type integer NOT NULL DEFAULT 0,
check_state JSONB NOT NULL DEFAULT '{}'::jsonb,
check_state JSONB NOT NULL DEFAULT '{}'::jsonb
)
)";
@ -1101,7 +1107,7 @@ bool DataBase::insertProjectManager(const QString& name,const QString& tag,const
QString strCheck = checkDoc.toJson(QJsonDocument::Compact);
qry.prepare("INSERT INTO project_manager(name, tag, meta_model, group_name, linkType, check_state) VALUES (?, ?, ?, ?, ?, ?)");
qry.prepare("INSERT INTO project_manager(name, tag, meta_model, group_name, link_type, check_state) VALUES (?, ?, ?, ?, ?, ?)");
qry.bindValue(0,name);
qry.bindValue(1,tag);
qry.bindValue(2,metaModel);
@ -1120,9 +1126,37 @@ bool DataBase::insertProjectManager(const QString& name,const QString& tag,const
return false;
}
bool DataBase::getProjectManager()
QStringList DataBase::getProjectFromManager(const QString& sMeta)
{
QSet<QString> projectSet;
if(db.open())
{
QSqlQuery qry(db);
qry.prepare("SELECT tag FROM project_manager WHERE meta_model = ?");
qry.bindValue(0,sMeta);
bool res = qry.exec();
QString str = qry.lastQuery();
if(!res)
{
qDebug()<<str<<"\n"<<qry.lastError().text();
qry.clear();
return QStringList();
}
else
{
while (qry.next())
{
QString tag = qry.value(0).toString();
projectSet.insert(tag);
qry.clear();
}
return QStringList(projectSet.values());
}
}
else
return QStringList();
}
QMap<QString,QJsonObject> DataBase::getCheckStateFromManager(const QString& sProject)
@ -1153,9 +1187,9 @@ QMap<QString,QJsonObject> DataBase::getCheckStateFromManager(const QString& sPro
QString group = qry.value(0).toString();
QString state = qry.value(1).toString();
QJsonObject jsonObj = QstringToJson(state);
qry.clear();
map.insert(group,jsonObj);
}
qry.clear();
return map;
}
}
@ -1176,10 +1210,10 @@ bool DataBase::createDynamicTable(const QString &tableName, const QStringList &f
// Remove the last comma and space
createTableSQL.chop(2);
createTableSQL += ")";
createTableSQL += ");";
QSqlQuery query;
bool res = query.exec();
QSqlQuery query(db);
bool res = query.exec(createTableSQL);
if (!res) {
qDebug() << "Error creating dynamic table:" << query.lastError().text();
} else {
@ -1189,3 +1223,59 @@ bool DataBase::createDynamicTable(const QString &tableName, const QStringList &f
}
return false;
}
bool DataBase::deleteProjectModel(const QString& sProject)
{
if(sProject == QString::fromWCharArray(L"新建"))
{
return false;
}
if(db.open())
{
QStringList lstTable;
QSqlQuery qry(db);
qry.prepare("SELECT name FROM project_manager WHERE tag = ?");
qry.bindValue(0,sProject);
bool res = qry.exec();
QString str = qry.lastQuery();
if(!res)
{
qDebug()<<str<<"\n"<<qry.lastError().text();
qry.clear();
return false;
}
else
{
while (qry.next())
{
QString sName = qry.value(0).toString(); //获取表名
lstTable.append(sName);
}
qry.finish();
}
for(auto &sTab:lstTable)
{
QString sql = QString("DROP TABLE IF EXISTS %1").arg(sTab); // 构建SQL语句
if (!qry.exec(sql)) { // 执行SQL语句
qDebug() << "删除表失败:" << qry.lastError().text(); // 打印错误信息
return false;
}
qDebug() << "" << sTab << "已成功删除。";
}
qry.finish();
qry.prepare("DELETE FROM project_manager WHERE tag = ?");
qry.bindValue(0,sProject);
// 执行删除操作
if (!qry.exec()) {
qDebug() << "删除行失败:" << qry.lastError().text();
return false;
}
qry.clear();
}
else
return false;
}

View File

@ -20,7 +20,7 @@ typedef QMap<QString,PropertyPage> MapProperty; //str为属性名model1
struct PropertyModel //工程模
{
MapProperty mapProperty;
int nType; //工程模类型,选择图标后确定
int nType = 0; //工程模类型,选择图标后确定
};
typedef QMap<QString,PropertyModel> MapProject; //str为工程名property为属性集
typedef QMap<QString,MapProject> MapMeta; //str为元模名,project为工程模集
@ -46,13 +46,15 @@ public:
public slots:
void onSaveClicked();
void onCancelClicked();
void onGenerateClicked();
void onApplyClicked();
void onRevokeClicked();
void onBaseModelIndexChanged(const QString&);
void onProjectIndexChanged(const QString&);
void onPropertyIndexChanged(const QString&);
void onIconClicked(const QModelIndex &index); //关联图元改变
void onIndexClicked(const QModelIndex &index); //索引列表点击
void onIndexRbtnClicked(const QPoint &pos); //索引列表右键菜单
void onDeleteProjectClicked(); //删除选中工程模
public:
QStringList getModelList() const; //获取元模型列表
QStringList getGroupList(const QString& model) const; //返回该元模下的属性组列表
@ -61,6 +63,7 @@ public:
QString combinePropertySql(const QStandardItem*); //根据item属性生成sql
private:
void updateIconList(); //选择工程模后刷新关联图标
void removeProjectData(const QString&,const QString&); //移除对应的project层级结构
private:
Ui::projectModelDlg *ui;
RenameModel* m_pRenameModel;

View File

@ -1,5 +1,6 @@
#include <QMessageBox>
#include <QJsonArray>
#include <QMenu>
#include "projectModelDlg.h"
#include "renameModel.h"
#include "dataBase.h"
@ -30,7 +31,7 @@ projectModelDlg::~projectModelDlg()
void projectModelDlg::initial()
{
connect(ui->btn_generate,&QPushButton::clicked,this,&projectModelDlg::onGenerateClicked);
ui->stackedWidget->setCurrentIndex(1);
connect(ui->btn_save,&QPushButton::clicked,this,&projectModelDlg::onSaveClicked);
connect(ui->btn_cancel,&QPushButton::clicked,this,&projectModelDlg::onCancelClicked);
connect(ui->btn_apply,&QPushButton::clicked,this,&projectModelDlg::onApplyClicked);
@ -40,6 +41,9 @@ void projectModelDlg::initial()
connect(ui->cb_projectModel,&QComboBox::textActivated,this,&projectModelDlg::onProjectIndexChanged);
connect(ui->cb_property,&QComboBox::textActivated,this,&projectModelDlg::onPropertyIndexChanged);
ui->treeView_model->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ui->treeView_model, &QTreeView::customContextMenuRequested, this, &projectModelDlg::onIndexRbtnClicked);
connect(ui->treeView_model, &QTreeView::clicked, this, &projectModelDlg::onIndexClicked);
initialModel();
initialList();
update();
@ -119,8 +123,8 @@ void projectModelDlg::initialModel()
for(auto &model:lstModel)
{
MapProject mp;
QStringList lstProject;
lstProject<<QString::fromWCharArray(L"新建"); //每个类别都有未命名工程
QStringList lstProject = DataBase::GetInstance()->getProjectFromManager(model);
lstProject.prepend(QString::fromWCharArray(L"新建")); //每个类别都有未命名工程
QStandardItem* modelItem = new QStandardItem(model); //总览view类型
for(auto &proj:lstProject)
@ -167,7 +171,6 @@ void projectModelDlg::update()
void projectModelDlg::generate(const QString& str)
{
QString pre = QString("project_");
MapMeta::Iterator iter = m_mapTotal.find(_curMeta); //获取元模下的工程
if(iter != m_mapTotal.end())
{
@ -179,11 +182,8 @@ void projectModelDlg::generate(const QString& str)
bool createRes = true; //动态表生成结果
for(MapProperty::Iterator it = mapProperty.begin();it != mapProperty.end();++it){ //每个属性组单独生成表
QUuid uuid = QUuid::createUuid();
// 不带花括号的 UUID 字符串
QString noDashes = uuid.toString(QUuid::WithoutBraces);
QString uuidString = noDashes.replace("-", "");
QString sName = pre+it.key()+QString("_")+uuidString; //生成表名
QString sName = _curMeta + QString("_") + str + QString("_")+it.key();
QStringList fields;
fields.append("id SERIAL NOT NULL PRIMARY KEY");
@ -202,7 +202,7 @@ void projectModelDlg::generate(const QString& str)
fields.append(s);
QJsonObject node; //保存已选择状态
node["name"] = rootItem->text();
node["name"] = childItem->text();
node["checked"] = 1;
arrState.append(node);
}
@ -213,7 +213,7 @@ void projectModelDlg::generate(const QString& str)
QStandardItem *childItem = rootItem->child(row);
if (childItem) {
QJsonObject node; //保存未选择状态
node["name"] = rootItem->text();
node["name"] = childItem->text();
node["checked"] = 0;
arrState.append(node);
}
@ -280,10 +280,6 @@ void projectModelDlg::onSaveClicked()
}
}
void projectModelDlg::onGenerateClicked()
{
}
void projectModelDlg::onCancelClicked()
{
@ -485,6 +481,103 @@ void projectModelDlg::onIconClicked(const QModelIndex &index)
{
QStandardItem* pItem = model->itemFromIndex(index);
int id = pItem->data(Qt::UserRole).toInt();
m_mapTotal[_curMeta][_curProject].nType = id;
}
}
void projectModelDlg::onIndexClicked(const QModelIndex &index)
{
// 获取模型
QStandardItemModel *model = qobject_cast<QStandardItemModel*>(ui->treeView_model->model());
if (!model) {
return;
}
// 判断是否为第二级节点
if (index.parent().isValid()) { // 父索引有效,说明是第二级节点
QString sMeta = model->data(index.parent(), Qt::DisplayRole).toString();
QString sProject = model->data(index, Qt::DisplayRole).toString();
ui->cb_baseModel->setCurrentText(sMeta); //无法编辑combobox的会跳转到该内容
onBaseModelIndexChanged(sMeta);
ui->cb_projectModel->setCurrentText(sProject);
onProjectIndexChanged(sProject);
_curMeta = sMeta;
_curProject = sProject;
} else {
QString sMeta = model->data(index, Qt::DisplayRole).toString();
ui->cb_baseModel->setCurrentText(sMeta); //无法编辑combobox的会跳转到该内容
onBaseModelIndexChanged(sMeta);
_curMeta = sMeta;
_curProject = "";
}
}
void projectModelDlg::onIndexRbtnClicked(const QPoint &pos)
{
// 获取当前点击的位置对应的索引
QModelIndex index = ui->treeView_model->indexAt(pos);
if (!index.isValid()) {
return; // 如果点击的是空白区域,直接返回
}
// 判断是否为第一级节点
if (!index.parent().isValid()) {
return; // 如果是第一级节点,不显示菜单
}
// 如果是第二级节点,创建右键菜单
QMenu menu;
QAction *deleteAction = new QAction("删除节点", this);
menu.addAction(deleteAction);
// 连接删除菜单项的触发信号与槽函数
connect(deleteAction, &QAction::triggered, this, &projectModelDlg::onDeleteProjectClicked);
// 在点击位置显示菜单
menu.exec(ui->treeView_model->mapToGlobal(pos));
}
void projectModelDlg::onDeleteProjectClicked()
{
// 获取当前选中的索引
QModelIndexList selectedIndexes = ui->treeView_model->selectionModel()->selectedRows();
if (selectedIndexes.isEmpty()) {
return; // 没有选中任何行
}
// 获取当前选中的第一项索引
QModelIndex index = selectedIndexes.first();
// 确保索引有效
if (!index.isValid()) {
return;
}
// 获取模型
QStandardItemModel *model = qobject_cast<QStandardItemModel*>(ui->treeView_model->model());
if (!model) {
return;
}
// 判断是否为第二级节点
if (index.parent().isValid()) { // 父索引有效,说明是第二级节点
// 删除当前选中的项
QString meta = model->data(index.parent(), Qt::DisplayRole).toString();
QString text = model->data(index, Qt::DisplayRole).toString();
bool val = DataBase::GetInstance()->deleteProjectModel(text);
if(val)
{
//removeProjectData(meta,text);
model->removeRow(index.row(), index.parent());
}
else
QMessageBox::information(NULL, QString::fromWCharArray(L"提示"), QString::fromWCharArray(L"删除失败"));
} else {
// 如果是第一级节点,不执行删除操作
return;
}
}
@ -571,21 +664,23 @@ QStringList projectModelDlg::getAttributeList(const QString& sM,const QString& s
void projectModelDlg::setItemAttribute(const QString& name,QStandardItem* p)
{
QMap<int,attribute> attMap = DataBase::GetInstance()->Attribute();
QMap<int,dataType> dt = DataBase::GetInstance()->DataType();
for(auto &att:attMap)
{
QString sType = dt[att.dataType].dataType; //获得属性id对应的属性名
if(name == att.attribute)
{
p->setData(att.id,Id);
p->setData(att.attribute,Attribute);
p->setData(att.dataType,DataType);
p->setData(sType,DataType);
p->setData(att.lengthPrecision,LengthPrecision);
p->setData(att.scale,Scale);
p->setData(att.defaultValue,DefaultValue);
p->setData(att.valueRange,ValueRange);
p->setData(att.attributeGroup,AttributeGroup);
p->setData(att.isNotNull,IsNotNull);
p->setData(att.isPrimaryKey,IsPrimaryKey);
p->setData(att.isIndex,IsIndex);
return;
}
}
@ -602,7 +697,7 @@ QString projectModelDlg::combinePropertySql(const QStandardItem* pItem)
QString valueRange = pItem->data(ValueRange).toString();
int attributeGroup = pItem->data(AttributeGroup).toInt();
int isNotNull = pItem->data(IsNotNull).toInt();
int isPrimaryKey = pItem->data(IsPrimaryKey).toInt();
int isIndex = pItem->data(IsIndex).toInt();
bool needsQuotes = stringDataTypes.contains(dataType);
// 处理数据类型及其长度精度
@ -633,9 +728,9 @@ QString projectModelDlg::combinePropertySql(const QStandardItem* pItem)
sql += QString(" DEFAULT %1").arg(defValue);
}
if (isPrimaryKey != 0) {
/*if (isPrimaryKey != 0) {
sql += " PRIMARY KEY";
}
}*/
return sql;
}
@ -665,3 +760,8 @@ void projectModelDlg::updateIconList()
}
}
}
void projectModelDlg::removeProjectData(const QString& sMeta,const QString& sProject)
{
m_mapTotal[sMeta].remove(sProject);
}

View File

@ -65,7 +65,8 @@ bool RenameModel::couldSave()
{
if(_pParent)
{
QString str = _pParent->getProjectName();
QString str = ui->lineEdit_name->text();
//QString str = _pParent->getProjectName();
if(str == QString::fromWCharArray(L"新建"))
{
ui->label_info->setText(QString::fromWCharArray(L"请输入需保存的名称"));

View File

@ -230,26 +230,6 @@ QWidget{
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="btn_generate">
<property name="text">
<string>生成</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>18</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="btn_save">
<property name="text">