mirror of https://gitee.com/bigwinds/arangodb
SingleServer INSERT babies now uses newest format. It tries to insert as much as possible. Reports each document individually. Also reports each error individually. The ordering of documents in request and response is identical.
This commit is contained in:
parent
489d6c5400
commit
a968446820
|
@ -121,6 +121,7 @@ bool RestDocumentHandler::createDocument() {
|
|||
SingleCollectionTransaction trx(transactionContext,
|
||||
collectionName, TRI_TRANSACTION_WRITE);
|
||||
VPackSlice body = parsedBody->slice();
|
||||
bool isMultiple = body.isArray();
|
||||
if (!body.isArray()) {
|
||||
trx.addHint(TRI_TRANSACTION_HINT_SINGLE_OPERATION, false);
|
||||
}
|
||||
|
@ -150,6 +151,16 @@ bool RestDocumentHandler::createDocument() {
|
|||
}
|
||||
|
||||
generateSaved(result, collectionName, TRI_col_type_e(trx.getCollectionType(collectionName)), transactionContext->getVPackOptions());
|
||||
|
||||
if (isMultiple && !result.countErrorCodes.empty()) {
|
||||
VPackBuilder errorBuilder;
|
||||
errorBuilder.openObject();
|
||||
for (auto const& it : result.countErrorCodes) {
|
||||
errorBuilder.add(basics::StringUtils::itoa(it.first), VPackValue(it.second));
|
||||
}
|
||||
errorBuilder.close();
|
||||
_response->setHeader("x-arango-error-codes", errorBuilder.slice().toJson());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -120,6 +120,26 @@ static OperationResult DBServerResponseBad(std::string const& resultBody) {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Insert an errror reported instead of the new document
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void createBabiesError(VPackBuilder& builder,
|
||||
std::unordered_map<int, size_t>& countErrorCodes,
|
||||
int errorCode) {
|
||||
builder.openObject();
|
||||
builder.add("error", VPackValue(true));
|
||||
builder.add("errorNum", VPackValue(errorCode));
|
||||
builder.close();
|
||||
|
||||
auto it = countErrorCodes.find(errorCode);
|
||||
if (it == countErrorCodes.end()) {
|
||||
countErrorCodes.emplace(errorCode, 1);
|
||||
} else {
|
||||
it->second++;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief sort ORs for the same attribute so they are in ascending value
|
||||
/// order. this will only work if the condition is for a single attribute
|
||||
|
@ -1234,20 +1254,23 @@ OperationResult Transaction::insertLocal(std::string const& collectionName,
|
|||
};
|
||||
|
||||
int res = TRI_ERROR_NO_ERROR;
|
||||
std::unordered_map<int, size_t> countErrorCodes;
|
||||
if (value.isArray()) {
|
||||
VPackArrayBuilder b(&resultBuilder);
|
||||
for (auto const& s : VPackArrayIterator(value)) {
|
||||
res = workForOneDocument(s);
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
break;
|
||||
createBabiesError(resultBuilder, countErrorCodes, res);
|
||||
}
|
||||
}
|
||||
// With babies the reporting is handled somewhere else.
|
||||
res = TRI_ERROR_NO_ERROR;
|
||||
} else {
|
||||
res = workForOneDocument(value);
|
||||
}
|
||||
|
||||
return OperationResult(resultBuilder.steal(), nullptr, "", res,
|
||||
options.waitForSync);
|
||||
options.waitForSync, countErrorCodes);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
|
Loading…
Reference in New Issue