diff --git a/include/sqlQueryExecutor.h b/include/sqlQueryExecutor.h index d8488e9..579671c 100644 --- a/include/sqlQueryExecutor.h +++ b/include/sqlQueryExecutor.h @@ -35,7 +35,8 @@ public: //属性相关 int getAttributeCount(const QString&, int, int); bool getAtrributeInfo(const QString&, const QString&, Attribute&); - bool batchInserAttributis(const QString&, int, int, QList); + bool batchInsertAttributes(const QString&, int, int, QList); + bool batchDeleteAttributes(const QString&, int, int, QList); signals: void errorOccurred(const QString& error); diff --git a/source/attributeTableModel.cpp b/source/attributeTableModel.cpp index 2b5644a..9e1430a 100644 --- a/source/attributeTableModel.cpp +++ b/source/attributeTableModel.cpp @@ -252,6 +252,7 @@ void AttributeTableModel::loadPageData() data.values.append(attribute.dataTypeID); data.values.append(attribute.dataLength); data.values.append(attribute.defaultValue); + data.values.append(attribute.id);//将id存入最后,不做显示,删除或者修改数据的时候会用到 m_currentPageData.append(data); } } @@ -398,10 +399,10 @@ void AttributeTableModel::removeRecord(int row) if(row < 0 || row > rowCount()) return; - emit showMessage(type_question, QString::fromWCharArray(L"提示"), + /*emit showMessage(type_question, QString::fromWCharArray(L"提示"), QString::fromWCharArray(L"确认要删除该记录吗?")); if(g_msgDlgBtn == btn_No) - return; + return;*/ int globalRow = (m_paginationInfo.currentPage - 1) * m_paginationInfo.entriesPerPage + row; @@ -428,9 +429,10 @@ void AttributeTableModel::removeRecord(int row) void AttributeTableModel::submitChanges() { QList insertRows = filterRowsByEditState(New); + bool insertCompleted = false; + QList deleteRows = filterRowsByEditState(Deleted); + bool deleteCompleted = false; // QList updateRows = filterRowsByEditState(Modified); - // QList deleteRows = filterRowsByEditState(Deleted); - bool insertResult = false; if(!insertRows.isEmpty()) { @@ -446,19 +448,34 @@ void AttributeTableModel::submitChanges() int dataLength = -1; if(rowData.values.value(3).isValid()) dataLength = rowData.values.value(3).toInt(); - QString defaultValue = rowData.values.value(4).toString(); + QString defaultValue = "null"; + if(rowData.values.value(4).isValid()) + defaultValue = rowData.values.value(4).toString(); insertAttributes.emplace_back(-1, name, type, dataTypeID, dataLength, defaultValue); } - insertResult = SqlQueryExecutor::instance().batchInserAttributis(m_connection, m_modelAttributeGroup.modelID, m_modelAttributeGroup.groupID, insertAttributes); + insertCompleted = SqlQueryExecutor::instance().batchInsertAttributes(m_connection, m_modelAttributeGroup.modelID, m_modelAttributeGroup.groupID, insertAttributes); } - if( (!insertRows.isEmpty() && insertResult) ) + if(!deleteRows.isEmpty()) { - m_modifiedRows.clear(); - refresh(); + QList deleteAttributes; + for(const RowData& rowData : deleteRows) + { + if(rowData.values.count() != m_displayField.count() + 1) //loadPageData时,会把属性id放到valuse的最后,并且不做展示 + continue; + + deleteAttributes.push_back(rowData.values.last().toInt()); + } + deleteCompleted = SqlQueryExecutor::instance().batchDeleteAttributes(m_connection, m_modelAttributeGroup.modelID, m_modelAttributeGroup.groupID, deleteAttributes); } - else + + if( (!insertRows.isEmpty() && !insertCompleted) && (!deleteRows.isEmpty() && !deleteCompleted) ) + { emit showMessage(type_warning, QString::fromWCharArray(L"错误"), QString::fromWCharArray(L"数据提交失败,详情可查看日志文件")); + } + + m_modifiedRows.clear(); + refresh(); } void AttributeTableModel::triggerSyncSignal() diff --git a/source/sqlQueryExecutor.cpp b/source/sqlQueryExecutor.cpp index d7e599d..9e23cfb 100644 --- a/source/sqlQueryExecutor.cpp +++ b/source/sqlQueryExecutor.cpp @@ -448,7 +448,7 @@ bool SqlQueryExecutor::getAtrributeInfo(const QString& connectionName, const QSt return true; } -bool SqlQueryExecutor::batchInserAttributis(const QString& connectionName, int modelID, int attributeGroupID, QList attributes) +bool SqlQueryExecutor::batchInsertAttributes(const QString& connectionName, int modelID, int attributeGroupID, QList attributes) { //属于批量操作,需要开启事务 QSqlDatabase db = QSqlDatabase::database(connectionName); @@ -486,7 +486,7 @@ bool SqlQueryExecutor::batchInserAttributis(const QString& connectionName, int m catch (const DatabaseException& e) { LOG_INFO("DB", QString("DB Rollback")); - if(!db.rollback()) // 回滚失败时记录警告 + if(!db.rollback()) // 回滚 { LOG_ERROR("DB", QString("Rollback failed. connectionName: %1. error: %2").arg(connectionName, db.lastError().databaseText())); } @@ -497,7 +497,15 @@ bool SqlQueryExecutor::batchInserAttributis(const QString& connectionName, int m //插入数据到关联表 QSqlQuery linkQuery(db); QString strSQL = "INSERT INTO basic.model_attribute (model_type_id, attribute_group_id, attribute_id) VALUES (?, ?, ?)"; - linkQuery.prepare(strSQL); + if(!linkQuery.prepare(strSQL)) + { + LOG_ERROR("SQL", QString("SQL '%1' prepare fialed. error: %2").arg(strSQL, linkQuery.lastError().databaseText())); + if(!db.rollback()) // 回滚 + { + LOG_ERROR("DB", QString("Rollback failed. connectionName: %1. error: %2").arg(connectionName, db.lastError().databaseText())); + } + return false; + } QVariantList modelIds, groupIds, attributeIds; for(const qint64& attributeID : attributeIDList) { @@ -512,7 +520,64 @@ bool SqlQueryExecutor::batchInserAttributis(const QString& connectionName, int m { LOG_ERROR("SQL", QString("SQL '%1' execBatch error: %2").arg(strSQL, linkQuery.lastError().databaseText())); LOG_INFO("DB", QString("DB Rollback")); - if(!db.rollback()) // 回滚失败时记录警告 + if(!db.rollback()) // 回滚 + { + LOG_ERROR("DB", QString("Rollback failed. connectionName: %1. error: %2").arg(connectionName, db.lastError().databaseText())); + } + return false; + } + + if(!db.commit()) // 提交 + { + LOG_ERROR("DB", QString("Commit transaction failed. connectionName: %1. error: %2").arg(connectionName, db.lastError().databaseText())); + return false; + } + + return true; +} + +bool SqlQueryExecutor::batchDeleteAttributes(const QString& connectionName, int modelID, int attributeGroupID, QList attributes) +{ + //属于批量操作,需要开启事务 + QSqlDatabase db = QSqlDatabase::database(connectionName); + if(!db.isOpen()) + { + LOG_ERROR("DB", QString("Database not open. connectionName: %1").arg(connectionName)); + return false; + } + + if(!db.transaction()) + { + LOG_ERROR("DB", QString("Start transaction failed. connectionName: %1. error: %2").arg(connectionName, db.lastError().databaseText())); + return false; + } + + QSqlQuery query(db); + QString strSQL = "DELETE FROM basic.model_attribute WHERE model_type_id = ? AND attribute_group_id = ? AND attribute_id = ?"; + if(!query.prepare(strSQL)) + { + LOG_ERROR("SQL", QString("SQL '%1' prepare fialed. error: %2").arg(strSQL, query.lastError().databaseText())); + if(!db.rollback()) // 回滚 + { + LOG_ERROR("DB", QString("Rollback failed. connectionName: %1. error: %2").arg(connectionName, db.lastError().databaseText())); + } + return false; + } + QVariantList modelIds, groupIds, attributeIds; + for(const int& attributeID : attributes) + { + modelIds << modelID; + groupIds << attributeGroupID; + attributeIds << attributeID; + } + query.addBindValue(modelIds); + query.addBindValue(groupIds); + query.addBindValue(attributeIds); + if( !query.execBatch() ) + { + LOG_ERROR("SQL", QString("SQL '%1' execBatch error: %2").arg(strSQL, query.lastError().databaseText())); + LOG_INFO("DB", QString("DB Rollback")); + if(!db.rollback()) // 回滚 { LOG_ERROR("DB", QString("Rollback failed. connectionName: %1. error: %2").arg(connectionName, db.lastError().databaseText())); }