* @brief Patch any subset of dataset fields by groupId + datasetId; any applied field forces * the tree rebuild so the epoch-gated dashboard apply and editor reload fire. */
| 4965 | * the tree rebuild so the epoch-gated dashboard apply and editor reload fire. |
| 4966 | */ |
| 4967 | API::CommandResponse API::Handlers::ProjectHandler::datasetUpdate(const QString& id, |
| 4968 | const QJsonObject& params) |
| 4969 | { |
| 4970 | if (!params.contains(QStringLiteral("groupId"))) |
| 4971 | return CommandResponse::makeError( |
| 4972 | id, ErrorCode::MissingParam, QStringLiteral("Missing required parameter: groupId")); |
| 4973 | |
| 4974 | if (!params.contains(Keys::DatasetId)) |
| 4975 | return CommandResponse::makeError( |
| 4976 | id, ErrorCode::MissingParam, QStringLiteral("Missing required parameter: datasetId")); |
| 4977 | |
| 4978 | const int groupId = params.value(QStringLiteral("groupId")).toInt(); |
| 4979 | const int datasetId = params.value(Keys::DatasetId).toInt(); |
| 4980 | auto& project = DataModel::ProjectModel::instance(); |
| 4981 | const auto& groups = project.groups(); |
| 4982 | if (groupId < 0 || static_cast<size_t>(groupId) >= groups.size()) |
| 4983 | return CommandResponse::makeError( |
| 4984 | id, ErrorCode::InvalidParam, QStringLiteral("Group id not found: %1").arg(groupId)); |
| 4985 | |
| 4986 | const auto& datasets = groups[groupId].datasets; |
| 4987 | if (datasetId < 0 || static_cast<size_t>(datasetId) >= datasets.size()) |
| 4988 | return CommandResponse::makeError(id, |
| 4989 | ErrorCode::InvalidParam, |
| 4990 | QStringLiteral("Dataset id not found: %1 in group %2") |
| 4991 | .arg(QString::number(datasetId), QString::number(groupId))); |
| 4992 | |
| 4993 | DataModel::Dataset d = datasets[datasetId]; |
| 4994 | bool rebuildTree = false; |
| 4995 | QSet<QString> consumed{ |
| 4996 | QStringLiteral("groupId"), Keys::DatasetId, QStringLiteral("expectedProjectEpoch")}; |
| 4997 | const auto identityKeyCount = consumed.size(); |
| 4998 | const QString err = applyDatasetUpdateParams(d, params, rebuildTree, consumed); |
| 4999 | if (!err.isEmpty()) |
| 5000 | return CommandResponse::makeError(id, ErrorCode::InvalidParam, err); |
| 5001 | |
| 5002 | if (consumed.size() > identityKeyCount) |
| 5003 | rebuildTree = true; |
| 5004 | |
| 5005 | const auto preEpoch = captureProjectEpoch(); |
| 5006 | project.updateDataset(groupId, datasetId, d, rebuildTree); |
| 5007 | |
| 5008 | QJsonObject result; |
| 5009 | result[QStringLiteral("groupId")] = groupId; |
| 5010 | result[Keys::DatasetId] = datasetId; |
| 5011 | result[QStringLiteral("updated")] = true; |
| 5012 | |
| 5013 | appendUnknownFieldsWarning(result, params, consumed, QStringLiteral("project.dataset.update")); |
| 5014 | appendStaleProjectWarning(result, params, preEpoch); |
| 5015 | attachProjectEpoch(result); |
| 5016 | |
| 5017 | if (!d.transformCode.isEmpty() && d.transformLanguage != -1) { |
| 5018 | const auto warning = detectLanguageMismatch(d.transformCode, d.transformLanguage); |
| 5019 | if (!warning.isEmpty()) |
| 5020 | result[QStringLiteral("warning")] = warning; |
| 5021 | } |
| 5022 | |
| 5023 | if (!d.transformCode.isEmpty() && !d.virtual_ && d.index <= 0) |
| 5024 | result[QStringLiteral("hint")] = |
nothing calls this directly
no test coverage detected