1
0
Fork 0

Merge branch 'devel' of ssh://github.com/triAGENS/ArangoDB into aql-feature-optimize-or

This commit is contained in:
James 2014-11-02 18:05:35 +00:00
commit 901c65559c
23 changed files with 749 additions and 195 deletions

View File

@ -1,6 +1,16 @@
v2.3.0 (XXXX-XX-XX) v2.3.0 (XXXX-XX-XX)
------------------- -------------------
* added command-line option `--javascript.v8-contexts` to control the number of
V8 contexts created in arangod.
Previously, the number of V8 contexts was equal to the number of server threads
(as specified by option `--server.threads`). However, it may be sensible to
create different amounts of threads and V8 contexts. If the option is not
specified, the number of V8 contexts created will be equal to the number of
server threads. Thus no change in configuration is required to keep the old
behavior.
* removed bitarray indexes * removed bitarray indexes
* removed internal "_admin/modules/flush" in order to fix requireApp * removed internal "_admin/modules/flush" in order to fix requireApp

View File

@ -8,7 +8,7 @@ You can use this to define your own extra variables and functions that you need
For example, you could put the following into the *.arangosh.rc* file in your home For example, you could put the following into the *.arangosh.rc* file in your home
directory: directory:
``` ```js
// var keyword omitted intentionally, // var keyword omitted intentionally,
// otherwise "timed" would not survive the scope of this script // otherwise "timed" would not survive the scope of this script
timed = function (cb) { timed = function (cb) {
@ -23,7 +23,7 @@ This will make a function named *timed* available in _arangosh_ in the global sc
You can now start _arangosh_ and invoke the function like this: You can now start _arangosh_ and invoke the function like this:
``` ```js
timed(function () { timed(function () {
for (var i = 0; i < 1000; ++i) { for (var i = 0; i < 1000; ++i) {
db.test.save({ value: i }); db.test.save({ value: i });

View File

@ -36,6 +36,10 @@
@startDocuBlock serverAllowMethod @startDocuBlock serverAllowMethod
!SUBSECTION Server threads
@startDocuBlock serverThreads
!SUBSECTION Keyfile !SUBSECTION Keyfile
@startDocuBlock serverKeyfile @startDocuBlock serverKeyfile
@ -64,12 +68,12 @@
@startDocuBlock serverBacklog @startDocuBlock serverBacklog
!SUBSECTION Disable statics !SUBSECTION Disable statistics
`--disable-statistics value` `--disable-statistics value`
If this option is *value* is *true*, then ArangoDB's statistics gathering If this option is *value* is *true*, then ArangoDB's statistics gathering
is turned off. Statistics gathering causes constant CPU activity so using this is turned off. Statistics gathering causes regular CPU activity so using this
option to turn it off might relieve heavy-loaded instances. option to turn it off might relieve heavy-loaded instances.
Note: this option is only available when ArangoDB has not been compiled with Note: this option is only available when ArangoDB has not been compiled with
the option *--disable-figures*. the option *--disable-figures*.
@ -90,6 +94,10 @@ the option *--disable-figures*.
@startDocuBlock databaseForceSyncProperties @startDocuBlock databaseForceSyncProperties
!SUBSECTION V8 Contexts
@startDocuBlock v8Contexts
!SUBSECTION Frequency !SUBSECTION Frequency
@startDocuBlock jsGcFrequency @startDocuBlock jsGcFrequency

View File

@ -1,17 +1,17 @@
!CHAPTER Command-Line Options for Communication !CHAPTER Command-Line Options for Communication
!SUBSECTION Scheduler threads !SUBSECTION Scheduler threads
<!-- lib/Scheduler/ApplicationScheduler.h -->
@startDocuBlock schedulerThreads @startDocuBlock schedulerThreads
!SUBSECTION Scheduler maximal queue size !SUBSECTION Scheduler maximal queue size
<!-- arangod/RestServer/ArangoServer.h --> @startDocuBlock schedulerMaximalQueueSize
@startDocuBlock serverAuthenticationDisable
!SUBSECTION Scheduler backend !SUBSECTION Scheduler backend
<!-- lib/Scheduler/ApplicationScheduler.h -->
@startDocuBlock schedulerBackend @startDocuBlock schedulerBackend
!SUBSECTION Io backends !SUBSECTION Io backends
`--show-io-backends` `--show-io-backends`

View File

@ -2,7 +2,7 @@
!SUBSECTION In Case Of Disaster !SUBSECTION In Case Of Disaster
The following command starts a emergency console. The following command starts an emergency console.
**Note**: Never start the emergency console for a database which also has a **Note**: Never start the emergency console for a database which also has a
server attached to it. In general the ArangoDB shell is what you want. server attached to it. In general the ArangoDB shell is what you want.
@ -14,18 +14,16 @@ ArangoDB shell [V8 version 3.9.4, DB version 1.x.y]
arango> 1 + 2; arango> 1 + 2;
3 3
arango> db.geo.count(); arango> var db = require("org/arangodb").db; db.geo.count();
703 703
``` ```
The emergency console disables the HTTP interface of the server and The emergency console provides a JavaScript console directly running in the
opens a JavaScript console on standard output instead. This allows you arangod server process. This allows to debug and examine collections and
to debug and examine collections and documents without interference documents as with the normal ArangoDB shell, but without client/server
from the outside. In most respects the emergency console behaves like communication.
the normal ArangoDB shell - but with exclusive access and no
client/server communication.
However, it is very likely that you never need the emergency console However, it is very likely that you will never need the emergency console
unless you are an ArangoDB developer. unless you are an ArangoDB developer.

View File

@ -1,4 +0,0 @@
!SUBSECTION Command-Line Options for Random Numbers
<!-- lib/ApplicationServer/ApplicationServer.h -->
@startDocuBlock randomGenerator

View File

@ -138,14 +138,13 @@
* [Authentication](Sharding/Authentication.md) * [Authentication](Sharding/Authentication.md)
* [Firewall setup](Sharding/FirewallSetup.md) * [Firewall setup](Sharding/FirewallSetup.md)
<!-- 20 --> <!-- 20 -->
* [Configure ArangoDB](ConfigureArango/README.md) * [Server Configuration](ConfigureArango/README.md)
* [Arangod options](ConfigureArango/Arangod.md) * [Arangod options](ConfigureArango/Arangod.md)
* [Write-ahead log options](ConfigureArango/Wal.md) * [Write-ahead log options](ConfigureArango/Wal.md)
* [Endpoints options](ConfigureArango/Endpoint.md) * [Endpoints options](ConfigureArango/Endpoint.md)
* [Cluster options](ConfigureArango/Cluster.md) * [Cluster options](ConfigureArango/Cluster.md)
* [Logging options](ConfigureArango/Logging.md) * [Logging options](ConfigureArango/Logging.md)
* [Communication options](ConfigureArango/Communication.md) * [Communication options](ConfigureArango/Communication.md)
* [Random numbers](ConfigureArango/RandomNumbers.md)
* [Authentication](ConfigureArango/Authentication.md) * [Authentication](ConfigureArango/Authentication.md)
* [Emergency Console](ConfigureArango/EmergencyConsole.md) * [Emergency Console](ConfigureArango/EmergencyConsole.md)
<!-- 21 --> <!-- 21 -->

View File

@ -40,22 +40,28 @@ For Mac OSX users: execute
For Windows and Linux users: use the installer script or distribution package For Windows and Linux users: use the installer script or distribution package
from our [download page](http://www.arangodb.com/download). from our [download page](http://www.arangodb.com/download).
If the package manager has not already started the ArangoDB server, use If the package manager has not already started the ArangoDB server, use the
following command to start it.
unix> /path/to/sbin/arangod unix> /path/to/sbin/arangod
2012-03-30T12:54:19Z [11794] INFO ArangoDB (version 2.x.y) is ready for business 2012-03-30T12:54:19Z [11794] INFO ArangoDB (version 2.x.y) is ready for business
2012-03-30T12:54:19Z [11794] INFO Have Fun! 2012-03-30T12:54:19Z [11794] INFO Have Fun!
`/path/to/sbin` is OS dependent. It will normally by either `/usr/sbin` or `/user/local/sbin`. Point your browser to `/path/to/sbin` is OS dependent. It will normally be either `/usr/sbin` or `/user/local/sbin`.
To access ArangoDB in your browser, open the following URL
http://localhost:8529/ http://localhost:8529/
and select `Tools / JS Shell`. You can now use the Arango shell from within your browser. Alternative, it is available as command-line tool _arangosh_. and select `Tools / JS Shell`. You can now use the Arango shell from within your browser.
Alternatively, a scriptable shell is available as a command-line tool _arangosh_.
arangosh> db._create("hello"); arangosh> db._create("hello");
arangosh> db.hello.save({ world: "earth" }); arangosh> db.hello.save({ world: "earth" });
Congratulations! You have created your first collection called `hello` and your first document. To verify your achievements, type: Congratulations! You have created your first collection named `hello` and your first document.
To verify your achievements, type:
arangosh> db.hello.toArray(); arangosh> db.hello.toArray();
@ -64,15 +70,15 @@ More Information
---------------- ----------------
Please check the Please check the
[Installation Manual](http://www.arangodb.com/manuals/current/InstallManual.html) [Installation Manual](https://www.arangodb.com/Installing/README.html)
for installation and compilation instructions. for installation and compilation instructions.
The The
[User Manual](http://www.arangodb.com/manuals/current/UserManual.html) [User Manual](https://www.arangodb.com/FirstSteps/README.html)
has an introductory chapter showing the basic operations of ArangoDB. has an introductory chapter showing the basic operations of ArangoDB.
Or you can use the Or you can use the
[online tutorial](http://www.arangodb.com/try) [online tutorial](https://www.arangodb.com/tryitout)
to play with ArangoDB without installing it locally. to play with ArangoDB without installing it locally.
@ -86,7 +92,7 @@ you report them:
You can use the Google group for improvements, feature requests, comments You can use the Google group for improvements, feature requests, comments
[http://www.arangodb.com/community](http://www.arangodb.com/community) [http://www.arangodb.com/community](https://www.arangodb.com/community)
Citing ArangoDB Citing ArangoDB
@ -96,7 +102,7 @@ Please kindly cite ArangoDB in your publications if it helps your research:
```bibtex ```bibtex
@misc{ArangoDB2014, @misc{ArangoDB2014,
Author = {ArangoDB}, Author = {ArangoDB},
Title = { {ArangoDB 2.2}: An Open Source multi-purpose database supporting flexible data models for documents, graphs, and key-values.}, Title = { {ArangoDB 2.3}: An Open source, multi-purpose database supporting flexible data models for documents, graphs, and key-values.},
Year = {2014}, Year = {2014},
Howpublished = {\url{http://arangodb.com/} Howpublished = {\url{http://arangodb.com/}
} }

View File

@ -4706,13 +4706,30 @@ int RemoteBlock::shutdown (int errorCode) {
return TRI_ERROR_NO_ERROR; return TRI_ERROR_NO_ERROR;
} }
// If we get here, then res->result is the response which will be
// a serialized AqlItemBlock:
StringBuffer const& responseBodyBuf(res->result->getBody()); StringBuffer const& responseBodyBuf(res->result->getBody());
Json responseBodyJson(TRI_UNKNOWN_MEM_ZONE, Json responseBodyJson(TRI_UNKNOWN_MEM_ZONE,
TRI_JsonString(TRI_UNKNOWN_MEM_ZONE, TRI_JsonString(TRI_UNKNOWN_MEM_ZONE,
responseBodyBuf.begin())); responseBodyBuf.begin()));
// read "warnings" attribute if present and add it our query
if (responseBodyJson.isArray()) {
auto warnings = responseBodyJson.get("warnings");
if (warnings.isList()) {
auto query = _engine->getQuery();
for (size_t i = 0; i < warnings.size(); ++i) {
auto warning = warnings.at(i);
if (warning.isArray()) {
auto code = warning.get("code");
auto message = warning.get("message");
if (code.isNumber() && message.isString()) {
query->registerWarning(static_cast<int>(code.json()->_value._number),
message.json()->_value._string.data);
}
}
}
}
}
return JsonHelper::getNumericValue<int> return JsonHelper::getNumericValue<int>
(responseBodyJson.json(), "code", TRI_ERROR_INTERNAL); (responseBodyJson.json(), "code", TRI_ERROR_INTERNAL);
LEAVE_BLOCK LEAVE_BLOCK

View File

@ -917,6 +917,34 @@ bool Query::getBooleanOption (char const* option, bool defaultValue) const {
return valueJson->_value._boolean; return valueJson->_value._boolean;
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief convert the list of warnings to JSON
////////////////////////////////////////////////////////////////////////////////
TRI_json_t* Query::warningsToJson () const {
if (_warnings.empty()) {
return nullptr;
}
size_t const n = _warnings.size();
TRI_json_t* json = TRI_CreateList2Json(TRI_UNKNOWN_MEM_ZONE, n);
if (json != nullptr) {
for (size_t i = 0; i < n; ++i) {
TRI_json_t* error = TRI_CreateArray2Json(TRI_UNKNOWN_MEM_ZONE, 2);
if (error != nullptr) {
TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, error, "code", TRI_CreateNumberJson(TRI_UNKNOWN_MEM_ZONE, static_cast<double>(_warnings[i].first)));
TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, error, "message", TRI_CreateString2CopyJson(TRI_UNKNOWN_MEM_ZONE, _warnings[i].second.c_str(), _warnings[i].second.size()));
TRI_PushBack3ListJson(TRI_UNKNOWN_MEM_ZONE, json, error);
}
}
}
return json;
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- private methods // --SECTION-- private methods
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -1092,34 +1120,6 @@ void Query::setPlan (ExecutionPlan *plan) {
_plan = plan; _plan = plan;
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief convert the list of warnings to JSON
////////////////////////////////////////////////////////////////////////////////
TRI_json_t* Query::warningsToJson () const {
if (_warnings.empty()) {
return nullptr;
}
size_t const n = _warnings.size();
TRI_json_t* json = TRI_CreateList2Json(TRI_UNKNOWN_MEM_ZONE, n);
if (json != nullptr) {
for (size_t i = 0; i < n; ++i) {
TRI_json_t* error = TRI_CreateArray2Json(TRI_UNKNOWN_MEM_ZONE, 2);
if (error != nullptr) {
TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, error, "code", TRI_CreateNumberJson(TRI_UNKNOWN_MEM_ZONE, static_cast<double>(_warnings[i].first)));
TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, error, "message", TRI_CreateString2CopyJson(TRI_UNKNOWN_MEM_ZONE, _warnings[i].second.c_str(), _warnings[i].second.size()));
TRI_PushBack3ListJson(TRI_UNKNOWN_MEM_ZONE, json, error);
}
}
}
return json;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief create a TransactionContext /// @brief create a TransactionContext
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -405,6 +405,12 @@ namespace triagens {
bool getBooleanOption (char const*, bool getBooleanOption (char const*,
bool) const; bool) const;
////////////////////////////////////////////////////////////////////////////////
/// @brief convert the list of warnings to JSON
////////////////////////////////////////////////////////////////////////////////
TRI_json_t* warningsToJson () const;
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- private methods // --SECTION-- private methods
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -452,12 +458,6 @@ namespace triagens {
void cleanupPlanAndEngine (int); void cleanupPlanAndEngine (int);
////////////////////////////////////////////////////////////////////////////////
/// @brief convert the list of warnings to JSON
////////////////////////////////////////////////////////////////////////////////
TRI_json_t* warningsToJson () const;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief create a TransactionContext /// @brief create a TransactionContext
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -841,7 +841,17 @@ void RestAqlHandler::handleUseQuery (std::string const& operation,
try { try {
res = query->engine()->shutdown(errorCode); // pass errorCode to shutdown res = query->engine()->shutdown(errorCode); // pass errorCode to shutdown
// return statistics
answerBody("stats", query->getStats()); answerBody("stats", query->getStats());
// return warnings if present
auto warnings = query->warningsToJson();
if (warnings != nullptr) {
answerBody("warnings", Json(TRI_UNKNOWN_MEM_ZONE, warnings));
}
// delete the query from the registry
_queryRegistry->destroy(_vocbase, _qId, errorCode); _queryRegistry->destroy(_vocbase, _qId, errorCode);
} }
catch (...) { catch (...) {

View File

@ -242,6 +242,10 @@ static int HashIndexHelperAllocate (TRI_hash_index_t const* hashIndex,
static int HashIndex_insert (TRI_hash_index_t* hashIndex, static int HashIndex_insert (TRI_hash_index_t* hashIndex,
TRI_hash_index_element_t* element, TRI_hash_index_element_t* element,
bool isRollback) { bool isRollback) {
TRI_IF_FAILURE("InsertHashIndex") {
return TRI_ERROR_DEBUG;
}
TRI_index_search_value_t key; TRI_index_search_value_t key;
int res = FillIndexSearchValueByHashIndexElement<TRI_hash_index_element_t>(hashIndex, &key, element); int res = FillIndexSearchValueByHashIndexElement<TRI_hash_index_element_t>(hashIndex, &key, element);
@ -269,6 +273,10 @@ static int HashIndex_insert (TRI_hash_index_t* hashIndex,
static int HashIndex_remove (TRI_hash_index_t* hashIndex, static int HashIndex_remove (TRI_hash_index_t* hashIndex,
TRI_hash_index_element_t* element) { TRI_hash_index_element_t* element) {
TRI_IF_FAILURE("RemoveHashIndex") {
return TRI_ERROR_DEBUG;
}
int res = TRI_RemoveElementHashArray(&hashIndex->_hashArray, element); int res = TRI_RemoveElementHashArray(&hashIndex->_hashArray, element);
// this might happen when rolling back // this might happen when rolling back
@ -331,6 +339,10 @@ static TRI_index_result_t HashIndex_find (TRI_hash_index_t* hashIndex,
static int MultiHashIndex_insert (TRI_hash_index_t* hashIndex, static int MultiHashIndex_insert (TRI_hash_index_t* hashIndex,
TRI_hash_index_element_multi_t* element, TRI_hash_index_element_multi_t* element,
bool isRollback) { bool isRollback) {
TRI_IF_FAILURE("InsertHashIndex") {
return TRI_ERROR_DEBUG;
}
TRI_index_search_value_t key; TRI_index_search_value_t key;
int res = FillIndexSearchValueByHashIndexElement<TRI_hash_index_element_multi_t>(hashIndex, &key, element); int res = FillIndexSearchValueByHashIndexElement<TRI_hash_index_element_multi_t>(hashIndex, &key, element);
@ -358,6 +370,10 @@ static int MultiHashIndex_insert (TRI_hash_index_t* hashIndex,
int MultiHashIndex_remove (TRI_hash_index_t* hashIndex, int MultiHashIndex_remove (TRI_hash_index_t* hashIndex,
TRI_hash_index_element_multi_t* element) { TRI_hash_index_element_multi_t* element) {
TRI_IF_FAILURE("RemoveHashIndex") {
return TRI_ERROR_DEBUG;
}
TRI_index_search_value_t key; TRI_index_search_value_t key;
int res = FillIndexSearchValueByHashIndexElement<TRI_hash_index_element_multi_t>(hashIndex, &key, element); int res = FillIndexSearchValueByHashIndexElement<TRI_hash_index_element_multi_t>(hashIndex, &key, element);

View File

@ -281,6 +281,7 @@ ArangoServer::ArangoServer (int argc, char** argv)
_disableAuthenticationUnixSockets(false), _disableAuthenticationUnixSockets(false),
_dispatcherThreads(8), _dispatcherThreads(8),
_dispatcherQueueSize(8192), _dispatcherQueueSize(8192),
_v8Contexts(8),
_databasePath(), _databasePath(),
_defaultMaximalSize(TRI_JOURNAL_DEFAULT_MAXIMAL_SIZE), _defaultMaximalSize(TRI_JOURNAL_DEFAULT_MAXIMAL_SIZE),
_defaultWaitForSync(false), _defaultWaitForSync(false),
@ -560,6 +561,7 @@ void ArangoServer::buildApplicationServer () {
additional["THREAD Options:help-admin"] additional["THREAD Options:help-admin"]
("server.threads", &_dispatcherThreads, "number of threads for basic operations") ("server.threads", &_dispatcherThreads, "number of threads for basic operations")
("javascript.v8-contexts", &_v8Contexts, "number of V8 contexts that are created for executing JavaScript actions")
; ;
additional["Server Options:help-extended"] additional["Server Options:help-extended"]
@ -795,25 +797,35 @@ int ArangoServer::startupServer () {
TRI_ASSERT(vocbase != nullptr); TRI_ASSERT(vocbase != nullptr);
// initialise V8 // initialise V8
size_t concurrency = _dispatcherThreads; if (! _applicationServer->programOptions().has("javascript.v8-contexts")) {
// the option was added recently so it's not always set
// the behavior in older ArangoDB was to create one V8 context per dispatcher thread
_v8Contexts = _dispatcherThreads;
}
if (_v8Contexts < 1) {
_v8Contexts = 1;
}
if (mode == OperationMode::MODE_CONSOLE) { if (mode == OperationMode::MODE_CONSOLE) {
// one V8 instance is taken by the console // one V8 instance is taken by the console
if (startServer) { if (startServer) {
++concurrency; ++_v8Contexts;
} }
} }
else if (mode == OperationMode::MODE_UNITTESTS || mode == OperationMode::MODE_SCRIPT) { else if (mode == OperationMode::MODE_UNITTESTS || mode == OperationMode::MODE_SCRIPT) {
if (concurrency == 1) { if (_v8Contexts == 1) {
// at least two to allow the test-runner and the scheduler to use a V8 // at least two to allow both the test-runner and the scheduler to use a V8 instance
concurrency = 2; _v8Contexts = 2;
} }
} }
_applicationV8->setVocbase(vocbase); _applicationV8->setVocbase(vocbase);
_applicationV8->setConcurrency(concurrency); _applicationV8->setConcurrency(_v8Contexts);
_applicationV8->defineDouble("DISPATCHER_THREADS", _dispatcherThreads); _applicationV8->defineDouble("DISPATCHER_THREADS", _dispatcherThreads);
_applicationV8->defineDouble("V8_CONTEXTS", _v8Contexts);
// ............................................................................. // .............................................................................
// prepare everything // prepare everything

View File

@ -317,12 +317,12 @@ namespace triagens {
bool _disableAuthenticationUnixSockets; bool _disableAuthenticationUnixSockets;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief number of dispatcher threads for non-database worker /// @brief number of dispatcher threads
/// @startDocuBlock serverThreads /// @startDocuBlock serverThreads
/// `--server.threads number` /// `--server.threads number`
/// ///
/// Specifies the *number* of threads that are spawned to handle action /// Specifies the *number* of threads that are spawned to handle HTTP REST
/// requests using Rest, JavaScript, or Ruby. /// requests.
/// @endDocuBlock /// @endDocuBlock
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -330,7 +330,7 @@ namespace triagens {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief maximum size of the dispatcher queue for asynchronous requests /// @brief maximum size of the dispatcher queue for asynchronous requests
/// @startDocuBlock serverAuthenticationDisable /// @startDocuBlock schedulerMaximalQueueSize
/// `--scheduler.maximal-queue-size size` /// `--scheduler.maximal-queue-size size`
/// ///
/// Specifies the maximum *size* of the dispatcher queue for asynchronous /// Specifies the maximum *size* of the dispatcher queue for asynchronous
@ -343,6 +343,21 @@ namespace triagens {
int _dispatcherQueueSize; int _dispatcherQueueSize;
////////////////////////////////////////////////////////////////////////////////
/// @brief number of V8 contexts for executing JavaScript actions
/// @startDocuBlock v8Contexts
/// `--server.v8-contexts number`
///
/// Specifies the *number* of V8 contexts that are created for executing
/// JavaScript code. More contexts allow execute more JavaScript actions in
/// parallel, provided that there are also enough threads available. Please
/// note that each V8 context will use a substantial amount of memory and
/// requires periodic CPU processing time for garbage collection.
/// @endDocuBlock
////////////////////////////////////////////////////////////////////////////////
int _v8Contexts;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief path to the database /// @brief path to the database
/// @startDocuBlock DatabaseDirectory /// @startDocuBlock DatabaseDirectory

View File

@ -259,6 +259,10 @@ static inline void SetRevision (TRI_document_collection_t* document,
static int InsertPrimaryIndex (TRI_document_collection_t* document, static int InsertPrimaryIndex (TRI_document_collection_t* document,
TRI_doc_mptr_t const* header, TRI_doc_mptr_t const* header,
bool isRollback) { bool isRollback) {
TRI_IF_FAILURE("InsertPrimaryIndex") {
return TRI_ERROR_DEBUG;
}
TRI_doc_mptr_t* found; TRI_doc_mptr_t* found;
TRI_ASSERT(document != nullptr); TRI_ASSERT(document != nullptr);
@ -294,6 +298,10 @@ static int InsertPrimaryIndex (TRI_document_collection_t* document,
static int InsertSecondaryIndexes (TRI_document_collection_t* document, static int InsertSecondaryIndexes (TRI_document_collection_t* document,
TRI_doc_mptr_t const* header, TRI_doc_mptr_t const* header,
bool isRollback) { bool isRollback) {
TRI_IF_FAILURE("InsertSecondaryIndexes") {
return TRI_ERROR_DEBUG;
}
if (! document->useSecondaryIndexes()) { if (! document->useSecondaryIndexes()) {
return TRI_ERROR_NO_ERROR; return TRI_ERROR_NO_ERROR;
} }
@ -329,9 +337,9 @@ static int InsertSecondaryIndexes (TRI_document_collection_t* document,
static int DeletePrimaryIndex (TRI_document_collection_t* document, static int DeletePrimaryIndex (TRI_document_collection_t* document,
TRI_doc_mptr_t const* header, TRI_doc_mptr_t const* header,
bool isRollback) { bool isRollback) {
// ............................................................................. TRI_IF_FAILURE("DeletePrimaryIndex") {
// remove from main index return TRI_ERROR_DEBUG;
// ............................................................................. }
TRI_doc_mptr_t* found = static_cast<TRI_doc_mptr_t*>(TRI_RemoveKeyPrimaryIndex(&document->_primaryIndex, TRI_EXTRACT_MARKER_KEY(header))); // ONLY IN INDEX, PROTECTED by RUNTIME TRI_doc_mptr_t* found = static_cast<TRI_doc_mptr_t*>(TRI_RemoveKeyPrimaryIndex(&document->_primaryIndex, TRI_EXTRACT_MARKER_KEY(header))); // ONLY IN INDEX, PROTECTED by RUNTIME
@ -353,6 +361,10 @@ static int DeleteSecondaryIndexes (TRI_document_collection_t* document,
return TRI_ERROR_NO_ERROR; return TRI_ERROR_NO_ERROR;
} }
TRI_IF_FAILURE("DeleteSecondaryIndexes") {
return TRI_ERROR_DEBUG;
}
int result = TRI_ERROR_NO_ERROR; int result = TRI_ERROR_NO_ERROR;
size_t const n = document->_allIndexes._length; size_t const n = document->_allIndexes._length;

View File

@ -118,7 +118,9 @@ namespace triagens {
header->copy(oldHeader); header->copy(oldHeader);
} }
else if (type == TRI_VOC_DOCUMENT_OPERATION_REMOVE) { else if (type == TRI_VOC_DOCUMENT_OPERATION_REMOVE) {
document->_headersPtr->relink(header, &oldHeader); // PROTECTED by trx in trxCollection if (status != StatusType::CREATED) {
document->_headersPtr->relink(header, &oldHeader); // PROTECTED by trx in trxCollection
}
} }
status = StatusType::SWAPPED; status = StatusType::SWAPPED;

View File

@ -41,7 +41,7 @@ def genJsFile(errors):
i = i + 1 i = i + 1
if i < len(errors): if i < len(errors):
out = out + ", \n" out = out + ",\n"
else: else:
out = out + "\n" out = out + "\n"

View File

@ -66,7 +66,7 @@ function DatabaseSuite () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testVersion : function () { testVersion : function () {
assertMatch(/(^2\.2)|(-devel$)/, internal.db._version()); assertMatch(/(^2\.3)|(-devel$)/, internal.db._version());
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -36,7 +36,9 @@
/// to perform and the second is an options object. For `which` the following /// to perform and the second is an options object. For `which` the following
/// values are allowed: /// values are allowed:
/// Empty will give you a complete list. /// Empty will give you a complete list.
var functionDoku = { ////////////////////////////////////////////////////////////////////////////////
var functionsDocumentation = {
'all' : " do all tests (marked with [x])", 'all' : " do all tests (marked with [x])",
"shell_server_perf" : "bulk tests intended to get an overview of executiontime needed.", "shell_server_perf" : "bulk tests intended to get an overview of executiontime needed.",
"single_client" : "run one test suite isolated via the arangosh; options required\n" + "single_client" : "run one test suite isolated via the arangosh; options required\n" +
@ -45,7 +47,7 @@ var functionDoku = {
" Run without to get more detail" " Run without to get more detail"
}; };
var optiondoku = [ var optionsDocumentation = [
'', '',
' The following properties of `options` are defined:', ' The following properties of `options` are defined:',
'', '',
@ -65,7 +67,7 @@ var optiondoku = [
' - `cleanup`: if set to true (the default), the cluster data files', ' - `cleanup`: if set to true (the default), the cluster data files',
' and logs are removed after termination of the test.', ' and logs are removed after termination of the test.',
' - `jasmineReportFormat`: this option is passed on to the `format`', ' - `jasmineReportFormat`: this option is passed on to the `format`',
' option of the Jasmin options object, only for Jasmin tests.', ' option of the Jasmine options object, only for Jasmine tests.',
'', '',
' - `valgrind`: if set to true the arangods are run with the valgrind', ' - `valgrind`: if set to true the arangods are run with the valgrind',
' memory checker', ' memory checker',
@ -76,7 +78,6 @@ var optiondoku = [
' - `portOffset`: move our base port by n ports up', ' - `portOffset`: move our base port by n ports up',
'' ''
]; ];
////////////////////////////////////////////////////////////////////////////////
var _ = require("underscore"); var _ = require("underscore");
var cleanupDirectories = []; var cleanupDirectories = [];
@ -146,14 +147,14 @@ function printUsage () {
print(' where "which" is one of:\n'); print(' where "which" is one of:\n');
var i; var i;
var checkAll; var checkAll;
var oneFunctionDoku; var oneFunctionDocumentation;
for (i in testFuncs) { for (i in testFuncs) {
if (testFuncs.hasOwnProperty(i)) { if (testFuncs.hasOwnProperty(i)) {
if (functionDoku.hasOwnProperty(i)) { if (functionsDocumentation.hasOwnProperty(i)) {
oneFunctionDoku = ' - ' + functionDoku[i]; oneFunctionDocumentation = ' - ' + functionsDocumentation[i];
} }
else { else {
oneFunctionDoku = ''; oneFunctionDocumentation = '';
} }
if (allTests.indexOf(i) !== -1) { if (allTests.indexOf(i) !== -1) {
checkAll = '[x]'; checkAll = '[x]';
@ -161,18 +162,17 @@ function printUsage () {
else { else {
checkAll = ' '; checkAll = ' ';
} }
print(' ' + checkAll + ' '+i+' ' + oneFunctionDoku); print(' ' + checkAll + ' '+i+' ' + oneFunctionDocumentation);
} }
} }
for (i in optiondoku) { for (i in optionsDocumentation) {
if (optiondoku.hasOwnProperty(i)) { if (optionsDocumentation.hasOwnProperty(i)) {
print(optiondoku[i]); print(optionsDocumentation[i]);
} }
} }
} }
function filterTestcaseByOptions (testname, options, whichFilter) function filterTestcaseByOptions (testname, options, whichFilter) {
{
if ((testname.indexOf("-cluster") !== -1) && (options.cluster === false)) { if ((testname.indexOf("-cluster") !== -1) && (options.cluster === false)) {
whichFilter.filter = 'noncluster'; whichFilter.filter = 'noncluster';
return false; return false;
@ -560,13 +560,13 @@ function runThere (options, instanceInfo, file) {
var t; var t;
if (file.indexOf("-spec") === -1) { if (file.indexOf("-spec") === -1) {
t = 'var runTest = require("jsunity").runTest; '+ t = 'var runTest = require("jsunity").runTest; '+
'return runTest('+JSON.stringify(file)+');'; 'return runTest(' + JSON.stringify(file) + ');';
} }
else { else {
var jasmineReportFormat = options.jasmineReportFormat || 'progress'; var jasmineReportFormat = options.jasmineReportFormat || 'progress';
t = 'var executeTestSuite = require("jasmine").executeTestSuite; '+ t = 'var executeTestSuite = require("jasmine").executeTestSuite; '+
'return executeTestSuite(['+JSON.stringify(file)+'],{"format": '+ 'return executeTestSuite([' + JSON.stringify(file) + '],{"format": '+
JSON.stringify(jasmineReportFormat)+'});'; JSON.stringify(jasmineReportFormat) + '});';
} }
var o = makeAuthorisationHeaders(options); var o = makeAuthorisationHeaders(options);
o.method = "POST"; o.method = "POST";

View File

@ -36,6 +36,14 @@ var cluster = require("org/arangodb/cluster");
var getModifyQueryResults = helper.getModifyQueryResults; var getModifyQueryResults = helper.getModifyQueryResults;
var assertQueryError = helper.assertQueryError; var assertQueryError = helper.assertQueryError;
var sanitizeStats = function (stats) {
// remove these members from the stats because they don't matter
// for the comparisons
delete stats.scannedFull;
delete stats.scannedIndex;
return stats;
};
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief test suite /// @brief test suite
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -203,11 +211,11 @@ function ahuacatlRemoveSuite () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testRemoveNothing : function () { testRemoveNothing : function () {
var expected = { executed: 0, ignored: 0 }; var expected = { writesExecuted: 0, writesIgnored: 0 };
var actual = getModifyQueryResults("FOR d IN " + cn1 + " FILTER d.value1 < 0 REMOVE d IN " + cn1); var actual = getModifyQueryResults("FOR d IN " + cn1 + " FILTER d.value1 < 0 REMOVE d IN " + cn1);
assertEqual(100, c1.count()); assertEqual(100, c1.count());
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -215,11 +223,11 @@ function ahuacatlRemoveSuite () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testRemoveNothingBind : function () { testRemoveNothingBind : function () {
var expected = { executed: 0, ignored: 0 }; var expected = { writesExecuted: 0, writesIgnored: 0 };
var actual = getModifyQueryResults("FOR d IN @@cn FILTER d.value1 < 0 REMOVE d IN @@cn", { "@cn": cn1 }); var actual = getModifyQueryResults("FOR d IN @@cn FILTER d.value1 < 0 REMOVE d IN @@cn", { "@cn": cn1 });
assertEqual(100, c1.count()); assertEqual(100, c1.count());
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -268,11 +276,11 @@ function ahuacatlRemoveSuite () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testRemoveIgnore1 : function () { testRemoveIgnore1 : function () {
var expected = { executed: 0, ignored: 100 }; var expected = { writesExecuted: 0, writesIgnored: 100 };
var actual = getModifyQueryResults("FOR d IN @@cn REMOVE 'foo' IN @@cn OPTIONS { ignoreErrors: true }", { "@cn": cn1 }); var actual = getModifyQueryResults("FOR d IN @@cn REMOVE 'foo' IN @@cn OPTIONS { ignoreErrors: true }", { "@cn": cn1 });
assertEqual(100, c1.count()); assertEqual(100, c1.count());
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -280,11 +288,11 @@ function ahuacatlRemoveSuite () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testRemoveIgnore2 : function () { testRemoveIgnore2 : function () {
var expected = { executed: 100, ignored: 1 }; var expected = { writesExecuted: 100, writesIgnored: 1 };
var actual = getModifyQueryResults("FOR i IN 0..100 REMOVE CONCAT('test', TO_STRING(i)) IN @@cn OPTIONS { ignoreErrors: true }", { "@cn": cn1 }); var actual = getModifyQueryResults("FOR i IN 0..100 REMOVE CONCAT('test', TO_STRING(i)) IN @@cn OPTIONS { ignoreErrors: true }", { "@cn": cn1 });
assertEqual(0, c1.count()); assertEqual(0, c1.count());
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -292,11 +300,11 @@ function ahuacatlRemoveSuite () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testRemoveAll1 : function () { testRemoveAll1 : function () {
var expected = { executed: 100, ignored: 0 }; var expected = { writesExecuted: 100, writesIgnored: 0 };
var actual = getModifyQueryResults("FOR d IN @@cn REMOVE d IN @@cn", { "@cn": cn1 }); var actual = getModifyQueryResults("FOR d IN @@cn REMOVE d IN @@cn", { "@cn": cn1 });
assertEqual(0, c1.count()); assertEqual(0, c1.count());
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -304,11 +312,11 @@ function ahuacatlRemoveSuite () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testRemoveAll2 : function () { testRemoveAll2 : function () {
var expected = { executed: 100, ignored: 0 }; var expected = { writesExecuted: 100, writesIgnored: 0 };
var actual = getModifyQueryResults("FOR d IN @@cn REMOVE d._key IN @@cn", { "@cn": cn1 }); var actual = getModifyQueryResults("FOR d IN @@cn REMOVE d._key IN @@cn", { "@cn": cn1 });
assertEqual(0, c1.count()); assertEqual(0, c1.count());
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -316,11 +324,11 @@ function ahuacatlRemoveSuite () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testRemoveAll3 : function () { testRemoveAll3 : function () {
var expected = { executed: 100, ignored: 0 }; var expected = { writesExecuted: 100, writesIgnored: 0 };
var actual = getModifyQueryResults("FOR d IN @@cn REMOVE { _key: d._key } IN @@cn", { "@cn": cn1 }); var actual = getModifyQueryResults("FOR d IN @@cn REMOVE { _key: d._key } IN @@cn", { "@cn": cn1 });
assertEqual(0, c1.count()); assertEqual(0, c1.count());
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -328,11 +336,11 @@ function ahuacatlRemoveSuite () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testRemoveAll4 : function () { testRemoveAll4 : function () {
var expected = { executed: 100, ignored: 0 }; var expected = { writesExecuted: 100, writesIgnored: 0 };
var actual = getModifyQueryResults("FOR i IN 0..99 REMOVE { _key: CONCAT('test', TO_STRING(i)) } IN @@cn", { "@cn": cn1 }); var actual = getModifyQueryResults("FOR i IN 0..99 REMOVE { _key: CONCAT('test', TO_STRING(i)) } IN @@cn", { "@cn": cn1 });
assertEqual(0, c1.count()); assertEqual(0, c1.count());
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -340,24 +348,23 @@ function ahuacatlRemoveSuite () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testRemoveAll5 : function () { testRemoveAll5 : function () {
var expected = { executed: 100, ignored: 0 }; var expected = { writesExecuted: 100, writesIgnored: 0 };
var actual = getModifyQueryResults("FOR d IN @@cn REMOVE d INTO @@cn", { "@cn": cn1 }); var actual = getModifyQueryResults("FOR d IN @@cn REMOVE d INTO @@cn", { "@cn": cn1 });
assertEqual(0, c1.count()); assertEqual(0, c1.count());
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief test remove /// @brief test remove
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testRemoveHalf : function () { testRemoveHalf : function () {
var expected = { executed: 50, ignored: 0 }; var expected = { writesExecuted: 50, writesIgnored: 0 };
var actual = getModifyQueryResults("FOR i IN 0..99 FILTER i % 2 == 0 REMOVE { _key: CONCAT('test', TO_STRING(i)) } IN @@cn", { "@cn": cn1 }); var actual = getModifyQueryResults("FOR i IN 0..99 FILTER i % 2 == 0 REMOVE { _key: CONCAT('test', TO_STRING(i)) } IN @@cn", { "@cn": cn1 });
assertEqual(50, c1.count()); assertEqual(50, c1.count());
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -373,11 +380,11 @@ function ahuacatlRemoveSuite () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testSingle : function () { testSingle : function () {
var expected = { executed: 1, ignored: 0 }; var expected = { writesExecuted: 1, writesIgnored: 0 };
var actual = getModifyQueryResults("REMOVE 'test0' IN @@cn", { "@cn": cn1 }); var actual = getModifyQueryResults("REMOVE 'test0' IN @@cn", { "@cn": cn1 });
assertEqual(99, c1.count()); assertEqual(99, c1.count());
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -396,12 +403,12 @@ function ahuacatlRemoveSuite () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testTwoCollectionsJoin1 : function () { testTwoCollectionsJoin1 : function () {
var expected = { executed: 50, ignored: 0 }; var expected = { writesExecuted: 50, writesIgnored: 0 };
var actual = getModifyQueryResults("FOR d IN @@cn1 FILTER d.value1 < 50 REMOVE { _key: d._key } IN @@cn2", { "@cn1": cn1, "@cn2": cn2 }); var actual = getModifyQueryResults("FOR d IN @@cn1 FILTER d.value1 < 50 REMOVE { _key: d._key } IN @@cn2", { "@cn1": cn1, "@cn2": cn2 });
assertEqual(100, c1.count()); assertEqual(100, c1.count());
assertEqual(0, c2.count()); assertEqual(0, c2.count());
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -409,12 +416,12 @@ function ahuacatlRemoveSuite () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testTwoCollectionsJoin2 : function () { testTwoCollectionsJoin2 : function () {
var expected = { executed: 48, ignored: 0 }; var expected = { writesExecuted: 48, writesIgnored: 0 };
var actual = getModifyQueryResults("FOR d IN @@cn1 FILTER d.value1 >= 2 && d.value1 < 50 REMOVE { _key: d._key } IN @@cn2", { "@cn1": cn1, "@cn2": cn2 }); var actual = getModifyQueryResults("FOR d IN @@cn1 FILTER d.value1 >= 2 && d.value1 < 50 REMOVE { _key: d._key } IN @@cn2", { "@cn1": cn1, "@cn2": cn2 });
assertEqual(100, c1.count()); assertEqual(100, c1.count());
assertEqual(2, c2.count()); assertEqual(2, c2.count());
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -422,12 +429,12 @@ function ahuacatlRemoveSuite () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testTwoCollectionsIgnoreErrors1 : function () { testTwoCollectionsIgnoreErrors1 : function () {
var expected = { executed: 50, ignored: 50 }; var expected = { writesExecuted: 50, writesIgnored: 50 };
var actual = getModifyQueryResults("FOR d IN @@cn1 REMOVE { _key: d._key } IN @@cn2 OPTIONS { ignoreErrors: true }", { "@cn1": cn1, "@cn2": cn2 }); var actual = getModifyQueryResults("FOR d IN @@cn1 REMOVE { _key: d._key } IN @@cn2 OPTIONS { ignoreErrors: true }", { "@cn1": cn1, "@cn2": cn2 });
assertEqual(100, c1.count()); assertEqual(100, c1.count());
assertEqual(0, c2.count()); assertEqual(0, c2.count());
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -435,12 +442,12 @@ function ahuacatlRemoveSuite () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testTwoCollectionsIgnoreErrors2 : function () { testTwoCollectionsIgnoreErrors2 : function () {
var expected = { executed: 0, ignored: 100 }; var expected = { writesExecuted: 0, writesIgnored: 100 };
var actual = getModifyQueryResults("FOR d IN @@cn1 REMOVE { _key: CONCAT('foo', d._key) } IN @@cn2 OPTIONS { ignoreErrors: true }", { "@cn1": cn1, "@cn2": cn2 }); var actual = getModifyQueryResults("FOR d IN @@cn1 REMOVE { _key: CONCAT('foo', d._key) } IN @@cn2 OPTIONS { ignoreErrors: true }", { "@cn1": cn1, "@cn2": cn2 });
assertEqual(100, c1.count()); assertEqual(100, c1.count());
assertEqual(50, c2.count()); assertEqual(50, c2.count());
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -448,11 +455,11 @@ function ahuacatlRemoveSuite () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testRemoveWaitForSync : function () { testRemoveWaitForSync : function () {
var expected = { executed: 100, ignored: 0 }; var expected = { writesExecuted: 100, writesIgnored: 0 };
var actual = getModifyQueryResults("FOR d IN @@cn REMOVE d IN @@cn OPTIONS { waitForSync: true }", { "@cn": cn1 }); var actual = getModifyQueryResults("FOR d IN @@cn REMOVE d IN @@cn OPTIONS { waitForSync: true }", { "@cn": cn1 });
assertEqual(0, c1.count()); assertEqual(0, c1.count());
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -466,12 +473,12 @@ function ahuacatlRemoveSuite () {
for (var i = 0; i < 100; ++i) { for (var i = 0; i < 100; ++i) {
edge.save("UnitTestsAhuacatlRemove1/foo" + i, "UnitTestsAhuacatlRemove2/bar", { what: i, _key: "test" + i }); edge.save("UnitTestsAhuacatlRemove1/foo" + i, "UnitTestsAhuacatlRemove2/bar", { what: i, _key: "test" + i });
} }
var expected = { executed: 10, ignored: 0 }; var expected = { writesExecuted: 10, writesIgnored: 0 };
var actual = getModifyQueryResults("FOR i IN 0..9 REMOVE CONCAT('test', TO_STRING(i)) IN @@cn", { "@cn": edge.name() }); var actual = getModifyQueryResults("FOR i IN 0..9 REMOVE CONCAT('test', TO_STRING(i)) IN @@cn", { "@cn": edge.name() });
assertEqual(100, c1.count()); assertEqual(100, c1.count());
assertEqual(90, edge.count()); assertEqual(90, edge.count());
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
db._drop("UnitTestsAhuacatlEdge"); db._drop("UnitTestsAhuacatlEdge");
} }
@ -526,11 +533,11 @@ function ahuacatlInsertSuite () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testInsertNothing : function () { testInsertNothing : function () {
var expected = { executed: 0, ignored: 0 }; var expected = { writesExecuted: 0, writesIgnored: 0 };
var actual = getModifyQueryResults("FOR d IN " + cn1 + " FILTER d.value1 < 0 INSERT { foxx: true } IN " + cn1); var actual = getModifyQueryResults("FOR d IN " + cn1 + " FILTER d.value1 < 0 INSERT { foxx: true } IN " + cn1);
assertEqual(100, c1.count()); assertEqual(100, c1.count());
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -538,11 +545,11 @@ function ahuacatlInsertSuite () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testInsertNothingBind : function () { testInsertNothingBind : function () {
var expected = { executed: 0, ignored: 0 }; var expected = { writesExecuted: 0, writesIgnored: 0 };
var actual = getModifyQueryResults("FOR d IN @@cn FILTER d.value1 < 0 INSERT { foxx: true } IN @@cn", { "@cn": cn1 }); var actual = getModifyQueryResults("FOR d IN @@cn FILTER d.value1 < 0 INSERT { foxx: true } IN @@cn", { "@cn": cn1 });
assertEqual(100, c1.count()); assertEqual(100, c1.count());
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -606,11 +613,11 @@ function ahuacatlInsertSuite () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testInsertIgnore1 : function () { testInsertIgnore1 : function () {
var expected = { executed: 0, ignored: 100 }; var expected = { writesExecuted: 0, writesIgnored: 100 };
var actual = getModifyQueryResults("FOR d IN @@cn INSERT d IN @@cn OPTIONS { ignoreErrors: true }", { "@cn": cn1 }); var actual = getModifyQueryResults("FOR d IN @@cn INSERT d IN @@cn OPTIONS { ignoreErrors: true }", { "@cn": cn1 });
assertEqual(100, c1.count()); assertEqual(100, c1.count());
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -618,11 +625,11 @@ function ahuacatlInsertSuite () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testInsertIgnore2 : function () { testInsertIgnore2 : function () {
var expected = { executed: 1, ignored: 50 }; var expected = { writesExecuted: 1, writesIgnored: 50 };
var actual = getModifyQueryResults("FOR i IN 50..100 INSERT { _key: CONCAT('test', TO_STRING(i)) } IN @@cn OPTIONS { ignoreErrors: true }", { "@cn": cn1 }); var actual = getModifyQueryResults("FOR i IN 50..100 INSERT { _key: CONCAT('test', TO_STRING(i)) } IN @@cn OPTIONS { ignoreErrors: true }", { "@cn": cn1 });
assertEqual(101, c1.count()); assertEqual(101, c1.count());
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -630,11 +637,11 @@ function ahuacatlInsertSuite () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testInsertIgnore3 : function () { testInsertIgnore3 : function () {
var expected = { executed: 51, ignored: 50 }; var expected = { writesExecuted: 51, writesIgnored: 50 };
var actual = getModifyQueryResults("FOR i IN 0..100 INSERT { _key: CONCAT('test', TO_STRING(i)) } IN @@cn OPTIONS { ignoreErrors: true }", { "@cn": cn2 }); var actual = getModifyQueryResults("FOR i IN 0..100 INSERT { _key: CONCAT('test', TO_STRING(i)) } IN @@cn OPTIONS { ignoreErrors: true }", { "@cn": cn2 });
assertEqual(101, c2.count()); assertEqual(101, c2.count());
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -642,11 +649,11 @@ function ahuacatlInsertSuite () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testInsertIgnore4 : function () { testInsertIgnore4 : function () {
var expected = { executed: 0, ignored: 100 }; var expected = { writesExecuted: 0, writesIgnored: 100 };
var actual = getModifyQueryResults("FOR i IN 0..99 INSERT { _key: CONCAT('test', TO_STRING(i)) } IN @@cn OPTIONS { ignoreErrors: true }", { "@cn": cn1 }); var actual = getModifyQueryResults("FOR i IN 0..99 INSERT { _key: CONCAT('test', TO_STRING(i)) } IN @@cn OPTIONS { ignoreErrors: true }", { "@cn": cn1 });
assertEqual(100, c1.count()); assertEqual(100, c1.count());
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -654,11 +661,11 @@ function ahuacatlInsertSuite () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testInsertIgnore5 : function () { testInsertIgnore5 : function () {
var expected = { executed: 50, ignored: 50 }; var expected = { writesExecuted: 50, writesIgnored: 50 };
var actual = getModifyQueryResults("FOR i IN 0..99 INSERT { _key: CONCAT('test', TO_STRING(i)) } IN @@cn OPTIONS { ignoreErrors: true }", { "@cn": cn2 }); var actual = getModifyQueryResults("FOR i IN 0..99 INSERT { _key: CONCAT('test', TO_STRING(i)) } IN @@cn OPTIONS { ignoreErrors: true }", { "@cn": cn2 });
assertEqual(100, c2.count()); assertEqual(100, c2.count());
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -666,11 +673,11 @@ function ahuacatlInsertSuite () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testInsertEmpty : function () { testInsertEmpty : function () {
var expected = { executed: 100, ignored: 0 }; var expected = { writesExecuted: 100, writesIgnored: 0 };
var actual = getModifyQueryResults("FOR d IN @@cn INSERT { } IN @@cn", { "@cn": cn1 }); var actual = getModifyQueryResults("FOR d IN @@cn INSERT { } IN @@cn", { "@cn": cn1 });
assertEqual(200, c1.count()); assertEqual(200, c1.count());
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -678,12 +685,12 @@ function ahuacatlInsertSuite () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testInsertCopy : function () { testInsertCopy : function () {
var expected = { executed: 50, ignored: 0 }; var expected = { writesExecuted: 50, writesIgnored: 0 };
var actual = getModifyQueryResults("FOR i IN 50..99 INSERT { _key: CONCAT('test', TO_STRING(i)) } IN @@cn", { "@cn": cn2 }); var actual = getModifyQueryResults("FOR i IN 50..99 INSERT { _key: CONCAT('test', TO_STRING(i)) } IN @@cn", { "@cn": cn2 });
assertEqual(100, c1.count()); assertEqual(100, c1.count());
assertEqual(100, c2.count()); assertEqual(100, c2.count());
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -691,12 +698,12 @@ function ahuacatlInsertSuite () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testSingle : function () { testSingle : function () {
var expected = { executed: 1, ignored: 0 }; var expected = { writesExecuted: 1, writesIgnored: 0 };
var actual = getModifyQueryResults("INSERT { value: 'foobar', _key: 'test' } IN @@cn", { "@cn": cn1 }); var actual = getModifyQueryResults("INSERT { value: 'foobar', _key: 'test' } IN @@cn", { "@cn": cn1 });
assertEqual(101, c1.count()); assertEqual(101, c1.count());
assertEqual("foobar", c1.document("test").value); assertEqual("foobar", c1.document("test").value);
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -704,11 +711,11 @@ function ahuacatlInsertSuite () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testInsertWaitForSync : function () { testInsertWaitForSync : function () {
var expected = { executed: 50, ignored: 0 }; var expected = { writesExecuted: 50, writesIgnored: 0 };
var actual = getModifyQueryResults("FOR i IN 1..50 INSERT { value: i } INTO @@cn OPTIONS { waitForSync: true }", { "@cn": cn2 }); var actual = getModifyQueryResults("FOR i IN 1..50 INSERT { value: i } INTO @@cn OPTIONS { waitForSync: true }", { "@cn": cn2 });
assertEqual(100, c1.count()); assertEqual(100, c1.count());
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -761,10 +768,10 @@ function ahuacatlInsertSuite () {
db._drop("UnitTestsAhuacatlEdge"); db._drop("UnitTestsAhuacatlEdge");
var edge = db._createEdgeCollection("UnitTestsAhuacatlEdge"); var edge = db._createEdgeCollection("UnitTestsAhuacatlEdge");
var expected = { executed: 50, ignored: 0 }; var expected = { writesExecuted: 50, writesIgnored: 0 };
var actual = getModifyQueryResults("FOR i IN 1..50 INSERT { _key: CONCAT('test', TO_STRING(i)), _from: CONCAT('UnitTestsAhuacatlInsert1/', TO_STRING(i)), _to: CONCAT('UnitTestsAhuacatlInsert2/', TO_STRING(i)), value: [ i ], sub: { foo: 'bar' } } INTO @@cn", { "@cn": edge.name() }); var actual = getModifyQueryResults("FOR i IN 1..50 INSERT { _key: CONCAT('test', TO_STRING(i)), _from: CONCAT('UnitTestsAhuacatlInsert1/', TO_STRING(i)), _to: CONCAT('UnitTestsAhuacatlInsert2/', TO_STRING(i)), value: [ i ], sub: { foo: 'bar' } } INTO @@cn", { "@cn": edge.name() });
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
assertEqual(50, edge.count()); assertEqual(50, edge.count());
for (var i = 1; i <= 50; ++i) { for (var i = 1; i <= 50; ++i) {
@ -828,10 +835,10 @@ function ahuacatlUpdateSuite () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testUpdateNothing : function () { testUpdateNothing : function () {
var expected = { executed: 0, ignored: 0 }; var expected = { writesExecuted: 0, writesIgnored: 0 };
var actual = getModifyQueryResults("FOR d IN " + cn1 + " FILTER d.value1 < 0 UPDATE { foxx: true } IN " + cn1); var actual = getModifyQueryResults("FOR d IN " + cn1 + " FILTER d.value1 < 0 UPDATE { foxx: true } IN " + cn1);
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -839,10 +846,10 @@ function ahuacatlUpdateSuite () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testUpdateNothingBind : function () { testUpdateNothingBind : function () {
var expected = { executed: 0, ignored: 0 }; var expected = { writesExecuted: 0, writesIgnored: 0 };
var actual = getModifyQueryResults("FOR d IN @@cn FILTER d.value1 < 0 UPDATE { foxx: true } IN @@cn", { "@cn": cn1 }); var actual = getModifyQueryResults("FOR d IN @@cn FILTER d.value1 < 0 UPDATE { foxx: true } IN @@cn", { "@cn": cn1 });
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -893,10 +900,10 @@ function ahuacatlUpdateSuite () {
testUpdateIgnore1 : function () { testUpdateIgnore1 : function () {
c1.ensureUniqueConstraint("value3"); c1.ensureUniqueConstraint("value3");
var expected = { executed: 1, ignored: 99 }; var expected = { writesExecuted: 1, writesIgnored: 99 };
var actual = getModifyQueryResults("FOR d IN @@cn UPDATE d WITH { value3: 1 } IN @@cn OPTIONS { ignoreErrors: true }", { "@cn": cn1 }); var actual = getModifyQueryResults("FOR d IN @@cn UPDATE d WITH { value3: 1 } IN @@cn OPTIONS { ignoreErrors: true }", { "@cn": cn1 });
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -905,10 +912,10 @@ function ahuacatlUpdateSuite () {
testUpdateIgnore2 : function () { testUpdateIgnore2 : function () {
c1.ensureUniqueConstraint("value1"); c1.ensureUniqueConstraint("value1");
var expected = { executed: 0, ignored: 51 }; var expected = { writesExecuted: 0, writesIgnored: 51 };
var actual = getModifyQueryResults("FOR i IN 50..100 UPDATE { _key: CONCAT('test', TO_STRING(i)), value1: 1 } IN @@cn OPTIONS { ignoreErrors: true }", { "@cn": cn1 }); var actual = getModifyQueryResults("FOR i IN 50..100 UPDATE { _key: CONCAT('test', TO_STRING(i)), value1: 1 } IN @@cn OPTIONS { ignoreErrors: true }", { "@cn": cn1 });
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -916,10 +923,10 @@ function ahuacatlUpdateSuite () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testUpdateEmpty1 : function () { testUpdateEmpty1 : function () {
var expected = { executed: 100, ignored: 0 }; var expected = { writesExecuted: 100, writesIgnored: 0 };
var actual = getModifyQueryResults("FOR d IN @@cn UPDATE { _key: d._key } IN @@cn", { "@cn": cn1 }); var actual = getModifyQueryResults("FOR d IN @@cn UPDATE { _key: d._key } IN @@cn", { "@cn": cn1 });
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
for (var i = 0; i < 100; ++i) { for (var i = 0; i < 100; ++i) {
var doc = c1.document("test" + i); var doc = c1.document("test" + i);
assertEqual(i, doc.value1); assertEqual(i, doc.value1);
@ -932,10 +939,10 @@ function ahuacatlUpdateSuite () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testUpdateEmpty2 : function () { testUpdateEmpty2 : function () {
var expected = { executed: 100, ignored: 0 }; var expected = { writesExecuted: 100, writesIgnored: 0 };
var actual = getModifyQueryResults("FOR d IN @@cn UPDATE d IN @@cn", { "@cn": cn1 }); var actual = getModifyQueryResults("FOR d IN @@cn UPDATE d IN @@cn", { "@cn": cn1 });
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
for (var i = 0; i < 100; ++i) { for (var i = 0; i < 100; ++i) {
var doc = c1.document("test" + i); var doc = c1.document("test" + i);
assertEqual(i, doc.value1); assertEqual(i, doc.value1);
@ -956,11 +963,11 @@ function ahuacatlUpdateSuite () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testSingle : function () { testSingle : function () {
var expected = { executed: 1, ignored: 0 }; var expected = { writesExecuted: 1, writesIgnored: 0 };
var actual = getModifyQueryResults("UPDATE { value: 'foobar', _key: 'test17' } IN @@cn", { "@cn": cn1 }); var actual = getModifyQueryResults("UPDATE { value: 'foobar', _key: 'test17' } IN @@cn", { "@cn": cn1 });
assertEqual("foobar", c1.document("test17").value); assertEqual("foobar", c1.document("test17").value);
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -968,9 +975,9 @@ function ahuacatlUpdateSuite () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testUpdateOldValue : function () { testUpdateOldValue : function () {
var expected = { executed: 100, ignored: 0 }; var expected = { writesExecuted: 100, writesIgnored: 0 };
var actual = getModifyQueryResults("FOR d IN @@cn UPDATE { _key: d._key, value1: d.value2, value2: d.value1, value3: d.value1 + 5 } IN @@cn", { "@cn": cn1 }); var actual = getModifyQueryResults("FOR d IN @@cn UPDATE { _key: d._key, value1: d.value2, value2: d.value1, value3: d.value1 + 5 } IN @@cn", { "@cn": cn1 });
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
for (var i = 0; i < 100; ++i) { for (var i = 0; i < 100; ++i) {
var doc = c1.document("test" + i); var doc = c1.document("test" + i);
@ -985,9 +992,9 @@ function ahuacatlUpdateSuite () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testUpdateWaitForSync : function () { testUpdateWaitForSync : function () {
var expected = { executed: 50, ignored: 0 }; var expected = { writesExecuted: 50, writesIgnored: 0 };
var actual = getModifyQueryResults("FOR i IN 1..50 UPDATE { _key: CONCAT('test', TO_STRING(i)) } INTO @@cn OPTIONS { waitForSync: true }", { "@cn": cn1 }); var actual = getModifyQueryResults("FOR i IN 1..50 UPDATE { _key: CONCAT('test', TO_STRING(i)) } INTO @@cn OPTIONS { waitForSync: true }", { "@cn": cn1 });
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
for (var i = 0; i < 100; ++i) { for (var i = 0; i < 100; ++i) {
var doc = c1.document("test" + i); var doc = c1.document("test" + i);
@ -1001,9 +1008,9 @@ function ahuacatlUpdateSuite () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testUpdateKeepNullDefault : function () { testUpdateKeepNullDefault : function () {
var expected = { executed: 100, ignored: 0 }; var expected = { writesExecuted: 100, writesIgnored: 0 };
var actual = getModifyQueryResults("FOR d IN @@cn UPDATE d._key WITH { value1: null, value3: 'foobar', value9: null } INTO @@cn", { "@cn": cn1 }); var actual = getModifyQueryResults("FOR d IN @@cn UPDATE d._key WITH { value1: null, value3: 'foobar', value9: null } INTO @@cn", { "@cn": cn1 });
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
for (var i = 0; i < 100; ++i) { for (var i = 0; i < 100; ++i) {
var doc = c1.document("test" + i); var doc = c1.document("test" + i);
@ -1019,9 +1026,9 @@ function ahuacatlUpdateSuite () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testUpdateKeepNullTrue : function () { testUpdateKeepNullTrue : function () {
var expected = { executed: 100, ignored: 0 }; var expected = { writesExecuted: 100, writesIgnored: 0 };
var actual = getModifyQueryResults("FOR d IN @@cn UPDATE d._key WITH { value1: null, value3: 'foobar', value9: null } INTO @@cn OPTIONS { keepNull: true }", { "@cn": cn1 }); var actual = getModifyQueryResults("FOR d IN @@cn UPDATE d._key WITH { value1: null, value3: 'foobar', value9: null } INTO @@cn OPTIONS { keepNull: true }", { "@cn": cn1 });
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
for (var i = 0; i < 100; ++i) { for (var i = 0; i < 100; ++i) {
var doc = c1.document("test" + i); var doc = c1.document("test" + i);
@ -1037,9 +1044,9 @@ function ahuacatlUpdateSuite () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testUpdateKeepNullFalse : function () { testUpdateKeepNullFalse : function () {
var expected = { executed: 100, ignored: 0 }; var expected = { writesExecuted: 100, writesIgnored: 0 };
var actual = getModifyQueryResults("FOR d IN @@cn UPDATE d._key WITH { value1: null, value3: 'foobar', value9: null } INTO @@cn OPTIONS { keepNull: false }", { "@cn": cn1 }); var actual = getModifyQueryResults("FOR d IN @@cn UPDATE d._key WITH { value1: null, value3: 'foobar', value9: null } INTO @@cn OPTIONS { keepNull: false }", { "@cn": cn1 });
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
for (var i = 0; i < 100; ++i) { for (var i = 0; i < 100; ++i) {
var doc = c1.document("test" + i); var doc = c1.document("test" + i);
@ -1055,9 +1062,9 @@ function ahuacatlUpdateSuite () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testUpdateFilter : function () { testUpdateFilter : function () {
var expected = { executed: 50, ignored: 0 }; var expected = { writesExecuted: 50, writesIgnored: 0 };
var actual = getModifyQueryResults("FOR d IN @@cn FILTER d.value1 % 2 == 0 UPDATE d._key WITH { value2: 100 } INTO @@cn", { "@cn": cn1 }); var actual = getModifyQueryResults("FOR d IN @@cn FILTER d.value1 % 2 == 0 UPDATE d._key WITH { value2: 100 } INTO @@cn", { "@cn": cn1 });
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
for (var i = 0; i < 100; ++i) { for (var i = 0; i < 100; ++i) {
var doc = c1.document("test" + i); var doc = c1.document("test" + i);
@ -1076,10 +1083,10 @@ function ahuacatlUpdateSuite () {
testUpdateUpdate : function () { testUpdateUpdate : function () {
var i; var i;
var expected = { executed: 100, ignored: 0 }; var expected = { writesExecuted: 100, writesIgnored: 0 };
for (i = 0; i < 5; ++i) { for (i = 0; i < 5; ++i) {
var actual = getModifyQueryResults("FOR d IN @@cn UPDATE d._key WITH { counter: HAS(d, 'counter') ? d.counter + 1 : 1 } INTO @@cn", { "@cn": cn1 }); var actual = getModifyQueryResults("FOR d IN @@cn UPDATE d._key WITH { counter: HAS(d, 'counter') ? d.counter + 1 : 1 } INTO @@cn", { "@cn": cn1 });
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
} }
for (i = 0; i < 100; ++i) { for (i = 0; i < 100; ++i) {
@ -1094,10 +1101,10 @@ function ahuacatlUpdateSuite () {
testReplace1 : function () { testReplace1 : function () {
var i; var i;
var expected = { executed: 100, ignored: 0 }; var expected = { writesExecuted: 100, writesIgnored: 0 };
for (i = 0; i < 5; ++i) { for (i = 0; i < 5; ++i) {
var actual = getModifyQueryResults("FOR d IN @@cn REPLACE d._key WITH { value4: 12 } INTO @@cn", { "@cn": cn1 }); var actual = getModifyQueryResults("FOR d IN @@cn REPLACE d._key WITH { value4: 12 } INTO @@cn", { "@cn": cn1 });
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
} }
for (i = 0; i < 100; ++i) { for (i = 0; i < 100; ++i) {
@ -1115,10 +1122,10 @@ function ahuacatlUpdateSuite () {
testReplace2 : function () { testReplace2 : function () {
var i; var i;
var expected = { executed: 100, ignored: 0 }; var expected = { writesExecuted: 100, writesIgnored: 0 };
for (i = 0; i < 5; ++i) { for (i = 0; i < 5; ++i) {
var actual = getModifyQueryResults("FOR d IN @@cn REPLACE { _key: d._key, value4: 13 } INTO @@cn", { "@cn": cn1 }); var actual = getModifyQueryResults("FOR d IN @@cn REPLACE { _key: d._key, value4: 13 } INTO @@cn", { "@cn": cn1 });
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
} }
for (i = 0; i < 100; ++i) { for (i = 0; i < 100; ++i) {
@ -1136,10 +1143,10 @@ function ahuacatlUpdateSuite () {
testReplaceReplace : function () { testReplaceReplace : function () {
var i; var i;
var expected = { executed: 100, ignored: 0 }; var expected = { writesExecuted: 100, writesIgnored: 0 };
for (i = 0; i < 5; ++i) { for (i = 0; i < 5; ++i) {
var actual = getModifyQueryResults("FOR d IN @@cn REPLACE d._key WITH { value1: d.value1 + 1 } INTO @@cn", { "@cn": cn1 }); var actual = getModifyQueryResults("FOR d IN @@cn REPLACE d._key WITH { value1: d.value1 + 1 } INTO @@cn", { "@cn": cn1 });
assertEqual(expected, actual.operations); assertEqual(expected, sanitizeStats(actual));
} }
for (i = 0; i < 100; ++i) { for (i = 0; i < 100; ++i) {

View File

@ -355,7 +355,6 @@ function ahuacatlRemoveSuite () {
assertEqual(expected, sanitizeStats(actual)); assertEqual(expected, sanitizeStats(actual));
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief test remove /// @brief test remove
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -4227,6 +4227,452 @@ function transactionServerFailuresSuite () {
internal.wait(0); internal.wait(0);
}, },
////////////////////////////////////////////////////////////////////////////////
/// @brief test: rollback in case of a server-side fail
////////////////////////////////////////////////////////////////////////////////
testInsertUniqueHashIndexServerFailures : function () {
var failures = [ "InsertPrimaryIndex", "InsertSecondaryIndexes", "InsertHashIndex" ];
failures.forEach (function (f) {
internal.debugClearFailAt();
db._drop(cn);
c = db._create(cn);
c.ensureUniqueConstraint("value");
internal.debugSetFailAt(f);
try {
c.save({ value: 1 });
fail();
}
catch (err) {
assertEqual(internal.errors.ERROR_DEBUG.code, err.errorNum);
}
assertEqual(0, c.count());
});
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test: rollback in case of a server-side fail
////////////////////////////////////////////////////////////////////////////////
testInsertUniqueHashIndexServerFailuresTrx : function () {
var failures = [ "InsertPrimaryIndex", "InsertSecondaryIndexes", "InsertHashIndex" ];
failures.forEach (function (f) {
internal.debugClearFailAt();
db._drop(cn);
c = db._create(cn);
c.ensureUniqueConstraint("value");
db._executeTransaction({
collections: {
write: cn
},
action: function () {
c.save({ value: 1 });
internal.debugSetFailAt(f);
try {
c.save({ value: 2 });
fail();
}
catch (err) {
assertEqual(internal.errors.ERROR_DEBUG.code, err.errorNum);
}
assertEqual(1, c.count());
internal.debugClearFailAt();
}
});
});
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test: rollback in case of a server-side fail
////////////////////////////////////////////////////////////////////////////////
testInsertUniqueHashIndexServerFailuresRollback : function () {
var failures = [ "InsertPrimaryIndex", "InsertSecondaryIndexes", "InsertHashIndex" ];
failures.forEach (function (f) {
internal.debugClearFailAt();
db._drop(cn);
c = db._create(cn);
c.ensureUniqueConstraint("value");
try {
db._executeTransaction({
collections: {
write: cn
},
action: function () {
c.save({ value: 1 });
internal.debugSetFailAt(f);
c.save({ value: 2 });
}
});
fail();
}
catch (err) {
assertEqual(internal.errors.ERROR_DEBUG.code, err.errorNum);
}
assertEqual(0, c.count());
internal.debugClearFailAt();
});
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test: rollback in case of a server-side fail
////////////////////////////////////////////////////////////////////////////////
testInsertNonUniqueHashIndexServerFailures : function () {
var failures = [ "InsertPrimaryIndex", "InsertSecondaryIndexes", "InsertHashIndex" ];
failures.forEach (function (f) {
internal.debugClearFailAt();
db._drop(cn);
c = db._create(cn);
c.ensureHashIndex("value");
internal.debugSetFailAt(f);
try {
c.save({ value: 1 });
fail();
}
catch (err) {
assertEqual(internal.errors.ERROR_DEBUG.code, err.errorNum);
}
assertEqual(0, c.count());
});
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test: rollback in case of a server-side fail
////////////////////////////////////////////////////////////////////////////////
testInsertNonUniqueHashIndexServerFailuresTrx : function () {
var failures = [ "InsertPrimaryIndex", "InsertSecondaryIndexes", "InsertHashIndex" ];
failures.forEach (function (f) {
internal.debugClearFailAt();
db._drop(cn);
c = db._create(cn);
c.ensureHashIndex("value");
db._executeTransaction({
collections: {
write: cn
},
action: function () {
c.save({ value: 1 });
internal.debugSetFailAt(f);
try {
c.save({ value: 2 });
fail();
}
catch (err) {
assertEqual(internal.errors.ERROR_DEBUG.code, err.errorNum);
}
assertEqual(1, c.count());
internal.debugClearFailAt();
}
});
});
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test: rollback in case of a server-side fail
////////////////////////////////////////////////////////////////////////////////
testInsertNonUniqueHashIndexServerFailuresRollback : function () {
var failures = [ "InsertPrimaryIndex", "InsertSecondaryIndexes", "InsertHashIndex" ];
failures.forEach (function (f) {
internal.debugClearFailAt();
db._drop(cn);
c = db._create(cn);
c.ensureHashIndex("value");
try {
db._executeTransaction({
collections: {
write: cn
},
action: function () {
c.save({ value: 1 });
internal.debugSetFailAt(f);
c.save({ value: 2 });
}
});
fail();
}
catch (err) {
assertEqual(internal.errors.ERROR_DEBUG.code, err.errorNum);
}
assertEqual(0, c.count());
internal.debugClearFailAt();
});
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test: rollback in case of a server-side fail
////////////////////////////////////////////////////////////////////////////////
testRemoveUniqueHashIndexServerFailures : function () {
var failures = [ "DeletePrimaryIndex", "DeleteSecondaryIndexes", "RemoveHashIndex" ];
failures.forEach (function (f) {
internal.debugClearFailAt();
db._drop(cn);
c = db._create(cn);
for (var i = 0; i < 1000; ++i) {
c.save({ value: i });
}
c.ensureUniqueConstraint("value");
internal.debugSetFailAt(f);
try {
c.truncate();
fail();
}
catch (err) {
assertEqual(internal.errors.ERROR_DEBUG.code, err.errorNum);
}
assertEqual(1000, c.count());
});
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test: rollback in case of a server-side fail
////////////////////////////////////////////////////////////////////////////////
testRemoveNonUniqueHashIndexServerFailures : function () {
var failures = [ "DeletePrimaryIndex", "DeleteSecondaryIndexes", "RemoveHashIndex" ];
failures.forEach (function (f) {
internal.debugClearFailAt();
db._drop(cn);
c = db._create(cn);
for (var i = 0; i < 1000; ++i) {
c.save({ value: i % 10 });
}
c.ensureHashIndex("value");
internal.debugSetFailAt(f);
try {
c.truncate();
fail();
}
catch (err) {
assertEqual(internal.errors.ERROR_DEBUG.code, err.errorNum);
}
assertEqual(1000, c.count());
});
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test: rollback in case of a server-side fail
////////////////////////////////////////////////////////////////////////////////
testRemoveNonUniqueHashIndexServerFailuresTrx : function () {
var failures = [ "DeletePrimaryIndex", "DeleteSecondaryIndexes", "RemoveHashIndex" ];
failures.forEach (function (f) {
internal.debugClearFailAt();
db._drop(cn);
c = db._create(cn);
c.ensureHashIndex("value");
for (var i = 0; i < 1000; ++i) {
c.save({ _key: "test" + i, value: i % 10 });
}
db._executeTransaction({
collections: {
write: cn
},
action: function () {
for (var j = 0; j < 10; ++j) {
c.remove("test" + j);
}
internal.debugSetFailAt(f);
try {
c.remove("test10");
fail();
}
catch (err) {
assertEqual(internal.errors.ERROR_DEBUG.code, err.errorNum);
}
}
});
assertEqual(990, c.count());
internal.debugClearFailAt();
});
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test: rollback in case of a server-side fail
////////////////////////////////////////////////////////////////////////////////
testRemoveNonUniqueHashIndexServerFailuresRollback : function () {
var failures = [ "DeletePrimaryIndex", "DeleteSecondaryIndexes", "RemoveHashIndex" ];
failures.forEach (function (f) {
internal.debugClearFailAt();
db._drop(cn);
c = db._create(cn);
for (var i = 0; i < 1000; ++i) {
c.save({ _key: "test" + i, value: i % 10 });
}
c.ensureHashIndex("value");
try {
db._executeTransaction({
collections: {
write: cn
},
action: function () {
for (var j = 0; j < 10; ++j) {
c.remove("test" + j);
}
internal.debugSetFailAt(f);
c.remove("test10");
}
});
fail();
}
catch (err) {
assertEqual(internal.errors.ERROR_DEBUG.code, err.errorNum);
}
assertEqual(1000, c.count());
internal.debugClearFailAt();
});
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test: rollback in case of a server-side fail
////////////////////////////////////////////////////////////////////////////////
testRemoveUniqueSkiplistServerFailures : function () {
var failures = [ "DeletePrimaryIndex", "DeleteSecondaryIndexes" ];
failures.forEach (function (f) {
internal.debugClearFailAt();
db._drop(cn);
c = db._create(cn);
for (var i = 0; i < 1000; ++i) {
c.save({ value: i });
}
c.ensureUniqueSkiplist("value");
internal.debugSetFailAt(f);
try {
c.truncate();
fail();
}
catch (err) {
assertEqual(internal.errors.ERROR_DEBUG.code, err.errorNum);
}
assertEqual(1000, c.count());
});
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test: rollback in case of a server-side fail
////////////////////////////////////////////////////////////////////////////////
testRemoveNonUniqueSkiplistServerFailures : function () {
var failures = [ "DeletePrimaryIndex", "DeleteSecondaryIndexes" ];
failures.forEach (function (f) {
internal.debugClearFailAt();
db._drop(cn);
c = db._create(cn);
for (var i = 0; i < 1000; ++i) {
c.save({ value: i % 10 });
}
c.ensureSkiplist("value");
internal.debugSetFailAt(f);
try {
c.truncate();
fail();
}
catch (err) {
assertEqual(internal.errors.ERROR_DEBUG.code, err.errorNum);
}
assertEqual(1000, c.count());
});
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test: rollback in case of a server-side fail
////////////////////////////////////////////////////////////////////////////////
testRemoveMultipleIndexesServerFailures : function () {
var failures = [ "DeletePrimaryIndex", "DeleteSecondaryIndexes", "RemoveHashIndex" ];
failures.forEach (function (f) {
internal.debugClearFailAt();
db._drop(cn);
c = db._create(cn);
for (var i = 0; i < 1000; ++i) {
c.save({ value: i % 10 });
}
c.ensureSkiplist("value");
c.ensureHashIndex("value");
internal.debugSetFailAt(f);
try {
c.truncate();
fail();
}
catch (err) {
assertEqual(internal.errors.ERROR_DEBUG.code, err.errorNum);
}
assertEqual(1000, c.count());
});
},
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief test: rollback in case of a server-side fail /// @brief test: rollback in case of a server-side fail
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -5046,3 +5492,4 @@ return jsunity.done();
// mode: outline-minor // mode: outline-minor
// outline-regexp: "\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @\\}\\)" // outline-regexp: "\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @\\}\\)"
// End: // End: