diff --git a/arangod/RestHandler/RestDocumentHandler.cpp b/arangod/RestHandler/RestDocumentHandler.cpp index 9c372031c0..b7ff0f133f 100644 --- a/arangod/RestHandler/RestDocumentHandler.cpp +++ b/arangod/RestHandler/RestDocumentHandler.cpp @@ -549,6 +549,9 @@ bool RestDocumentHandler::modifyDocument(bool isPatch) { return false; } + // extract or chose the update policy + TRI_doc_update_policy_e const policy = extractUpdatePolicy(); + // extract or chose the update policy OperationOptions opOptions; opOptions.waitForSync = extractWaitForSync(); @@ -557,7 +560,7 @@ bool RestDocumentHandler::modifyDocument(bool isPatch) { { VPackObjectBuilder guard(&builder); builder.add(TRI_VOC_ATTRIBUTE_KEY, VPackValue(key)); - if (revision != 0) { + if (revision != 0 && policy != TRI_DOC_UPDATE_LAST_WRITE) { builder.add(TRI_VOC_ATTRIBUTE_REV, VPackValue(revision)); } } @@ -697,22 +700,16 @@ bool RestDocumentHandler::deleteDocument() { "invalid revision number"); return false; } - - // extract or choose the update policy - TRI_doc_update_policy_e const policy = extractUpdatePolicy(); + OperationOptions opOptions; bool const waitForSync = extractWaitForSync(); + TRI_doc_update_policy_e const policy = extractUpdatePolicy(); if (policy == TRI_DOC_UPDATE_ILLEGAL) { generateError(HttpResponse::BAD, TRI_ERROR_HTTP_BAD_PARAMETER, "policy must be 'error' or 'last'"); return false; } - if (ServerState::instance()->isCoordinator()) { - return deleteDocumentCoordinator(collection, key, revision, policy, - waitForSync); - } - SingleCollectionWriteTransaction<1> trx(new StandaloneTransactionContext(), _vocbase, collection); @@ -726,34 +723,33 @@ bool RestDocumentHandler::deleteDocument() { return false; } - TRI_voc_cid_t const cid = trx.cid(); - // If we are a DBserver, we want to use the cluster-wide collection - // name for error reporting: - std::string collectionName = collection; - if (ServerState::instance()->isDBServer()) { - collectionName = trx.resolver()->getCollectionName(cid); + + VPackBuilder builder; + { + VPackObjectBuilder guard(&builder); + builder.add(TRI_VOC_ATTRIBUTE_KEY, VPackValue(key)); + if (revision != 0 && policy != TRI_DOC_UPDATE_LAST_WRITE) { + builder.add(TRI_VOC_ATTRIBUTE_REV, VPackValue(revision)); + } } + VPackSlice search = builder.slice(); - TRI_voc_rid_t rid = 0; - res = trx.remove(trx.trxCollection(), key, 0, policy, revision, &rid, waitForSync); + OperationResult result = trx.remove(collection, search, opOptions); - if (res == TRI_ERROR_NO_ERROR) { - res = trx.commit(); - } else { - trx.abort(); - } + res = trx.finish(result.code); - // ............................................................................. - // outside write transaction - // ............................................................................. - - if (res != TRI_ERROR_NO_ERROR) { - generateTransactionError(collectionName, res, (TRI_voc_key_t)key.c_str(), - rid); + if(!result.successful()) { + generateTransactionError(result); return false; } - generateDeleted(trx, cid, (TRI_voc_key_t)key.c_str(), rid); + if (res != TRI_ERROR_NO_ERROR) { + generateTransactionError(collection, res, (TRI_voc_key_t)key.c_str()); + return false; + } + + // TODO Fix Collection Type! + generateDeleted(result, collection, TRI_COL_TYPE_DOCUMENT); return true; } diff --git a/arangod/RestHandler/RestImportHandler.cpp b/arangod/RestHandler/RestImportHandler.cpp index 2976db0a24..f4e70069e3 100644 --- a/arangod/RestHandler/RestImportHandler.cpp +++ b/arangod/RestHandler/RestImportHandler.cpp @@ -389,11 +389,12 @@ bool RestImportHandler::createFromJson(std::string const& type) { TRI_document_collection_t* document = trx.documentCollection(); bool const isEdgeCollection = (document->_info.type() == TRI_COL_TYPE_EDGE); - trx.lockWrite(); - if (overwrite) { + OperationOptions truncateOpts; + truncateOpts.waitForSync = false; // truncate collection first - trx.truncate(trx.trxCollection(), false); + trx.truncate(collection, truncateOpts); + // Ignore the result ... } if (linewise) { @@ -641,11 +642,13 @@ bool RestImportHandler::createFromKeyValueList() { TRI_document_collection_t* document = trx.documentCollection(); bool const isEdgeCollection = (document->_info.type() == TRI_COL_TYPE_EDGE); - trx.lockWrite(); - if (overwrite) { + OperationOptions truncateOpts; + truncateOpts.waitForSync = false; + // truncate collection first + trx.truncate(collection, truncateOpts); + // Ignore the result ... // truncate collection first - trx.truncate(trx.trxCollection(), false); } size_t i = (size_t)lineNumber; diff --git a/arangod/RestHandler/RestVocbaseBaseHandler.cpp b/arangod/RestHandler/RestVocbaseBaseHandler.cpp index 0e2f517dea..e34caed470 100644 --- a/arangod/RestHandler/RestVocbaseBaseHandler.cpp +++ b/arangod/RestHandler/RestVocbaseBaseHandler.cpp @@ -132,46 +132,30 @@ RestVocbaseBaseHandler::~RestVocbaseBaseHandler() {} //////////////////////////////////////////////////////////////////////////////// void RestVocbaseBaseHandler::generateSaved( - arangodb::OperationResult const& result, - std::string const& collectionName, + arangodb::OperationResult const& result, std::string const& collectionName, TRI_col_type_e type) { - VPackSlice slice = result.slice(); - TRI_ASSERT(slice.isObject()); - if (result.wasSynchronous) { createResponse(rest::HttpResponse::ACCEPTED); } else { createResponse(rest::HttpResponse::CREATED); } - _response->setContentType("application/json; charset=utf-8"); - _response->setHeader("etag", 4, "\"" + slice.get(TRI_VOC_ATTRIBUTE_REV).copyString() + "\""); + generate20x(result, collectionName, type); +} - std::string escapedHandle(DocumentHelper::assembleDocumentId( - collectionName, slice.get(TRI_VOC_ATTRIBUTE_KEY).copyString(), true)); - if (_request->compatibility() < 10400L) { - // pre-1.4 location header (e.g. /_api/document/xyz) - _response->setHeader("location", 8, - std::string(DOCUMENT_PATH + "/" + escapedHandle)); +//////////////////////////////////////////////////////////////////////////////// +/// @brief Generate a result for successful delete +//////////////////////////////////////////////////////////////////////////////// + +void RestVocbaseBaseHandler::generateDeleted( + arangodb::OperationResult const& result, std::string const& collectionName, + TRI_col_type_e type) { + rest::HttpResponse::HttpResponseCode statusCode; + if (result.wasSynchronous) { + statusCode = rest::HttpResponse::OK; } else { - // 1.4+ location header (e.g. /_db/_system/_api/document/xyz) - if (type == TRI_COL_TYPE_EDGE) { - _response->setHeader("location", 8, - std::string("/_db/" + _request->databaseName() + - EDGE_PATH + "/" + escapedHandle)); - } else { - _response->setHeader("location", 8, - std::string("/_db/" + _request->databaseName() + - DOCUMENT_PATH + "/" + escapedHandle)); - } - } - VPackStringBufferAdapter buffer(_response->body().stringBuffer()); - VPackDumper dumper(&buffer); - try { - dumper.dump(slice); - } catch (...) { - generateError(HttpResponse::SERVER_ERROR, TRI_ERROR_INTERNAL, - "cannot generate output"); + statusCode = rest::HttpResponse::ACCEPTED; } + generate20x(result, collectionName, type); } //////////////////////////////////////////////////////////////////////////////// @@ -219,6 +203,7 @@ bool RestVocbaseBaseHandler::checkCreateCollection(std::string const& name, //////////////////////////////////////////////////////////////////////////////// /// @brief generates a HTTP 201 or 202 response +/// DEPRECATED //////////////////////////////////////////////////////////////////////////////// void RestVocbaseBaseHandler::generate20x( @@ -269,6 +254,48 @@ void RestVocbaseBaseHandler::generate20x( .appendText("\"}"); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief generates a HTTP 20x response +//////////////////////////////////////////////////////////////////////////////// + +void RestVocbaseBaseHandler::generate20x( + arangodb::OperationResult const& result, + std::string const& collectionName, + TRI_col_type_e type) { + + VPackSlice slice = result.slice(); + TRI_ASSERT(slice.isObject()); + _response->setContentType("application/json; charset=utf-8"); + _response->setHeader("etag", 4, "\"" + slice.get(TRI_VOC_ATTRIBUTE_REV).copyString() + "\""); + + std::string escapedHandle(DocumentHelper::assembleDocumentId( + collectionName, slice.get(TRI_VOC_ATTRIBUTE_KEY).copyString(), true)); + if (_request->compatibility() < 10400L) { + // pre-1.4 location header (e.g. /_api/document/xyz) + _response->setHeader("location", 8, + std::string(DOCUMENT_PATH + "/" + escapedHandle)); + } else { + // 1.4+ location header (e.g. /_db/_system/_api/document/xyz) + if (type == TRI_COL_TYPE_EDGE) { + _response->setHeader("location", 8, + std::string("/_db/" + _request->databaseName() + + EDGE_PATH + "/" + escapedHandle)); + } else { + _response->setHeader("location", 8, + std::string("/_db/" + _request->databaseName() + + DOCUMENT_PATH + "/" + escapedHandle)); + } + } + VPackStringBufferAdapter buffer(_response->body().stringBuffer()); + VPackDumper dumper(&buffer); + try { + dumper.dump(slice); + } catch (...) { + generateError(HttpResponse::SERVER_ERROR, TRI_ERROR_INTERNAL, + "cannot generate output"); + } +} + //////////////////////////////////////////////////////////////////////////////// /// @brief generates not implemented //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/RestHandler/RestVocbaseBaseHandler.h b/arangod/RestHandler/RestVocbaseBaseHandler.h index 3f702df8c8..0fc8ccaf5c 100644 --- a/arangod/RestHandler/RestVocbaseBaseHandler.h +++ b/arangod/RestHandler/RestVocbaseBaseHandler.h @@ -143,11 +143,19 @@ class RestVocbaseBaseHandler : public RestBaseHandler { ////////////////////////////////////////////////////////////////////////////// /// @brief generates a HTTP 201 or 202 response + /// DEPRECATED ////////////////////////////////////////////////////////////////////////////// void generate20x(rest::HttpResponse::HttpResponseCode, std::string const&, TRI_voc_key_t, TRI_voc_rid_t, TRI_col_type_e); + ////////////////////////////////////////////////////////////////////////////// + /// @brief generates a HTTP 201 or 202 response + ////////////////////////////////////////////////////////////////////////////// + + void generate20x(arangodb::OperationResult const&, std::string const&, + TRI_col_type_e); + ////////////////////////////////////////////////////////////////////////////// /// @brief generates ok message without content ////////////////////////////////////////////////////////////////////////////// @@ -193,6 +201,7 @@ class RestVocbaseBaseHandler : public RestBaseHandler { ////////////////////////////////////////////////////////////////////////////// /// @brief generates deleted message + /// DEPRECATED ////////////////////////////////////////////////////////////////////////////// void generateDeleted(arangodb::SingleCollectionWriteTransaction<1>& trx, @@ -210,6 +219,13 @@ class RestVocbaseBaseHandler : public RestBaseHandler { type); } + ////////////////////////////////////////////////////////////////////////////// + /// @brief generates deleted message + ////////////////////////////////////////////////////////////////////////////// + + void generateDeleted(arangodb::OperationResult const& result, + std::string const& collectionName, TRI_col_type_e type); + ////////////////////////////////////////////////////////////////////////////// /// @brief generates document not found error message, read transaction ////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/V8Server/v8-collection.cpp b/arangod/V8Server/v8-collection.cpp index 9a62d3646d..b194305c8b 100644 --- a/arangod/V8Server/v8-collection.cpp +++ b/arangod/V8Server/v8-collection.cpp @@ -2021,7 +2021,8 @@ static void JS_TruncateVocbaseCol( TRI_V8_TRY_CATCH_BEGIN(isolate); v8::HandleScope scope(isolate); - bool const forceSync = ExtractWaitForSync(args, 1); + OperationOptions opOptions; + opOptions.waitForSync = ExtractWaitForSync(args, 1); TRI_vocbase_col_t* collection = TRI_UnwrapClass(args.Holder(), WRP_VOCBASE_COL_TYPE); @@ -2030,22 +2031,22 @@ static void JS_TruncateVocbaseCol( TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } - TRI_THROW_SHARDING_COLLECTION_NOT_YET_IMPLEMENTED(collection); - SingleCollectionWriteTransaction trx( new V8TransactionContext(true), collection->_vocbase, collection->_cid); + int res = trx.begin(); if (res != TRI_ERROR_NO_ERROR) { TRI_V8_THROW_EXCEPTION(res); } - if (trx.orderDitch(trx.trxCollection()) == nullptr) { - TRI_V8_THROW_EXCEPTION_MEMORY(); - } + OperationResult result = trx.truncate(collection->_name, opOptions); - res = trx.truncate(trx.trxCollection(), forceSync); - res = trx.finish(res); + res = trx.finish(result.code); + + if (result.failed()) { + TRI_V8_THROW_EXCEPTION(result.code); + } if (res != TRI_ERROR_NO_ERROR) { TRI_V8_THROW_EXCEPTION(res);