1
0
Fork 0

Merge branch 'devel' of https://github.com/triAGENS/ArangoDB into mjmh

This commit is contained in:
Jan Steemann 2014-05-22 13:11:39 +02:00
commit ac7e73f6e7
7 changed files with 248 additions and 56 deletions

View File

@ -2170,6 +2170,15 @@ static v8::Handle<v8::Value> ModifyVocbaseColCoordinator (
return scope.Close(ret);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief internal struct which is used for reading the different option
/// parameters for the replace function
////////////////////////////////////////////////////////////////////////////////
struct ReplaceOptions {
bool overwrite = true;
bool waitForSync = false;
};
////////////////////////////////////////////////////////////////////////////////
/// @brief replaces a document
@ -2178,10 +2187,14 @@ static v8::Handle<v8::Value> ModifyVocbaseColCoordinator (
static v8::Handle<v8::Value> ReplaceVocbaseCol (bool useCollection,
v8::Arguments const& argv) {
v8::HandleScope scope;
ReplaceOptions options;
TRI_doc_update_policy_e policy = TRI_DOC_UPDATE_ERROR;
// check the arguments
if (argv.Length() < 2) {
TRI_V8_EXCEPTION_USAGE(scope, "replace(<document>, <data>, <overwrite>, <waitForSync>)");
TRI_V8_EXCEPTION_USAGE(scope, "replace(<document>, <data>, <overwrite>, <waitForSync>) or"
"replace(<document>, <data>, {overwrite: booleanValue, waitForSync: booleanValue})"
);
}
// we're only accepting "real" object documents
@ -2189,8 +2202,26 @@ static v8::Handle<v8::Value> ReplaceVocbaseCol (bool useCollection,
TRI_V8_EXCEPTION(scope, TRI_ERROR_ARANGO_DOCUMENT_TYPE_INVALID);
}
const TRI_doc_update_policy_e policy = ExtractUpdatePolicy(argv, 3);
const bool forceSync = ExtractForceSync(argv, 4);
if (argv.Length() > 2) {
if (argv[2]->IsObject()) {
v8::Handle<v8::Object> optionsObject = argv[2].As<v8::Object>();
if (optionsObject->Has(v8::String::New("overwrite"))) {
options.overwrite = TRI_ObjectToBoolean(optionsObject->Get(v8::String::New("overwrite")));
policy = ExtractUpdatePolicy(options.overwrite);
}
if (optionsObject->Has(v8::String::New("waitForSync"))) {
options.waitForSync = TRI_ObjectToBoolean(optionsObject->Get(v8::String::New("waitForSync")));
}
} else {// old variant replace(<document>, <data>, <overwrite>, <waitForSync>)
if (argv.Length() > 2 ) {
options.overwrite = TRI_ObjectToBoolean(argv[2]);
policy = ExtractUpdatePolicy(options.overwrite);
}
if (argv.Length() > 3 ) {
options.waitForSync = TRI_ObjectToBoolean(argv[3]);
}
}
}
TRI_voc_key_t key = 0;
TRI_voc_rid_t rid;
@ -2238,7 +2269,7 @@ static v8::Handle<v8::Value> ReplaceVocbaseCol (bool useCollection,
if (ServerState::instance()->isCoordinator()) {
return scope.Close(ModifyVocbaseColCoordinator(col,
policy,
forceSync,
options.waitForSync,
false, // isPatch
true, // keepNull, does not matter
argv));
@ -2309,7 +2340,7 @@ static v8::Handle<v8::Value> ReplaceVocbaseCol (bool useCollection,
TRI_V8_EXCEPTION_MESSAGE(scope, TRI_errno(), "<data> cannot be converted into JSON shape");
}
res = trx.updateDocument(key, &document, shaped, policy, forceSync, rid, &actualRevision);
res = trx.updateDocument(key, &document, shaped, policy, options.waitForSync, rid, &actualRevision);
res = trx.finish(res);
@ -7229,12 +7260,14 @@ static v8::Handle<v8::Value> JS_RenameVocbaseCol (v8::Arguments const& argv) {
/// If there is a conflict, i. e. if the revision of the @LIT{document} does not
/// match the revision in the collection, then an error is thrown.
///
/// @FUN{@FA{collection}.replace(@FA{document}, @FA{data}, true)}
/// @FUN{@FA{collection}.replace(@FA{document}, @FA{data}, true)} or
/// @FUN{@FA{collection}.replace(@FA{document}, @FA{data}, {@FA{overwrite}: true})}
///
/// As before, but in case of a conflict, the conflict is ignored and the old
/// document is overwritten.
///
/// @FUN{@FA{collection}.replace(@FA{document}, @FA{data}, true, @FA{waitForSync})}
/// @FUN{@FA{collection}.replace(@FA{document}, @FA{data}, true, @FA{waitForSync})} or
/// @FUN{@FA{collection}.replace(@FA{document}, @FA{data}, {@FA{overwrite}: true, @FA{waitForSync}: true or false})}
///
/// The optional @FA{waitForSync} parameter can be used to force
/// synchronisation of the document replacement operation to disk even in case
@ -7401,7 +7434,9 @@ static v8::Handle<v8::Value> JS_RotateVocbaseCol (v8::Arguments const& argv) {
////////////////////////////////////////////////////////////////////////////////
/// @brief updates a document
///
/// @FUN{@FA{collection}.update(@FA{document}, @FA{data}, @FA{overwrite}, @FA{keepNull}, @FA{waitForSync})}
/// @FUN{@FA{collection}.update(@FA{document}, @FA{data}, @FA{overwrite}, @FA{keepNull}, @FA{waitForSync})} or
/// @FUN{@FA{collection}.update(@FA{document}, @FA{data},
/// { @FA{overwrite} : true or false, @FA{keepNull} : true or false, @FA{waitForSync} : true or false})}
///
/// Updates an existing @FA{document}. The @FA{document} must be a document in
/// the current collection. This document is then patched with the

View File

@ -1158,15 +1158,23 @@ ArangoCollection.prototype.replace = function (id, data, overwrite, waitForSync)
id = id._id;
}
var policy = "";
if (overwrite) {
policy = "?policy=last";
var params = "";
if (typeof overwrite === "object") {
// we assume the caller uses new signature (id, data, options)
var options = overwrite;
if (options.hasOwnProperty("overwrite") && options.overwrite) {
params += "?policy=last";
}
var url = this._documenturl(id) + policy;
if (options.hasOwnProperty("waitForSync") ) {
waitForSync = options.waitForSync;
}
} else {
if (overwrite) {
params += "?policy=last";
}
}
var url = this._documenturl(id) + params;
url = this._appendSyncParameter(url, waitForSync);
if (rev === null) {
requestResult = this._database._connection.PUT(url, JSON.stringify(data));
}

View File

@ -705,13 +705,23 @@ ArangoDatabase.prototype._replace = function (id, data, overwrite, waitForSync)
id = id._id;
}
var policy = "";
var params = "";
if (overwrite) {
policy = "?policy=last";
if (typeof overwrite === "object") {
// we assume the caller uses new signature (id, data, options)
var options = overwrite;
if (options.hasOwnProperty("overwrite") && options.overwrite) {
params += "?policy=last";
}
var url = this._documenturl(id) + policy;
if (options.hasOwnProperty("waitForSync") ) {
waitForSync = options.waitForSync;
}
} else {
if (overwrite) {
params += "?policy=last";
}
}
var url = this._documenturl(id) + params;
url = this._appendSyncParameter(url, waitForSync);
if (rev === null) {

View File

@ -1157,15 +1157,23 @@ ArangoCollection.prototype.replace = function (id, data, overwrite, waitForSync)
id = id._id;
}
var policy = "";
if (overwrite) {
policy = "?policy=last";
var params = "";
if (typeof overwrite === "object") {
// we assume the caller uses new signature (id, data, options)
var options = overwrite;
if (options.hasOwnProperty("overwrite") && options.overwrite) {
params += "?policy=last";
}
var url = this._documenturl(id) + policy;
if (options.hasOwnProperty("waitForSync") ) {
waitForSync = options.waitForSync;
}
} else {
if (overwrite) {
params += "?policy=last";
}
}
var url = this._documenturl(id) + params;
url = this._appendSyncParameter(url, waitForSync);
if (rev === null) {
requestResult = this._database._connection.PUT(url, JSON.stringify(data));
}

View File

@ -704,13 +704,23 @@ ArangoDatabase.prototype._replace = function (id, data, overwrite, waitForSync)
id = id._id;
}
var policy = "";
var params = "";
if (overwrite) {
policy = "?policy=last";
if (typeof overwrite === "object") {
// we assume the caller uses new signature (id, data, options)
var options = overwrite;
if (options.hasOwnProperty("overwrite") && options.overwrite) {
params += "?policy=last";
}
var url = this._documenturl(id) + policy;
if (options.hasOwnProperty("waitForSync") ) {
waitForSync = options.waitForSync;
}
} else {
if (overwrite) {
params += "?policy=last";
}
}
var url = this._documenturl(id) + params;
url = this._appendSyncParameter(url, waitForSync);
if (rev === null) {

View File

@ -713,6 +713,48 @@ function CollectionDocumentSuite () {
assertEqual(4, doc4.a);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief tests the replace function with the new signature
////////////////////////////////////////////////////////////////////////////////
testReplaceWithNewSignatureDocument : function () {
var a1 = collection.save({ a : 1});
assertTypeOf("string", a1._id);
assertTypeOf("string", a1._rev);
// important test, the server has to compute the overwrite policy in correct wise
var a2 = collection.replace(a1, { a : 2 });
assertEqual(a1._id, a2._id);
assertNotEqual(a1._rev, a2._rev);
try {
collection.replace(a1, { a : 3 });
fail();
}
catch (err) {
assertEqual(ERRORS.ERROR_ARANGO_CONFLICT.code, err.errorNum);
}
var doc2 = collection.document(a1._id);
assertEqual(a1._id, doc2._id);
assertEqual(a2._rev, doc2._rev);
assertEqual(2, doc2.a);
// new signature
var a4 = collection.replace(a1, { a : 4 }, {"overwrite" : true});
assertEqual(a1._id, a4._id);
assertNotEqual(a1._rev, a4._rev);
assertNotEqual(a2._rev, a4._rev);
var doc4 = collection.document(a1._id);
assertEqual(a1._id, doc4._id);
assertEqual(a4._rev, doc4._rev);
assertEqual(4, doc4.a);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief replace a document, waitForSync=false
////////////////////////////////////////////////////////////////////////////////
@ -725,6 +767,21 @@ function CollectionDocumentSuite () {
var a2 = collection.replace(a1, { a : 2 }, true, false);
assertEqual(a1._id, a2._id);
assertNotEqual(a1._rev, a2._rev);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief tests the replace function with new signature
////////////////////////////////////////////////////////////////////////////////
testReplaceWithNewSignatureDocumentSyncFalse : function () {
var a1 = collection.save({ a : 1});
assertTypeOf("string", a1._id);
assertTypeOf("string", a1._rev);
var a2 = collection.replace(a1, { a : 2 }, {"overwrite": true, "waitForSync": false});
assertEqual(a1._id, a2._id);
assertNotEqual(a1._rev, a2._rev);
},
@ -745,6 +802,22 @@ function CollectionDocumentSuite () {
assertNotEqual(a1._rev, a2._rev);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief tests the replace function with new signature
////////////////////////////////////////////////////////////////////////////////
testReplaceDocumentSyncTrue : function () {
var a1 = collection.save({ a : 1});
assertTypeOf("string", a1._id);
assertTypeOf("string", a1._rev);
var a2 = collection.replace(a1, { a : 2 }, {"overwrite": true, "waitForSync": true});
assertEqual(a1._id, a2._id);
assertNotEqual(a1._rev, a2._rev);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief update a document
////////////////////////////////////////////////////////////////////////////////
@ -1407,6 +1480,47 @@ function DatabaseDocumentSuite () {
var doc4 = db._document(a1._id);
assertEqual(a1._id, doc4._id);
assertEqual(a4._rev, doc4._rev);
assertEqual(4, doc4.a);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief tests the _replace function with new signature
////////////////////////////////////////////////////////////////////////////////
test_ReplaceWithNewSignatureDocument : function () {
var a1 = collection.save({ a : 1});
assertTypeOf("string", a1._id);
assertTypeOf("string", a1._rev);
var a2 = db._replace(a1, { a : 2 });
assertEqual(a1._id, a2._id);
assertNotEqual(a1._rev, a2._rev);
try {
db._replace(a1, { a : 3 });
fail();
}
catch (err) {
assertEqual(ERRORS.ERROR_ARANGO_CONFLICT.code, err.errorNum);
}
var doc2 = db._document(a1._id);
assertEqual(a1._id, doc2._id);
assertEqual(a2._rev, doc2._rev);
assertEqual(2, doc2.a);
var a4 = db._replace(a1, { a : 4 }, {"overwrite": true});
assertEqual(a1._id, a4._id);
assertNotEqual(a1._rev, a4._rev);
assertNotEqual(a2._rev, a4._rev);
var doc4 = db._document(a1._id);
assertEqual(a1._id, doc4._id);
assertEqual(a4._rev, doc4._rev);
assertEqual(4, doc4.a);

View File

@ -599,7 +599,8 @@ function GeneralGraphAQLQueriesSuite() {
fail();
} catch (err) {
assertEqual(err.errorNum, ERRORS.ERROR_BAD_PARAMETER.code);
assertEqual(err.errorMessage, "edge collections: failed and unknown and foxxle are not known to the graph");
assertEqual(err.errorMessage,
"edge collections: failed and unknown and foxxle are not known to the graph");
}
},
@ -750,32 +751,38 @@ function GeneralGraphAQLQueriesSuite() {
assertFalse(findIdInResult(result, e3), "e3 is not excluded");
}
////////////////////////////////////////////////////////////////////////////////
/// @brief test: let construct on edges
////////////////////////////////////////////////////////////////////////////////
};
/* Broken string replacement
test_letOnEdges: function() {
var query = g._edges("v1/1").let("myVal = e.val");
assertEqual(query.printQuery(), "FOR edges_0 IN GRAPH_EDGES("
+ "@graphName,@startVertex_0,any) LET myVal = edges_0.val");
var bindVars = query.bindVars;
assertEqual(bindVars.graphName, "graph");
assertEqual(bindVars.startVertex_0, "v1/1");
*/
/*
var result = query.toArray();
assertEqual(result.length, 1);
assertTrue(findIdInResult(result, e3));
assertFalse(findIdInResult(result, e1));
assertFalse(findIdInResult(result, e2));
*/
/*
}
*/
function ChainedFluentAQLResultsSuite() {
var gn = "UnitTestGraph";
var g;
var edgeDef = [];
var createTestData = function() {
g = graph._create(gn, edgeDef);
};
var dropData = function() {
graph._drop(gn);
};
return {
setUp: function() {
},
tearDown: dropData
};
}
function EdgesAndVerticesSuite() {