1
0
Fork 0

Fix baby methods for documents in arangosh.

This commit is contained in:
Max Neunhoeffer 2016-03-18 02:05:19 +01:00
parent 20fb42afd5
commit d1c5c64d6b
8 changed files with 277 additions and 63 deletions

View File

@ -178,9 +178,10 @@ void RestCursorHandler::processQuery(VPackSlice const& slice) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
}
auto transactionContext = std::make_shared<StandaloneTransactionContext>(_vocbase);
arangodb::basics::VPackStringBufferAdapter bufferAdapter(
_response->body().stringBuffer());
VPackDumper dumper(&bufferAdapter);
VPackDumper dumper(&bufferAdapter, transactionContext->getVPackOptions());
dumper.dump(result.slice());
return;
}

View File

@ -337,7 +337,14 @@ bool RestDocumentHandler::checkDocument() {
/// @brief was docuBlock REST_DOCUMENT_REPLACE
////////////////////////////////////////////////////////////////////////////////
bool RestDocumentHandler::replaceDocument() { return modifyDocument(false); }
bool RestDocumentHandler::replaceDocument() {
bool found;
std::string value = _request->value("onlyget", found);
if (found) {
return readManyDocuments();
}
return modifyDocument(false);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief was docuBlock REST_DOCUMENT_UPDATE
@ -581,3 +588,59 @@ bool RestDocumentHandler::deleteDocument() {
return true;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief was docuBlock REST_DOCUMENT_READ_MANY
////////////////////////////////////////////////////////////////////////////////
bool RestDocumentHandler::readManyDocuments() {
std::vector<std::string> const& suffix = _request->suffix();
if (suffix.size() != 1) {
generateError(HttpResponse::BAD, TRI_ERROR_HTTP_BAD_PARAMETER,
"expecting PUT /_api/document/<collection> with a BODY");
return false;
}
// split the document reference
std::string const& collectionName = suffix[0];
OperationOptions opOptions;
opOptions.ignoreRevs = extractBooleanParameter("ignoreRevs", false);
auto transactionContext(StandaloneTransactionContext::Create(_vocbase));
SingleCollectionTransaction trx(transactionContext,
collectionName, TRI_TRANSACTION_READ);
// ...........................................................................
// inside read transaction
// ...........................................................................
int res = trx.begin();
if (res != TRI_ERROR_NO_ERROR) {
generateTransactionError(collectionName, res, "");
return false;
}
auto builderPtr = _request->toVelocyPack(transactionContext->getVPackOptions());
VPackSlice search = builderPtr->slice();
OperationResult result = trx.document(collectionName, search, opOptions);
res = trx.finish(result.code);
if (!result.successful()) {
generateTransactionError(result);
return false;
}
if (res != TRI_ERROR_NO_ERROR) {
generateTransactionError(collectionName, res, "");
return false;
}
generateDocument(result.slice(), true,
transactionContext->getVPackOptions());
return true;
}

View File

@ -67,6 +67,12 @@ class RestDocumentHandler : public RestVocbaseBaseHandler {
bool readSingleDocument(bool generateBody);
//////////////////////////////////////////////////////////////////////////////
/// @brief reads multiple documents
//////////////////////////////////////////////////////////////////////////////
bool readManyDocuments();
//////////////////////////////////////////////////////////////////////////////
/// @brief reads all documents
//////////////////////////////////////////////////////////////////////////////

View File

@ -30,6 +30,7 @@
#include "Basics/VPackStringBufferAdapter.h"
#include "Cluster/ServerState.h"
#include "Rest/HttpRequest.h"
#include "Utils/StandaloneTransactionContext.h"
#include "Utils/Transaction.h"
#include "VocBase/document-collection.h"
@ -292,7 +293,8 @@ void RestVocbaseBaseHandler::generatePreconditionFailed(
}
VPackStringBufferAdapter buffer(_response->body().stringBuffer());
VPackDumper dumper(&buffer);
auto transactionContext(StandaloneTransactionContext::Create(_vocbase));
VPackDumper dumper(&buffer, transactionContext->getVPackOptions());
try {
dumper.dump(builder.slice());
@ -408,6 +410,10 @@ void RestVocbaseBaseHandler::generateTransactionError(
generateError(HttpResponse::BAD, res, "invalid document key");
return;
case TRI_ERROR_ARANGO_DOCUMENT_HANDLE_BAD:
generateError(HttpResponse::BAD, res, "invalid document handle");
return;
case TRI_ERROR_ARANGO_INVALID_EDGE_ATTRIBUTE:
generateError(HttpResponse::BAD, res, "invalid edge attribute");
return;
@ -499,6 +505,10 @@ void RestVocbaseBaseHandler::generateTransactionError(
generateError(HttpResponse::BAD, result.code, "invalid document key");
return;
case TRI_ERROR_ARANGO_DOCUMENT_HANDLE_BAD:
generateError(HttpResponse::BAD, result.code, "invalid document handle");
return;
case TRI_ERROR_ARANGO_INVALID_EDGE_ATTRIBUTE:
generateError(HttpResponse::BAD, result.code, "invalid edge attribute");
return;

View File

@ -545,7 +545,12 @@ std::string Transaction::extractKey(VPackSlice const slice) {
return k.copyString();
}
if (slice.isString()) {
return slice.copyString();
std::string key = slice.copyString();
size_t pos = key.find('/');
if (pos != std::string::npos) {
key = key.substr(pos+1);
}
return key;
}
return "";
}
@ -968,7 +973,7 @@ OperationResult Transaction::documentLocal(std::string const& collectionName,
auto workOnOneDocument = [&](VPackSlice const value) -> int {
std::string key(Transaction::extractKey(value));
if (key.empty()) {
return TRI_ERROR_ARANGO_DOCUMENT_KEY_BAD;
return TRI_ERROR_ARANGO_DOCUMENT_HANDLE_BAD;
}
VPackSlice expectedRevision;
@ -1541,21 +1546,32 @@ OperationResult Transaction::removeLocal(std::string const& collectionName,
VPackBuilder resultBuilder;
auto workOnOneDocument = [&](VPackSlice const value) -> int {
auto workOnOneDocument = [&](VPackSlice value) -> int {
VPackSlice actualRevision;
TRI_doc_mptr_t previous;
std::string key;
std::shared_ptr<VPackBuilder> builder;
if (value.isString()) {
key = value.copyString();
size_t pos = key.find('/');
if (pos != std::string::npos) {
key = key.substr(pos+1);
builder = std::make_shared<VPackBuilder>();
builder->add(VPackValue(key));
value = builder->slice();
}
} else if (value.isObject()) {
key = value.get(TRI_VOC_ATTRIBUTE_KEY).copyString();
} else {
return TRI_ERROR_ARANGO_DOCUMENT_HANDLE_BAD;
}
int res = document->remove(this, value, options,
!isLocked(document, TRI_TRANSACTION_WRITE),
actualRevision, previous);
if (res != TRI_ERROR_NO_ERROR) {
if (res == TRI_ERROR_ARANGO_CONFLICT && !options.silent) {
std::string key;
if (value.isString()) {
key = value.copyString();
} else {
key = value.get(TRI_VOC_ATTRIBUTE_KEY).copyString();
}
buildDocumentIdentity(resultBuilder, cid, key,
actualRevision, VPackSlice(),
options.returnOld ? &previous : nullptr, nullptr);
@ -1564,12 +1580,6 @@ OperationResult Transaction::removeLocal(std::string const& collectionName,
}
if (!options.silent) {
std::string key;
if (value.isString()) {
key = value.copyString();
} else {
key = value.get(TRI_VOC_ATTRIBUTE_KEY).copyString();
}
buildDocumentIdentity(resultBuilder, cid, key,
actualRevision, VPackSlice(),
options.returnOld ? &previous : nullptr, nullptr);

View File

@ -2341,7 +2341,9 @@ TRI_voc_rid_t TRI_ExtractRevisionId(VPackSlice const slice) {
////////////////////////////////////////////////////////////////////////////////
VPackSlice TRI_ExtractRevisionIdAsSlice(VPackSlice const slice) {
TRI_ASSERT(slice.isObject());
if (!slice.isObject()) {
return VPackSlice();
}
return slice.get(TRI_VOC_ATTRIBUTE_REV);
}

View File

@ -789,23 +789,37 @@ ArangoCollection.prototype.document = function (id) {
var rev = null;
var requestResult;
if (typeof id === "object") {
if (id.hasOwnProperty("_rev")) {
rev = id._rev;
}
if (id.hasOwnProperty("_id")) {
id = id._id;
} else if (id.hasOwnProperty("_key")) {
id = id._key;
}
if (id === undefined || id === null) {
throw new ArangoError({
errorNum : internal.errors.ERROR_ARANGO_DOCUMENT_HANDLE_BAD.code,
errorMessage : internal.errors.ERROR_ARANGO_DOCUMENT_HANDLE_BAD.message
});
}
if (rev === null) {
requestResult = this._database._connection.GET(this._documenturl(id));
}
else {
requestResult = this._database._connection.GET(this._documenturl(id),
{'if-match' : JSON.stringify(rev) });
var url;
if (Array.isArray(id)) {
url = this._documentcollectionurl() + "?onlyget=true&ignoreRevs=false";
var body = JSON.stringify(id);
requestResult = this._database._connection.PUT(url, body);
} else {
if (typeof id === "object") {
if (id.hasOwnProperty("_rev")) {
rev = id._rev;
}
if (id.hasOwnProperty("_id")) {
id = id._id;
} else if (id.hasOwnProperty("_key")) {
id = id._key;
}
}
url = this._documenturl(id);
if (rev === null) {
requestResult = this._database._connection.GET(this._documenturl(id));
}
else {
requestResult = this._database._connection.GET(this._documenturl(id),
{'if-match' : JSON.stringify(rev) });
}
}
if (requestResult !== null && requestResult.error === true) {
@ -1034,12 +1048,13 @@ ArangoCollection.prototype.remove = function (id, overwrite, waitForSync) {
}
var url;
var body = "";
if (Array.isArray(id)) {
url = this._documentcollectionurl();
body = JSON.stringify(id);
} else {
if (typeof id === "object")
if (typeof id === "object") {
if (id.hasOwnProperty("_rev")) {
rev = id._rev;
}
@ -1048,6 +1063,7 @@ ArangoCollection.prototype.remove = function (id, overwrite, waitForSync) {
} else if (id.hasOwnProperty("_key")) {
id = id._key;
}
}
url = this._documenturl(id);
}
@ -1073,6 +1089,7 @@ ArangoCollection.prototype.remove = function (id, overwrite, waitForSync) {
return options.silent ? true :requestResult;
};
////////////////////////////////////////////////////////////////////////////////
/// @brief replaces a document in the collection
/// @param id the id of the document
@ -1084,29 +1101,72 @@ ArangoCollection.prototype.remove = function (id, overwrite, waitForSync) {
/// @example replace("example/996280832675", { a : 1, c : 2}, {waitForSync: false, overwrite: true})
////////////////////////////////////////////////////////////////////////////////
function fillInSpecial(id, data) {
var pos;
if (data === null || typeof data !== "object" || Array.isArray(data)) {
throw new ArangoError({
error : true,
errorCode : internal.errors.ERROR_ARANGO_DOCUMENT_TYPE_INVALID.code,
errorNum : internal.errors.ERROR_ARANGO_DOCUMENT_TYPE_INVALID.code,
errorMessage : internal.errors.ERROR_ARANGO_DOCUMENT_TYPE_INVALID.message
});
}
if (typeof id === "object" && id !== null && !Array.isArray(id)) {
if (id.hasOwnProperty("_rev")) {
data._rev = id._rev;
}
if (id.hasOwnProperty("_id")) {
data._id = id._id;
pos = id._id.indexOf("/");
if (pos >= 0) {
data._key = id._id.substr(pos+1);
} else {
delete data._key;
}
} else if (id.hasOwnProperty("_key")) {
data._key = id._key;
delete data._id;
} else {
throw new ArangoError({
error : true,
errorCode : internal.errors.ERROR_ARANGO_DOCUMENT_TYPE_INVALID.code,
errorNum : internal.errors.ERROR_ARANGO_DOCUMENT_TYPE_INVALID.code,
errorMessage : internal.errors.ERROR_ARANGO_DOCUMENT_TYPE_INVALID.message
});
}
} else if (typeof id === "string") {
delete data._rev;
pos = id.indexOf("/");
if (pos >= 0) {
data._id = id;
data._key = id.substr(pos+1);
} else {
data._key = id;
delete data._id;
}
} else {
throw new ArangoError({
error : true,
errorCode : internal.errors.ERROR_ARANGO_DOCUMENT_HANDLE_BAD.code,
errorNum : internal.errors.ERROR_ARANGO_DOCUMENT_HANDLE_BAD.code,
errorMessage : internal.errors.ERROR_ARANGO_DOCUMENT_HANDLE_BAD.message
});
}
}
ArangoCollection.prototype.replace = function (id, data, overwrite, waitForSync) {
var rev = null;
var requestResult;
if (id === undefined || id === null) {
throw new ArangoError({
error : true,
errorCode : internal.errors.ERROR_ARANGO_DOCUMENT_HANDLE_BAD.code,
errorNum : internal.errors.ERROR_ARANGO_DOCUMENT_HANDLE_BAD.code,
errorMessage : internal.errors.ERROR_ARANGO_DOCUMENT_HANDLE_BAD.message
});
}
if (typeof id === "object") {
if (id.hasOwnProperty("_rev")) {
rev = id._rev;
}
if (id.hasOwnProperty("_id")) {
id = id._id;
} else if (id.hasOwnProperty("_key")) {
id = id._key;
}
}
var params = "";
var ignoreRevs = false;
var options;
if (typeof overwrite === "object") {
@ -1127,11 +1187,38 @@ ArangoCollection.prototype.replace = function (id, data, overwrite, waitForSync)
}
options = {};
}
var url = this._documenturl(id);
var url;
if (Array.isArray(id)) {
if (!Array.isArray(data) || id.length !== data.length) {
throw new ArangoError({
error : true,
errorCode : internal.errors.ERROR_ARANGO_DOCUMENT_HANDLE_BAD.code,
errorNum : internal.errors.ERROR_ARANGO_DOCUMENT_TYPE_INVALID.code,
errorMessage : internal.errors.ERROR_ARANGO_DOCUMENT_TYPE_INVALID.message
});
}
for (var i = 0; i < id.length; i++) {
fillInSpecial(id[i], data[i]);
}
url = this._documentcollectionurl();
} else if (typeof id === "object") {
if (id.hasOwnProperty("_rev")) {
rev = id._rev;
}
if (id.hasOwnProperty("_id")) {
id = id._id;
} else if (id.hasOwnProperty("_key")) {
id = id._key;
}
url = this._documenturl(id);
}
url = this._appendSyncParameter(url, waitForSync);
url = this._appendBoolParameter(url, "ignoreRevs", true);
url = this._appendBoolParameter(url, "ignoreRevs", ignoreRevs);
url = this._appendBoolParameter(url, "returnOld", options.returnOld);
url = this._appendBoolParameter(url, "returnNew", options.returnNew);
if (rev === null || ignoreRevs) {
requestResult = this._database._connection.PUT(url, JSON.stringify(data));
}
@ -1175,17 +1262,6 @@ ArangoCollection.prototype.update = function (id, data, overwrite, keepNull, wai
});
}
if (typeof id === "object") {
if (id.hasOwnProperty("_rev")) {
rev = id._rev;
}
if (id.hasOwnProperty("_id")) {
id = id._id;
} else if (id.hasOwnProperty("_key")) {
id = id._key;
}
}
var params = "";
var ignoreRevs = false;
var options;
@ -1223,9 +1299,32 @@ ArangoCollection.prototype.update = function (id, data, overwrite, keepNull, wai
}
var url = this._documenturl(id) + params;
var url;
if (Array.isArray(id)) {
if (!Array.isArray(data) || id.length !== data.length) {
throw new ArangoError({
errorNum : internal.errors.ERROR_ARANGO_DOCUMENT_TYPE_INVALID.code,
errorMessage : internal.errors.ERROR_ARANGO_DOCUMENT_TYPE_INVALID.message
});
}
for (var i = 0; i < id.length; i++) {
fillInSpecial(id[i], data[i]);
}
url = this._documentcollectionurl() + params;
} else if (typeof id === "object") {
if (id.hasOwnProperty("_rev")) {
rev = id._rev;
}
if (id.hasOwnProperty("_id")) {
id = id._id;
} else if (id.hasOwnProperty("_key")) {
id = id._key;
}
url = this._documenturl(id) + params;
}
url = this._appendSyncParameter(url, waitForSync);
url = this._appendBoolParameter(url, "ignoreRevs", true);
url = this._appendBoolParameter(url, "ignoreRevs", ignoreRevs);
url = this._appendBoolParameter(url, "returnOld", options.returnOld);
url = this._appendBoolParameter(url, "returnNew", options.returnNew);
@ -1426,4 +1525,3 @@ ArangoCollection.prototype.removeByKeys = function (keys) {
};
};

View File

@ -625,6 +625,14 @@ ArangoDatabase.prototype._remove = function (id, overwrite, waitForSync) {
var requestResult;
if (typeof id === "object") {
if (Array.isArray(id)) {
throw new ArangoError({
error: true,
code: internal.errors.ERROR_ARANGO_DOCUMENT_HANDLE_BAD.code,
errorNum: internal.errors.ERROR_ARANGO_DOCUMENT_HANDLE_BAD.code,
errorMessage: internal.errors.ERROR_ARANGO_DOCUMENT_HANDLE_BAD.message
});
}
if (id.hasOwnProperty("_rev")) {
rev = id._rev;
}
@ -689,6 +697,14 @@ ArangoDatabase.prototype._replace = function (id, data, overwrite, waitForSync)
var requestResult;
if (typeof id === "object") {
if (Array.isArray(id)) {
throw new ArangoError({
error: true,
code: internal.errors.ERROR_ARANGO_DOCUMENT_TYPE_INVALID.code,
errorNum: internal.errors.ERROR_ARANGO_DOCUMENT_TYPE_INVALID.code,
errorMessage: internal.errors.ERROR_ARANGO_DOCUMENT_TYPE_INVALID.message
});
}
if (id.hasOwnProperty("_rev")) {
rev = id._rev;
}
@ -753,6 +769,14 @@ ArangoDatabase.prototype._update = function (id, data, overwrite, keepNull, wait
var requestResult;
if (typeof id === "object") {
if (Array.isArray(id)) {
throw new ArangoError({
error: true,
code: internal.errors.ERROR_ARANGO_DOCUMENT_TYPE_INVALID.code,
errorNum: internal.errors.ERROR_ARANGO_DOCUMENT_TYPE_INVALID.code,
errorMessage: internal.errors.ERROR_ARANGO_DOCUMENT_TYPE_INVALID.message
});
}
if (id.hasOwnProperty("_rev")) {
rev = id._rev;
}