mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'devel' of github.com:triAGENS/ArangoDB into devel
This commit is contained in:
commit
6bf1d00d18
|
@ -15,6 +15,8 @@ v1.4
|
||||||
v1.3.1 (2013-XX-XX)
|
v1.3.1 (2013-XX-XX)
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
|
* issue #530: ReferenceError: ArangoError is not a constructor
|
||||||
|
|
||||||
* issue #535: Problem with AQL user functions javascript API
|
* issue #535: Problem with AQL user functions javascript API
|
||||||
|
|
||||||
* set --javascript.app-path for test execution to prevent startup error
|
* set --javascript.app-path for test execution to prevent startup error
|
||||||
|
|
|
@ -28,7 +28,11 @@ start () {
|
||||||
chown arangodb $PIDDIR
|
chown arangodb $PIDDIR
|
||||||
|
|
||||||
$DAEMON -c $CONF --pid-file "$PIDFILE" --supervisor $@
|
$DAEMON -c $CONF --pid-file "$PIDFILE" --supervisor $@
|
||||||
log_end_msg $?
|
RETVAL=$?
|
||||||
|
|
||||||
|
log_end_msg $RETVAL
|
||||||
|
|
||||||
|
return $RETVAL
|
||||||
}
|
}
|
||||||
|
|
||||||
case "$1" in
|
case "$1" in
|
||||||
|
@ -36,25 +40,30 @@ case "$1" in
|
||||||
log_daemon_msg "Starting $DESC" "$NAME"
|
log_daemon_msg "Starting $DESC" "$NAME"
|
||||||
|
|
||||||
start
|
start
|
||||||
|
exit $?
|
||||||
;;
|
;;
|
||||||
|
|
||||||
stop)
|
stop)
|
||||||
log_daemon_msg "Stopping $DESC" "$NAME"
|
log_daemon_msg "Stopping $DESC" "$NAME"
|
||||||
|
|
||||||
start-stop-daemon --stop --quiet --oknodo --exec $DAEMON --startas $DAEMON
|
start-stop-daemon --stop --quiet --oknodo --exec $DAEMON --startas $DAEMON
|
||||||
log_end_msg $?
|
RETVAL=$?
|
||||||
|
log_end_msg $RETVAL
|
||||||
|
|
||||||
test -f $PIDFILE && rm -f $PIDFILE
|
test -f $PIDFILE && rm -f $PIDFILE
|
||||||
|
exit $RETVAL
|
||||||
;;
|
;;
|
||||||
|
|
||||||
restart)
|
restart)
|
||||||
$0 stop
|
$0 stop
|
||||||
sleep 3
|
sleep 3
|
||||||
$0 start
|
$0 start
|
||||||
|
exit $?
|
||||||
;;
|
;;
|
||||||
|
|
||||||
force-reload)
|
force-reload)
|
||||||
$0 restart
|
$0 restart
|
||||||
|
exit $?
|
||||||
;;
|
;;
|
||||||
|
|
||||||
status)
|
status)
|
||||||
|
@ -65,6 +74,7 @@ case "$1" in
|
||||||
log_daemon_msg "Upgrading $DESC" "$NAME"
|
log_daemon_msg "Upgrading $DESC" "$NAME"
|
||||||
|
|
||||||
start --upgrade
|
start --upgrade
|
||||||
|
exit $?
|
||||||
;;
|
;;
|
||||||
|
|
||||||
*)
|
*)
|
||||||
|
|
|
@ -786,6 +786,7 @@ static TRI_aql_node_t* OptimiseLimit (TRI_aql_statement_walker_t* const walker,
|
||||||
TRI_aql_node_t* node) {
|
TRI_aql_node_t* node) {
|
||||||
TRI_aql_scope_t* scope;
|
TRI_aql_scope_t* scope;
|
||||||
TRI_aql_node_t* limit;
|
TRI_aql_node_t* limit;
|
||||||
|
aql_optimiser_t* optimiser = (aql_optimiser_t*) walker->_data;
|
||||||
int64_t limitValue;
|
int64_t limitValue;
|
||||||
|
|
||||||
assert(node);
|
assert(node);
|
||||||
|
@ -794,7 +795,27 @@ static TRI_aql_node_t* OptimiseLimit (TRI_aql_statement_walker_t* const walker,
|
||||||
assert(scope);
|
assert(scope);
|
||||||
|
|
||||||
limit = TRI_AQL_NODE_MEMBER(node, 1);
|
limit = TRI_AQL_NODE_MEMBER(node, 1);
|
||||||
limitValue = TRI_AQL_NODE_INT(limit);
|
|
||||||
|
if (limit->_type != TRI_AQL_NODE_VALUE) {
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (limit->_value._type == TRI_AQL_TYPE_INT) {
|
||||||
|
limitValue = TRI_AQL_NODE_INT(limit);
|
||||||
|
}
|
||||||
|
else if (limit->_value._type == TRI_AQL_TYPE_DOUBLE) {
|
||||||
|
limitValue = (int64_t) TRI_AQL_NODE_DOUBLE(limit);
|
||||||
|
}
|
||||||
|
else if (limit->_value._type == TRI_AQL_TYPE_NULL) {
|
||||||
|
limitValue = 0;
|
||||||
|
}
|
||||||
|
else if (limit->_value._type == TRI_AQL_TYPE_BOOL) {
|
||||||
|
limitValue = (int64_t) TRI_AQL_NODE_BOOL(limit);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
TRI_SetErrorContextAql(optimiser->_context, TRI_ERROR_QUERY_NUMBER_OUT_OF_RANGE, NULL);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
// check for the easy case, a limit value of 0, e.g. LIMIT 10, 0
|
// check for the easy case, a limit value of 0, e.g. LIMIT 10, 0
|
||||||
if (limitValue == 0) {
|
if (limitValue == 0) {
|
||||||
|
|
|
@ -750,17 +750,20 @@ static int RollbackInsert (TRI_document_collection_t* document,
|
||||||
|
|
||||||
static int RollbackUpdate (TRI_document_collection_t* document,
|
static int RollbackUpdate (TRI_document_collection_t* document,
|
||||||
TRI_doc_mptr_t* newHeader,
|
TRI_doc_mptr_t* newHeader,
|
||||||
TRI_doc_mptr_t* oldHeader) {
|
TRI_doc_mptr_t* oldHeader,
|
||||||
|
bool adjustHeader) {
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
assert(newHeader != NULL);
|
assert(newHeader != NULL);
|
||||||
assert(oldHeader != NULL);
|
assert(oldHeader != NULL);
|
||||||
|
|
||||||
// ignore any errors we're getting from this
|
// ignore any errors we're getting from this
|
||||||
DeleteSecondaryIndexes(document, newHeader, true);
|
DeleteSecondaryIndexes(document, newHeader, true);
|
||||||
|
|
||||||
// put back the header into its old position
|
if (adjustHeader) {
|
||||||
document->_headers->move(document->_headers, newHeader, oldHeader);
|
// put back the header into its old position
|
||||||
|
document->_headers->move(document->_headers, newHeader, oldHeader);
|
||||||
|
}
|
||||||
|
|
||||||
*newHeader = *oldHeader;
|
*newHeader = *oldHeader;
|
||||||
|
|
||||||
|
@ -779,7 +782,8 @@ static int RollbackUpdate (TRI_document_collection_t* document,
|
||||||
|
|
||||||
static int RollbackRemove (TRI_document_collection_t* document,
|
static int RollbackRemove (TRI_document_collection_t* document,
|
||||||
TRI_doc_mptr_t* newHeader,
|
TRI_doc_mptr_t* newHeader,
|
||||||
TRI_doc_mptr_t* oldHeader) {
|
TRI_doc_mptr_t* oldHeader,
|
||||||
|
bool adjustHeader) {
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
// there is no new header
|
// there is no new header
|
||||||
|
@ -794,8 +798,10 @@ static int RollbackRemove (TRI_document_collection_t* document,
|
||||||
LOG_ERROR("error rolling back remove operation");
|
LOG_ERROR("error rolling back remove operation");
|
||||||
}
|
}
|
||||||
|
|
||||||
// put back the header into its old position
|
if (adjustHeader) {
|
||||||
document->_headers->relink(document->_headers, oldHeader, oldHeader);
|
// put back the header into its old position
|
||||||
|
document->_headers->relink(document->_headers, oldHeader, oldHeader);
|
||||||
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -851,7 +857,7 @@ static int InsertDocument (TRI_transaction_collection_t* trxCollection,
|
||||||
TRI_doc_mptr_t* mptr,
|
TRI_doc_mptr_t* mptr,
|
||||||
bool* freeMarker) {
|
bool* freeMarker) {
|
||||||
TRI_document_collection_t* document;
|
TRI_document_collection_t* document;
|
||||||
bool written;
|
bool directOperation;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
TRI_ASSERT_MAINTAINER(*freeMarker == true);
|
TRI_ASSERT_MAINTAINER(*freeMarker == true);
|
||||||
|
@ -893,8 +899,8 @@ static int InsertDocument (TRI_transaction_collection_t* trxCollection,
|
||||||
&marker->base,
|
&marker->base,
|
||||||
totalSize,
|
totalSize,
|
||||||
forceSync,
|
forceSync,
|
||||||
&written);
|
&directOperation);
|
||||||
if (! written) {
|
if (! directOperation) {
|
||||||
*freeMarker = false;
|
*freeMarker = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -918,11 +924,13 @@ static int InsertDocument (TRI_transaction_collection_t* trxCollection,
|
||||||
idx->postInsert(trxCollection, idx, header);
|
idx->postInsert(trxCollection, idx, header);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return TRI_ERROR_NO_ERROR;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
// something has failed.... now delete from the indexes again
|
// something has failed.... now delete from the indexes again
|
||||||
RollbackInsert(document, header, NULL);
|
RollbackInsert(document, header, NULL);
|
||||||
}
|
TRI_ASSERT_MAINTAINER(*freeMarker == true);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -988,7 +996,7 @@ static int RemoveDocument (TRI_transaction_collection_t* trxCollection,
|
||||||
TRI_primary_collection_t* primary;
|
TRI_primary_collection_t* primary;
|
||||||
TRI_document_collection_t* document;
|
TRI_document_collection_t* document;
|
||||||
TRI_doc_mptr_t* header;
|
TRI_doc_mptr_t* header;
|
||||||
bool written;
|
bool directOperation;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
TRI_ASSERT_MAINTAINER(*freeMarker == true);
|
TRI_ASSERT_MAINTAINER(*freeMarker == true);
|
||||||
|
@ -1048,22 +1056,24 @@ static int RemoveDocument (TRI_transaction_collection_t* trxCollection,
|
||||||
&marker->base,
|
&marker->base,
|
||||||
totalSize,
|
totalSize,
|
||||||
forceSync,
|
forceSync,
|
||||||
&written);
|
&directOperation);
|
||||||
|
|
||||||
if (! written) {
|
if (! directOperation) {
|
||||||
*freeMarker = false;
|
*freeMarker = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res == TRI_ERROR_NO_ERROR) {
|
if (res == TRI_ERROR_NO_ERROR) {
|
||||||
if (written) {
|
if (directOperation) {
|
||||||
// release the header pointer
|
// release the header pointer
|
||||||
document->_headers->release(document->_headers, header);
|
document->_headers->release(document->_headers, header);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return TRI_ERROR_NO_ERROR;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
// deletion failed. roll back
|
// deletion failed. roll back
|
||||||
RollbackRemove(document, NULL, header);
|
RollbackRemove(document, NULL, header, ! directOperation);
|
||||||
}
|
TRI_ASSERT_MAINTAINER(*freeMarker == true);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -1153,7 +1163,7 @@ static int UpdateDocument (TRI_transaction_collection_t* trxCollection,
|
||||||
TRI_doc_mptr_t* newHeader;
|
TRI_doc_mptr_t* newHeader;
|
||||||
TRI_doc_mptr_t oldData;
|
TRI_doc_mptr_t oldData;
|
||||||
int res;
|
int res;
|
||||||
bool written;
|
bool directOperation;
|
||||||
|
|
||||||
TRI_ASSERT_MAINTAINER(*freeMarker == true);
|
TRI_ASSERT_MAINTAINER(*freeMarker == true);
|
||||||
document = (TRI_document_collection_t*) trxCollection->_collection->_collection;
|
document = (TRI_document_collection_t*) trxCollection->_collection->_collection;
|
||||||
|
@ -1215,23 +1225,25 @@ static int UpdateDocument (TRI_transaction_collection_t* trxCollection,
|
||||||
&marker->base,
|
&marker->base,
|
||||||
totalSize,
|
totalSize,
|
||||||
forceSync,
|
forceSync,
|
||||||
&written);
|
&directOperation);
|
||||||
|
|
||||||
if (! written) {
|
if (! directOperation) {
|
||||||
*freeMarker = false;
|
*freeMarker = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res == TRI_ERROR_NO_ERROR) {
|
if (res == TRI_ERROR_NO_ERROR) {
|
||||||
if (written) {
|
if (directOperation) {
|
||||||
document->_headers->moveBack(document->_headers, oldHeader);
|
document->_headers->moveBack(document->_headers, oldHeader);
|
||||||
}
|
}
|
||||||
|
|
||||||
// write new header into result
|
// write new header into result
|
||||||
*mptr = *((TRI_doc_mptr_t*) newHeader);
|
*mptr = *((TRI_doc_mptr_t*) newHeader);
|
||||||
|
|
||||||
|
return TRI_ERROR_NO_ERROR;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
RollbackUpdate(document, newHeader, &oldData);
|
RollbackUpdate(document, newHeader, &oldData, ! directOperation);
|
||||||
}
|
TRI_ASSERT_MAINTAINER(*freeMarker == true);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -2988,10 +3000,10 @@ int TRI_RollbackOperationDocumentCollection (TRI_document_collection_t* document
|
||||||
res = RollbackInsert(document, newHeader, NULL);
|
res = RollbackInsert(document, newHeader, NULL);
|
||||||
}
|
}
|
||||||
else if (type == TRI_VOC_DOCUMENT_OPERATION_UPDATE) {
|
else if (type == TRI_VOC_DOCUMENT_OPERATION_UPDATE) {
|
||||||
res = RollbackUpdate(document, newHeader, oldData);
|
res = RollbackUpdate(document, newHeader, oldData, true);
|
||||||
}
|
}
|
||||||
else if (type == TRI_VOC_DOCUMENT_OPERATION_REMOVE) {
|
else if (type == TRI_VOC_DOCUMENT_OPERATION_REMOVE) {
|
||||||
res = RollbackRemove(document, NULL, oldHeader);
|
res = RollbackRemove(document, NULL, oldHeader, true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
res = TRI_ERROR_INTERNAL;
|
res = TRI_ERROR_INTERNAL;
|
||||||
|
@ -3057,6 +3069,10 @@ int TRI_WriteOperationDocumentCollection (TRI_document_collection_t* document,
|
||||||
bool waitForSync) {
|
bool waitForSync) {
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
|
TRI_DEBUG_INTENTIONAL_FAIL_IF("TRI_WriteOperationDocumentCollection") {
|
||||||
|
return TRI_ERROR_INTERNAL;
|
||||||
|
}
|
||||||
|
|
||||||
if (type == TRI_VOC_DOCUMENT_OPERATION_INSERT) {
|
if (type == TRI_VOC_DOCUMENT_OPERATION_INSERT) {
|
||||||
res = WriteInsertMarker(document, (TRI_doc_document_key_marker_t*) marker, newHeader, totalSize, waitForSync);
|
res = WriteInsertMarker(document, (TRI_doc_document_key_marker_t*) marker, newHeader, totalSize, waitForSync);
|
||||||
}
|
}
|
||||||
|
|
|
@ -234,29 +234,38 @@ static void MoveHeader (TRI_headers_t* h,
|
||||||
if (old->_prev == NULL) {
|
if (old->_prev == NULL) {
|
||||||
headers->_begin = header;
|
headers->_begin = header;
|
||||||
}
|
}
|
||||||
|
else if (headers->_begin == header) {
|
||||||
|
if (header->_next != NULL) {
|
||||||
|
headers->_begin = header->_next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (old->_next == NULL) {
|
if (old->_next == NULL) {
|
||||||
headers->_end = header;
|
headers->_end = header;
|
||||||
}
|
}
|
||||||
if (header->_prev != NULL && header->_prev == old->_next) {
|
else if (headers->_end == header) {
|
||||||
header->_prev->_next = NULL;
|
if (header->_prev != NULL) {
|
||||||
headers->_end = header->_prev;
|
headers->_end = header->_prev;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (header->_next != NULL && header->_next == old->_prev) {
|
|
||||||
header->_next->_prev = NULL;
|
if (header->_prev != NULL) {
|
||||||
headers->_begin = header->_next;
|
if (header->_prev == old->_next) {
|
||||||
|
header->_prev->_next = NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
header->_prev->_next = header->_next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
if (headers->_begin == old->_next) {
|
if (header->_next != NULL) {
|
||||||
// adjust list start pointer
|
if (header->_next == old->_prev) {
|
||||||
headers->_begin = header;
|
header->_next->_prev = NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
header->_next->_prev = header->_prev;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
/*
|
|
||||||
if (old->_next == NULL) {
|
|
||||||
// adjust list end pointer
|
|
||||||
headers->_end = header;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (old->_prev != NULL) {
|
if (old->_prev != NULL) {
|
||||||
old->_prev->_next = header;
|
old->_prev->_next = header;
|
||||||
|
@ -273,11 +282,7 @@ static void MoveHeader (TRI_headers_t* h,
|
||||||
else {
|
else {
|
||||||
header->_next = NULL;
|
header->_next = NULL;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
header->_prev = old->_prev;
|
|
||||||
header->_next = old->_next;
|
|
||||||
*/
|
|
||||||
|
|
||||||
TRI_ASSERT_MAINTAINER(headers->_begin != NULL);
|
TRI_ASSERT_MAINTAINER(headers->_begin != NULL);
|
||||||
TRI_ASSERT_MAINTAINER(headers->_end != NULL);
|
TRI_ASSERT_MAINTAINER(headers->_end != NULL);
|
||||||
TRI_ASSERT_MAINTAINER(header->_prev != header);
|
TRI_ASSERT_MAINTAINER(header->_prev != header);
|
||||||
|
|
|
@ -491,12 +491,15 @@ static int AddCollectionOperation (TRI_transaction_collection_t* trxCollection,
|
||||||
transaction_operation_t trxOperation;
|
transaction_operation_t trxOperation;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
|
TRI_DEBUG_INTENTIONAL_FAIL_IF("AddCollectionOperation-OOM") {
|
||||||
|
return TRI_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
if (trxCollection->_operations == NULL) {
|
if (trxCollection->_operations == NULL) {
|
||||||
res = InitCollectionOperations(trxCollection);
|
res = InitCollectionOperations(trxCollection);
|
||||||
|
|
||||||
if (res != TRI_ERROR_NO_ERROR) {
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
return res;
|
return TRI_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -514,21 +517,23 @@ static int AddCollectionOperation (TRI_transaction_collection_t* trxCollection,
|
||||||
}
|
}
|
||||||
|
|
||||||
res = TRI_PushBackVector(trxCollection->_operations, &trxOperation);
|
res = TRI_PushBackVector(trxCollection->_operations, &trxOperation);
|
||||||
|
|
||||||
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
|
return TRI_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
if (res == TRI_ERROR_NO_ERROR) {
|
if (type == TRI_VOC_DOCUMENT_OPERATION_UPDATE) {
|
||||||
if (type == TRI_VOC_DOCUMENT_OPERATION_UPDATE) {
|
TRI_document_collection_t* document = (TRI_document_collection_t*) trxCollection->_collection->_collection;
|
||||||
TRI_document_collection_t* document = (TRI_document_collection_t*) trxCollection->_collection->_collection;
|
|
||||||
|
|
||||||
document->_headers->moveBack(document->_headers, oldHeader);
|
document->_headers->moveBack(document->_headers, oldHeader);
|
||||||
}
|
}
|
||||||
else if (type == TRI_VOC_DOCUMENT_OPERATION_REMOVE) {
|
else if (type == TRI_VOC_DOCUMENT_OPERATION_REMOVE) {
|
||||||
TRI_document_collection_t* document = (TRI_document_collection_t*) trxCollection->_collection->_collection;
|
TRI_document_collection_t* document = (TRI_document_collection_t*) trxCollection->_collection->_collection;
|
||||||
|
|
||||||
document->_headers->unlink(document->_headers, oldHeader);
|
document->_headers->unlink(document->_headers, oldHeader);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return TRI_ERROR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -1687,7 +1692,7 @@ int TRI_AddOperationCollectionTransaction (TRI_transaction_collection_t* trxColl
|
||||||
TRI_df_marker_t* marker,
|
TRI_df_marker_t* marker,
|
||||||
size_t totalSize,
|
size_t totalSize,
|
||||||
bool syncRequested,
|
bool syncRequested,
|
||||||
bool* written) {
|
bool* directOperation) {
|
||||||
TRI_transaction_t* trx;
|
TRI_transaction_t* trx;
|
||||||
TRI_primary_collection_t* primary;
|
TRI_primary_collection_t* primary;
|
||||||
int res;
|
int res;
|
||||||
|
@ -1699,13 +1704,8 @@ int TRI_AddOperationCollectionTransaction (TRI_transaction_collection_t* trxColl
|
||||||
trxCollection->_originalRevision = primary->base._info._tick;
|
trxCollection->_originalRevision = primary->base._info._tick;
|
||||||
}
|
}
|
||||||
|
|
||||||
// the tick value of a marker must always be greater than the tick value of any other
|
|
||||||
// existing marker in the collection
|
|
||||||
TRI_SetRevisionDocumentCollection((TRI_document_collection_t*) primary, marker->_tick);
|
|
||||||
|
|
||||||
if (trx->_hints & ((TRI_transaction_hint_t) TRI_TRANSACTION_HINT_SINGLE_OPERATION)) {
|
if (trx->_hints & ((TRI_transaction_hint_t) TRI_TRANSACTION_HINT_SINGLE_OPERATION)) {
|
||||||
// just one operation in the transaction. we can write the marker directly
|
// just one operation in the transaction. we can write the marker directly
|
||||||
// TODO: error checking
|
|
||||||
res = TRI_WriteOperationDocumentCollection((TRI_document_collection_t*) primary,
|
res = TRI_WriteOperationDocumentCollection((TRI_document_collection_t*) primary,
|
||||||
type,
|
type,
|
||||||
newHeader,
|
newHeader,
|
||||||
|
@ -1714,14 +1714,22 @@ int TRI_AddOperationCollectionTransaction (TRI_transaction_collection_t* trxColl
|
||||||
marker,
|
marker,
|
||||||
totalSize,
|
totalSize,
|
||||||
syncRequested || trxCollection->_waitForSync || trx->_waitForSync);
|
syncRequested || trxCollection->_waitForSync || trx->_waitForSync);
|
||||||
*written = true;
|
*directOperation = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
trx->_hasOperations = true;
|
trx->_hasOperations = true;
|
||||||
|
|
||||||
res = AddCollectionOperation(trxCollection, type, newHeader, oldHeader, oldData, marker, totalSize);
|
res = AddCollectionOperation(trxCollection, type, newHeader, oldHeader, oldData, marker, totalSize);
|
||||||
|
|
||||||
*written = false;
|
if (res == TRI_ERROR_NO_ERROR) {
|
||||||
|
// if everything went well, this will ensure we don't double free etc. headers
|
||||||
|
*directOperation = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
TRI_ASSERT_MAINTAINER(res == TRI_ERROR_OUT_OF_MEMORY);
|
||||||
|
// if something went wrong, this will ensure that we'll not manipulate headers twice
|
||||||
|
*directOperation = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (syncRequested) {
|
if (syncRequested) {
|
||||||
|
@ -1732,6 +1740,14 @@ int TRI_AddOperationCollectionTransaction (TRI_transaction_collection_t* trxColl
|
||||||
trx->_waitForSync = true;
|
trx->_waitForSync = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (res == TRI_ERROR_NO_ERROR) {
|
||||||
|
// operation succeeded, now update the revision id for the collection
|
||||||
|
|
||||||
|
// the tick value of a marker must always be greater than the tick value of any other
|
||||||
|
// existing marker in the collection
|
||||||
|
TRI_SetRevisionDocumentCollection((TRI_document_collection_t*) primary, marker->_tick);
|
||||||
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Droid Sans';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: local('Droid Sans'), local('DroidSans'), url(/_admin/ttf/droidsans.ttf) format('truetype');
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Droid Sans';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
src: local('Droid Sans Bold'), local('DroidSans-Bold'), url(/_admin/ttf/droidsans-bold.ttf) format('truetype');
|
||||||
|
}
|
|
@ -8,7 +8,7 @@
|
||||||
<meta name="description" content="ArangoDB Admin Web Interface">
|
<meta name="description" content="ArangoDB Admin Web Interface">
|
||||||
<meta name="author" content="Heiko Kernbach">
|
<meta name="author" content="Heiko Kernbach">
|
||||||
|
|
||||||
<link href='http://fonts.googleapis.com/css?family=Droid+Sans:400,700' rel='stylesheet' type='text/css'/>
|
<link href='css/droidsans.css' rel='stylesheet' type='text/css'/>
|
||||||
<link href='css/swagger/hightlight.default.css' media='screen' rel='stylesheet' type='text/css'/>
|
<link href='css/swagger/hightlight.default.css' media='screen' rel='stylesheet' type='text/css'/>
|
||||||
<link href='css/swagger/screen.css' media='screen' rel='stylesheet' type='text/css'/>
|
<link href='css/swagger/screen.css' media='screen' rel='stylesheet' type='text/css'/>
|
||||||
|
|
||||||
|
@ -132,8 +132,6 @@
|
||||||
<script src="js/modules/org/arangodb/arango-collection-common.js"></script>
|
<script src="js/modules/org/arangodb/arango-collection-common.js"></script>
|
||||||
<script src="js/modules/org/arangodb/arango-collection.js"></script>
|
<script src="js/modules/org/arangodb/arango-collection.js"></script>
|
||||||
<script src="js/modules/org/arangodb/arango-database.js"></script>
|
<script src="js/modules/org/arangodb/arango-database.js"></script>
|
||||||
<script src="js/modules/org/arangodb/arango-error-common.js"></script>
|
|
||||||
<script src="js/modules/org/arangodb/arango-error.js"></script>
|
|
||||||
<script src="js/modules/org/arangodb/arango-query-cursor.js"></script>
|
<script src="js/modules/org/arangodb/arango-query-cursor.js"></script>
|
||||||
<script src="js/modules/org/arangodb/arango-statement-common.js"></script>
|
<script src="js/modules/org/arangodb/arango-statement-common.js"></script>
|
||||||
<script src="js/modules/org/arangodb/arango-statement.js"></script>
|
<script src="js/modules/org/arangodb/arango-statement.js"></script>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*jslint indent: 2, nomen: true, maxlen: 120, vars: true, white: true, plusplus: true, nonpropdel: true, proto: true, regexp: true */
|
/*jslint indent: 2, nomen: true, maxlen: 120, vars: true, white: true, plusplus: true, nonpropdel: true, proto: true, regexp: true */
|
||||||
/*global require, module, Module, ArangoError, SYS_DOWNLOAD,
|
/*global require, module, Module, ArangoError, SYS_DEBUG_SET_FAILAT, SYS_DEBUG_REMOVE_FAILAT,
|
||||||
|
SYS_DEBUG_CLEAR_FAILAT, SYS_DOWNLOAD,
|
||||||
SYS_EXECUTE, SYS_LOAD, SYS_LOG_LEVEL, SYS_MD5, SYS_OUTPUT, SYS_PROCESS_STATISTICS,
|
SYS_EXECUTE, SYS_LOAD, SYS_LOG_LEVEL, SYS_MD5, SYS_OUTPUT, SYS_PROCESS_STATISTICS,
|
||||||
SYS_RAND, SYS_SERVER_STATISTICS, SYS_SPRINTF, SYS_TIME, SYS_START_PAGER, SYS_STOP_PAGER,
|
SYS_RAND, SYS_SERVER_STATISTICS, SYS_SPRINTF, SYS_TIME, SYS_START_PAGER, SYS_STOP_PAGER,
|
||||||
SYS_SHA256, SYS_WAIT, SYS_PARSE, SYS_IMPORT_CSV_FILE, SYS_IMPORT_JSON_FILE, SYS_LOG,
|
SYS_SHA256, SYS_WAIT, SYS_PARSE, SYS_IMPORT_CSV_FILE, SYS_IMPORT_JSON_FILE, SYS_LOG,
|
||||||
|
@ -59,15 +60,23 @@
|
||||||
/// @brief ArangoError
|
/// @brief ArangoError
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
try {
|
if (typeof ArangoError !== "undefined") {
|
||||||
// necessary for the web interface
|
exports.ArangoError = ArangoError;
|
||||||
if (ArangoError !== undefined) {
|
delete ArangoError;
|
||||||
exports.ArangoError = ArangoError;
|
|
||||||
delete ArangoError;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (err) {
|
else {
|
||||||
exports.ArangoError = require("org/arangodb/arango-error").ArangoError;
|
exports.ArangoError = function (error) {
|
||||||
|
if (error !== undefined) {
|
||||||
|
this.error = error.error;
|
||||||
|
this.code = error.code;
|
||||||
|
this.errorNum = error.errorNum;
|
||||||
|
this.errorMessage = error.errorMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.message = this.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.ArangoError.prototype = Error.prototype;
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.ArangoError.prototype._PRINT = function (context) {
|
exports.ArangoError.prototype._PRINT = function (context) {
|
||||||
|
@ -216,6 +225,42 @@
|
||||||
// --SECTION-- public functions
|
// --SECTION-- public functions
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief debugSetFailAt
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
if (typeof SYS_DEBUG_SET_FAILAT !== "undefined") {
|
||||||
|
exports.debugSetFailAt = SYS_DEBUG_SET_FAILAT;
|
||||||
|
delete SYS_DEBUG_SET_FAILAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief debugRemoveFailAt
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
if (typeof SYS_DEBUG_REMOVE_FAILAT !== "undefined") {
|
||||||
|
exports.debugRemoveFailAt = SYS_DEBUG_REMOVE_FAILAT;
|
||||||
|
delete SYS_DEBUG_REMOVE_FAILAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief debugClearFailAt
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
if (typeof SYS_DEBUG_CLEAR_FAILAT !== "undefined") {
|
||||||
|
exports.debugClearFailAt = SYS_DEBUG_CLEAR_FAILAT;
|
||||||
|
delete SYS_DEBUG_CLEAR_FAILAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief debugCanUseFailAt
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
if (typeof SYS_DEBUG_CAN_USE_FAILAT !== "undefined") {
|
||||||
|
exports.debugCanUseFailAt = SYS_DEBUG_CAN_USE_FAILAT;
|
||||||
|
delete SYS_DEBUG_CAN_USE_FAILAT;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief download
|
/// @brief download
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -247,7 +247,7 @@ var unregisterFunctionsGroup = function (group) {
|
||||||
/// @fn JSF_aqlfunctions_register
|
/// @fn JSF_aqlfunctions_register
|
||||||
/// @brief register an AQL user function
|
/// @brief register an AQL user function
|
||||||
///
|
///
|
||||||
/// @FUN{aqlfunctions.register(@FA{name}, @FA{code}, @FA{isDeterministic}, @FA{testValues})}
|
/// @FUN{aqlfunctions.register(@FA{name}, @FA{code}, @FA{isDeterministic})}
|
||||||
///
|
///
|
||||||
/// Registers an AQL user function, identified by a fully qualified function
|
/// Registers an AQL user function, identified by a fully qualified function
|
||||||
/// name. The function code in @FA{code} must be specified as a Javascript
|
/// name. The function code in @FA{code} must be specified as a Javascript
|
||||||
|
@ -280,7 +280,7 @@ var registerFunction = function (name, code, isDeterministic) {
|
||||||
var testCode = "(function() { var callback = " + code + "; return callback; })()";
|
var testCode = "(function() { var callback = " + code + "; return callback; })()";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var res = INTERNAL.executeScript(testCode, undefined, "(user function " + name + ")");
|
var res = internal.executeScript(testCode, undefined, "(user function " + name + ")");
|
||||||
}
|
}
|
||||||
catch (err1) {
|
catch (err1) {
|
||||||
var err = new ArangoError();
|
var err = new ArangoError();
|
||||||
|
|
|
@ -1,81 +0,0 @@
|
||||||
module.define("org/arangodb/arango-error-common", function(exports, module) {
|
|
||||||
/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, white: true, plusplus: true */
|
|
||||||
/*global require */
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief ArangoError
|
|
||||||
///
|
|
||||||
/// @file
|
|
||||||
///
|
|
||||||
/// DISCLAIMER
|
|
||||||
///
|
|
||||||
/// Copyright 2013 triagens GmbH, Cologne, Germany
|
|
||||||
///
|
|
||||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
/// you may not use this file except in compliance with the License.
|
|
||||||
/// You may obtain a copy of the License at
|
|
||||||
///
|
|
||||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
///
|
|
||||||
/// Unless required by applicable law or agreed to in writing, software
|
|
||||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
/// See the License for the specific language governing permissions and
|
|
||||||
/// limitations under the License.
|
|
||||||
///
|
|
||||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
|
||||||
///
|
|
||||||
/// @author Achim Brandt
|
|
||||||
/// @author Dr. Frank Celler
|
|
||||||
/// @author Copyright 2012-2013, triAGENS GmbH, Cologne, Germany
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
var arangodb = require("org/arangodb");
|
|
||||||
|
|
||||||
var ArangoError = require("org/arangodb/arango-error").ArangoError;
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// --SECTION-- ArangoError
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// --SECTION-- private methods
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @addtogroup ArangoShell
|
|
||||||
/// @{
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief prints the object
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
ArangoError.prototype._PRINT = function (context) {
|
|
||||||
context.output += this.toString();
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief converts into a string
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
ArangoError.prototype.toString = function() {
|
|
||||||
var errorNum = this.errorNum;
|
|
||||||
var errorMessage = this.errorMessage;
|
|
||||||
|
|
||||||
return "[ArangoError " + errorNum + ": " + errorMessage + "]";
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @}
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// --SECTION-- END-OF-FILE
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Local Variables:
|
|
||||||
// mode: outline-minor
|
|
||||||
// outline-regexp: "/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @}\\|/\\*jslint"
|
|
||||||
// End:
|
|
||||||
});
|
|
|
@ -1,78 +0,0 @@
|
||||||
module.define("org/arangodb/arango-error", function(exports, module) {
|
|
||||||
/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, white: true, plusplus: true */
|
|
||||||
/*global require, exports */
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief ArangoError
|
|
||||||
///
|
|
||||||
/// @file
|
|
||||||
///
|
|
||||||
/// DISCLAIMER
|
|
||||||
///
|
|
||||||
/// Copyright 2013 triagens GmbH, Cologne, Germany
|
|
||||||
///
|
|
||||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
/// you may not use this file except in compliance with the License.
|
|
||||||
/// You may obtain a copy of the License at
|
|
||||||
///
|
|
||||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
///
|
|
||||||
/// Unless required by applicable law or agreed to in writing, software
|
|
||||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
/// See the License for the specific language governing permissions and
|
|
||||||
/// limitations under the License.
|
|
||||||
///
|
|
||||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
|
||||||
///
|
|
||||||
/// @author Achim Brandt
|
|
||||||
/// @author Dr. Frank Celler
|
|
||||||
/// @author Copyright 2012-2013, triAGENS GmbH, Cologne, Germany
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
var internal = require("internal");
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// --SECTION-- ArangoError
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// --SECTION-- constructors and destructors
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @addtogroup ArangoShell
|
|
||||||
/// @{
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief constructor
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
function ArangoError (error) {
|
|
||||||
if (error !== undefined) {
|
|
||||||
this.error = error.error;
|
|
||||||
this.code = error.code;
|
|
||||||
this.errorNum = error.errorNum;
|
|
||||||
this.errorMessage = error.errorMessage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.ArangoError = ArangoError;
|
|
||||||
|
|
||||||
// must be called after exporting ArangoError
|
|
||||||
require("org/arangodb/arango-error-common");
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @}
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// --SECTION-- END-OF-FILE
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Local Variables:
|
|
||||||
// mode: outline-minor
|
|
||||||
// outline-regexp: "/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @}\\|/\\*jslint"
|
|
||||||
// End:
|
|
||||||
});
|
|
|
@ -1,2 +1,2 @@
|
||||||
<div class="copy"><p>Copyright 2012 triAGENS GmbH | <a href="#about">About</a></p></div>
|
<div class="copy"><p>Copyright (c) triAGENS GmbH | <a href="#about">About</a></p></div>
|
||||||
|
|
||||||
|
|
|
@ -60,8 +60,15 @@ var dashboardView = Backbone.View.extend({
|
||||||
$(this.el).html(this.template.text);
|
$(this.el).html(this.template.text);
|
||||||
|
|
||||||
//Client calculated charts
|
//Client calculated charts
|
||||||
self.genCustomCategory("Client calculated charts", "custom", "Customized Charts");
|
self.genCustomCategories();
|
||||||
self.genCustomChart();
|
self.genCustomChartDescription(
|
||||||
|
"userTime + systemTime",
|
||||||
|
"custom",
|
||||||
|
"totalTime2",
|
||||||
|
"Total Time (User+System)",
|
||||||
|
"accumulated",
|
||||||
|
"seconds"
|
||||||
|
);
|
||||||
|
|
||||||
$.each(this.options.description.models[0].attributes.groups, function () {
|
$.each(this.options.description.models[0].attributes.groups, function () {
|
||||||
$('.thumbnails').append(
|
$('.thumbnails').append(
|
||||||
|
@ -98,6 +105,11 @@ var dashboardView = Backbone.View.extend({
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
//generate function for all custom categories
|
||||||
|
genCustomCategories: function () {
|
||||||
|
this.genCustomCategory("Client calculated charts", "custom", "Customized Charts");
|
||||||
|
},
|
||||||
|
//generate a custom category
|
||||||
genCustomCategory: function(description, group, name) {
|
genCustomCategory: function(description, group, name) {
|
||||||
this.options.description.models[0].attributes.groups.push({
|
this.options.description.models[0].attributes.groups.push({
|
||||||
"description":description,
|
"description":description,
|
||||||
|
@ -105,22 +117,26 @@ var dashboardView = Backbone.View.extend({
|
||||||
"name":name
|
"name":name
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
genCustomChart: function () {
|
//generate a custom description
|
||||||
//totalTime
|
genCustomChartDescription: function (description, group, identifier, name, type, units) {
|
||||||
var figure = {
|
var figure = {
|
||||||
"description" : "userTime + systemTime",
|
"description" : description,
|
||||||
"group" : "custom",
|
"group" : group,
|
||||||
"identifier" : "totalTime2",
|
"identifier" : identifier,
|
||||||
"name" : "Total Time (User+System)",
|
"name" : name,
|
||||||
"type" : "accumulated",
|
"type" : type,
|
||||||
"units" : "seconds"
|
"units" : units
|
||||||
};
|
};
|
||||||
this.options.description.models[0].attributes.figures.push(figure);
|
this.options.description.models[0].attributes.figures.push(figure);
|
||||||
this.renderFigure(figure);
|
this.renderFigure(figure);
|
||||||
},
|
},
|
||||||
|
//calculate customized chart value functions here
|
||||||
|
updateCustomChartValues: function () {
|
||||||
|
this.totalTime2();
|
||||||
|
},
|
||||||
|
|
||||||
updateCustomChart: function () {
|
//custom chart value calculation for totalTime2
|
||||||
//totalTime
|
totalTime2: function () {
|
||||||
var val1 = this.collection.models[0].attributes.system.userTime;
|
var val1 = this.collection.models[0].attributes.system.userTime;
|
||||||
var val2 = this.collection.models[0].attributes.system.systemTime;
|
var val2 = this.collection.models[0].attributes.system.systemTime;
|
||||||
var totalTime2Value = val1+val2;
|
var totalTime2Value = val1+val2;
|
||||||
|
@ -283,7 +299,7 @@ var dashboardView = Backbone.View.extend({
|
||||||
|
|
||||||
calculateSeries: function (flush) {
|
calculateSeries: function (flush) {
|
||||||
var self = this;
|
var self = this;
|
||||||
self.updateCustomChart();
|
self.updateCustomChartValues();
|
||||||
|
|
||||||
var timeStamp = Math.round(new Date() * 10);
|
var timeStamp = Math.round(new Date() * 10);
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,7 @@ var shellView = Backbone.View.extend({
|
||||||
var internal = require("internal");
|
var internal = require("internal");
|
||||||
var arangodb = require("org/arangodb");
|
var arangodb = require("org/arangodb");
|
||||||
var client = require("org/arangodb/arangosh");
|
var client = require("org/arangodb/arangosh");
|
||||||
var header = 'Welcome to arangosh Copyright (c) 2012 triAGENS GmbH.\n';
|
var header = 'Welcome to arangosh Copyright (c) triAGENS GmbH.\n';
|
||||||
window.jqconsole = $('#replShell').jqconsole(header, 'JSH> ', "...>");
|
window.jqconsole = $('#replShell').jqconsole(header, 'JSH> ', "...>");
|
||||||
this.executeJs(internal.print(client.HELP));
|
this.executeJs(internal.print(client.HELP));
|
||||||
// Abort prompt on Ctrl+Z.
|
// Abort prompt on Ctrl+Z.
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Swagger UI</title>
|
<title>Swagger UI</title>
|
||||||
<link href='http://fonts.googleapis.com/css?family=Droid+Sans:400,700' rel='stylesheet' type='text/css'/>
|
<link href='css/droidsans.css' rel='stylesheet' type='text/css'/>
|
||||||
<link href='css/swagger/hightlight.default.css' media='screen' rel='stylesheet' type='text/css'/>
|
<link href='css/swagger/hightlight.default.css' media='screen' rel='stylesheet' type='text/css'/>
|
||||||
<link href='css/swagger/screen.css' media='screen' rel='stylesheet' type='text/css'/>
|
<link href='css/swagger/screen.css' media='screen' rel='stylesheet' type='text/css'/>
|
||||||
<script src='js/lib/jquery-1.8.0.min.js' type='text/javascript'></script>
|
<script src='js/lib/jquery-1.8.0.min.js' type='text/javascript'></script>
|
||||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -1,5 +1,6 @@
|
||||||
/*jslint indent: 2, nomen: true, maxlen: 120, vars: true, white: true, plusplus: true, nonpropdel: true, proto: true, regexp: true */
|
/*jslint indent: 2, nomen: true, maxlen: 120, vars: true, white: true, plusplus: true, nonpropdel: true, proto: true, regexp: true */
|
||||||
/*global require, module, Module, ArangoError, SYS_DOWNLOAD,
|
/*global require, module, Module, ArangoError, SYS_DEBUG_SET_FAILAT, SYS_DEBUG_REMOVE_FAILAT,
|
||||||
|
SYS_DEBUG_CLEAR_FAILAT, SYS_DOWNLOAD,
|
||||||
SYS_EXECUTE, SYS_LOAD, SYS_LOG_LEVEL, SYS_MD5, SYS_OUTPUT, SYS_PROCESS_STATISTICS,
|
SYS_EXECUTE, SYS_LOAD, SYS_LOG_LEVEL, SYS_MD5, SYS_OUTPUT, SYS_PROCESS_STATISTICS,
|
||||||
SYS_RAND, SYS_SERVER_STATISTICS, SYS_SPRINTF, SYS_TIME, SYS_START_PAGER, SYS_STOP_PAGER,
|
SYS_RAND, SYS_SERVER_STATISTICS, SYS_SPRINTF, SYS_TIME, SYS_START_PAGER, SYS_STOP_PAGER,
|
||||||
SYS_SHA256, SYS_WAIT, SYS_PARSE, SYS_IMPORT_CSV_FILE, SYS_IMPORT_JSON_FILE, SYS_LOG,
|
SYS_SHA256, SYS_WAIT, SYS_PARSE, SYS_IMPORT_CSV_FILE, SYS_IMPORT_JSON_FILE, SYS_LOG,
|
||||||
|
@ -59,15 +60,23 @@
|
||||||
/// @brief ArangoError
|
/// @brief ArangoError
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
try {
|
if (typeof ArangoError !== "undefined") {
|
||||||
// necessary for the web interface
|
exports.ArangoError = ArangoError;
|
||||||
if (ArangoError !== undefined) {
|
delete ArangoError;
|
||||||
exports.ArangoError = ArangoError;
|
|
||||||
delete ArangoError;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (err) {
|
else {
|
||||||
exports.ArangoError = require("org/arangodb/arango-error").ArangoError;
|
exports.ArangoError = function (error) {
|
||||||
|
if (error !== undefined) {
|
||||||
|
this.error = error.error;
|
||||||
|
this.code = error.code;
|
||||||
|
this.errorNum = error.errorNum;
|
||||||
|
this.errorMessage = error.errorMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.message = this.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.ArangoError.prototype = Error.prototype;
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.ArangoError.prototype._PRINT = function (context) {
|
exports.ArangoError.prototype._PRINT = function (context) {
|
||||||
|
@ -216,6 +225,42 @@
|
||||||
// --SECTION-- public functions
|
// --SECTION-- public functions
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief debugSetFailAt
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
if (typeof SYS_DEBUG_SET_FAILAT !== "undefined") {
|
||||||
|
exports.debugSetFailAt = SYS_DEBUG_SET_FAILAT;
|
||||||
|
delete SYS_DEBUG_SET_FAILAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief debugRemoveFailAt
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
if (typeof SYS_DEBUG_REMOVE_FAILAT !== "undefined") {
|
||||||
|
exports.debugRemoveFailAt = SYS_DEBUG_REMOVE_FAILAT;
|
||||||
|
delete SYS_DEBUG_REMOVE_FAILAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief debugClearFailAt
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
if (typeof SYS_DEBUG_CLEAR_FAILAT !== "undefined") {
|
||||||
|
exports.debugClearFailAt = SYS_DEBUG_CLEAR_FAILAT;
|
||||||
|
delete SYS_DEBUG_CLEAR_FAILAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief debugCanUseFailAt
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
if (typeof SYS_DEBUG_CAN_USE_FAILAT !== "undefined") {
|
||||||
|
exports.debugCanUseFailAt = SYS_DEBUG_CAN_USE_FAILAT;
|
||||||
|
delete SYS_DEBUG_CAN_USE_FAILAT;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief download
|
/// @brief download
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -2438,6 +2438,155 @@ function transactionRollbackSuite () {
|
||||||
c1.save({ _key: "test" });
|
c1.save({ _key: "test" });
|
||||||
assertEqual(3, c1.count());
|
assertEqual(3, c1.count());
|
||||||
assertEqual([ "bar", "baz", "test" ], sortedKeys(c1));
|
assertEqual([ "bar", "baz", "test" ], sortedKeys(c1));
|
||||||
|
},
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief test: rollback a mixed workload
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
testRollbackMixed1 : function () {
|
||||||
|
c1 = db._create(cn1);
|
||||||
|
|
||||||
|
var i;
|
||||||
|
|
||||||
|
for (i = 0; i < 100; ++i) {
|
||||||
|
c1.save({ _key: "key" + i, value: i });
|
||||||
|
}
|
||||||
|
|
||||||
|
var obj = {
|
||||||
|
collections : {
|
||||||
|
write: [ cn1 ]
|
||||||
|
},
|
||||||
|
action : function () {
|
||||||
|
|
||||||
|
for (i = 0; i < 50; ++i) {
|
||||||
|
c1.remove("key" + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 50; i < 100; ++i) {
|
||||||
|
c1.update("key" + i, { value: i - 50 });
|
||||||
|
}
|
||||||
|
|
||||||
|
c1.remove("key50");
|
||||||
|
throw "doh!";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
TRANSACTION(obj);
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEqual(100, c1.count());
|
||||||
|
},
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief test: rollback a mixed workload
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
testRollbackMixed2 : function () {
|
||||||
|
c1 = db._create(cn1);
|
||||||
|
|
||||||
|
c1.save({ _key: "foo" });
|
||||||
|
c1.save({ _key: "bar" });
|
||||||
|
|
||||||
|
var obj = {
|
||||||
|
collections : {
|
||||||
|
write: [ cn1 ]
|
||||||
|
},
|
||||||
|
action : function () {
|
||||||
|
var i;
|
||||||
|
|
||||||
|
for (i = 0; i < 10; ++i) {
|
||||||
|
c1.save({ _key: "key" + i, value: i });
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 5; ++i) {
|
||||||
|
c1.remove("key" + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 5; i < 10; ++i) {
|
||||||
|
c1.update("key" + i, { value: i - 5 });
|
||||||
|
}
|
||||||
|
|
||||||
|
c1.remove("key5");
|
||||||
|
throw "doh!";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
TRANSACTION(obj);
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEqual(2, c1.count());
|
||||||
|
assertEqual("foo", c1.document("foo")._key);
|
||||||
|
assertEqual("bar", c1.document("bar")._key);
|
||||||
|
},
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief test: rollback a mixed workload
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
testRollbackMixed3 : function () {
|
||||||
|
c1 = db._create(cn1);
|
||||||
|
|
||||||
|
c1.save({ _key: "foo" });
|
||||||
|
c1.save({ _key: "bar" });
|
||||||
|
|
||||||
|
var obj = {
|
||||||
|
collections : {
|
||||||
|
write: [ cn1 ]
|
||||||
|
},
|
||||||
|
action : function () {
|
||||||
|
var i;
|
||||||
|
|
||||||
|
for (i = 0; i < 10; ++i) {
|
||||||
|
c1.save({ _key: "key" + i, value: i });
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 10; ++i) {
|
||||||
|
c1.remove("key" + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 10; ++i) {
|
||||||
|
c1.save({ _key: "key" + i, value: i });
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 10; ++i) {
|
||||||
|
c1.update("key" + i, { value: i - 5 });
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 10; ++i) {
|
||||||
|
c1.update("key" + i, { value: i + 5 });
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 10; ++i) {
|
||||||
|
c1.remove("key" + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 10; ++i) {
|
||||||
|
c1.save({ _key: "key" + i, value: i });
|
||||||
|
}
|
||||||
|
|
||||||
|
throw "doh!";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
TRANSACTION(obj);
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEqual(2, c1.count());
|
||||||
|
assertEqual("foo", c1.document("foo")._key);
|
||||||
|
assertEqual("bar", c1.document("bar")._key);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -2898,6 +3047,483 @@ function transactionCrossCollectionSuite () {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- test suite
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief test suite
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
function transactionServerFailuresSuite () {
|
||||||
|
var cn = "UnitTestsTransaction";
|
||||||
|
|
||||||
|
var c = null;
|
||||||
|
|
||||||
|
return {
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief set up
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
setUp : function () {
|
||||||
|
internal.debugClearFailAt();
|
||||||
|
db._drop(cn);
|
||||||
|
},
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief tear down
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
tearDown : function () {
|
||||||
|
internal.debugClearFailAt();
|
||||||
|
|
||||||
|
if (c !== null) {
|
||||||
|
c.drop();
|
||||||
|
}
|
||||||
|
|
||||||
|
c = null;
|
||||||
|
},
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief test: rollback in case of a server-side fail
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
testRollbackInsertSingle1 : function () {
|
||||||
|
c = db._create(cn);
|
||||||
|
|
||||||
|
internal.debugSetFailAt("TRI_WriteOperationDocumentCollection");
|
||||||
|
try {
|
||||||
|
c.save({ _key: "foo" });
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
assertEqual(internal.errors.ERROR_INTERNAL.code, err.errorNum);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief test: rollback in case of a server-side fail
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
testRollbackInsertSingle2 : function () {
|
||||||
|
c = db._create(cn);
|
||||||
|
|
||||||
|
c.save({ _key: "foo" });
|
||||||
|
internal.debugSetFailAt("TRI_WriteOperationDocumentCollection");
|
||||||
|
try {
|
||||||
|
c.save({ _key: "foo2" });
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
assertEqual(internal.errors.ERROR_INTERNAL.code, err.errorNum);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief test: rollback in case of a server-side fail
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
testRollbackInsertMulti1 : function () {
|
||||||
|
c = db._create(cn);
|
||||||
|
c.save({ _key: "baz" });
|
||||||
|
|
||||||
|
var obj = {
|
||||||
|
collections : {
|
||||||
|
write: [ cn ]
|
||||||
|
},
|
||||||
|
action : function () {
|
||||||
|
c.save({ _key: "foo" });
|
||||||
|
internal.debugSetFailAt("AddCollectionOperation-OOM");
|
||||||
|
c.save({ _key: "bar" });
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
TRANSACTION(obj);
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
assertEqual(internal.errors.ERROR_OUT_OF_MEMORY.code, err.errorNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEqual(1, c.count());
|
||||||
|
assertEqual("baz", c.document("baz")._key);
|
||||||
|
},
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief test: rollback in case of a server-side fail
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
testRollbackInsertMulti2 : function () {
|
||||||
|
c = db._create(cn);
|
||||||
|
|
||||||
|
var i;
|
||||||
|
for (i = 0; i < 100; ++i) {
|
||||||
|
c.save({ _key: "key" + i });
|
||||||
|
}
|
||||||
|
|
||||||
|
var obj = {
|
||||||
|
collections : {
|
||||||
|
write: [ cn ]
|
||||||
|
},
|
||||||
|
action : function () {
|
||||||
|
for (i = 0; i < 100; ++i) {
|
||||||
|
c.save({ _key: "foo" + i });
|
||||||
|
}
|
||||||
|
internal.debugSetFailAt("AddCollectionOperation-OOM");
|
||||||
|
c.save({ _key: "bar" });
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
TRANSACTION(obj);
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
assertEqual(internal.errors.ERROR_OUT_OF_MEMORY.code, err.errorNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEqual(100, c.count());
|
||||||
|
assertEqual("key0", c.document("key0")._key);
|
||||||
|
assertEqual("key99", c.document("key99")._key);
|
||||||
|
},
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief test: rollback in case of a server-side fail
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
testRollbackUpdateSingle1 : function () {
|
||||||
|
c = db._create(cn);
|
||||||
|
|
||||||
|
c.save({ _key: "foo", value: 1 });
|
||||||
|
|
||||||
|
internal.debugSetFailAt("TRI_WriteOperationDocumentCollection");
|
||||||
|
try {
|
||||||
|
c.update("foo", { value: 2 });
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
assertEqual(internal.errors.ERROR_INTERNAL.code, err.errorNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEqual(1, c.count());
|
||||||
|
assertEqual("foo", c.document("foo")._key);
|
||||||
|
assertEqual(1, c.document("foo").value);
|
||||||
|
},
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief test: rollback in case of a server-side fail
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
testRollbackUpdateSingle2 : function () {
|
||||||
|
c = db._create(cn);
|
||||||
|
|
||||||
|
c.save({ _key: "foo", value: 1 });
|
||||||
|
c.save({ _key: "bar", value: "a" });
|
||||||
|
|
||||||
|
c.update("foo", { value: 2 });
|
||||||
|
internal.debugSetFailAt("TRI_WriteOperationDocumentCollection");
|
||||||
|
try {
|
||||||
|
c.update("bar", { value: "b" });
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
assertEqual(internal.errors.ERROR_INTERNAL.code, err.errorNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEqual(2, c.count());
|
||||||
|
assertEqual("foo", c.document("foo")._key);
|
||||||
|
assertEqual(2, c.document("foo").value);
|
||||||
|
assertEqual("bar", c.document("bar")._key);
|
||||||
|
assertEqual("a", c.document("bar").value);
|
||||||
|
},
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief test: rollback in case of a server-side fail
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
testRollbackUpdateMulti1 : function () {
|
||||||
|
c = db._create(cn);
|
||||||
|
|
||||||
|
c.save({ _key: "foo", value: 1 });
|
||||||
|
c.save({ _key: "bar", value: "a" });
|
||||||
|
|
||||||
|
var obj = {
|
||||||
|
collections : {
|
||||||
|
write: [ cn ]
|
||||||
|
},
|
||||||
|
action : function () {
|
||||||
|
c.update("foo", { value: 2 });
|
||||||
|
internal.debugSetFailAt("AddCollectionOperation-OOM");
|
||||||
|
c.update("bar", { value: "b" });
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
TRANSACTION(obj);
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
assertEqual(internal.errors.ERROR_OUT_OF_MEMORY.code, err.errorNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEqual(2, c.count());
|
||||||
|
assertEqual("foo", c.document("foo")._key);
|
||||||
|
assertEqual(1, c.document("foo").value);
|
||||||
|
assertEqual("bar", c.document("bar")._key);
|
||||||
|
assertEqual("a", c.document("bar").value);
|
||||||
|
},
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief test: rollback in case of a server-side fail
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
testRollbackUpdateMulti2 : function () {
|
||||||
|
c = db._create(cn);
|
||||||
|
|
||||||
|
c.save({ _key: "foo", value: 1 });
|
||||||
|
c.save({ _key: "bar", value: "a" });
|
||||||
|
|
||||||
|
var obj = {
|
||||||
|
collections : {
|
||||||
|
write: [ cn ]
|
||||||
|
},
|
||||||
|
action : function () {
|
||||||
|
internal.debugSetFailAt("AddCollectionOperation-OOM");
|
||||||
|
c.update("foo", { value: 2 });
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
TRANSACTION(obj);
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
assertEqual(internal.errors.ERROR_OUT_OF_MEMORY.code, err.errorNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEqual(2, c.count());
|
||||||
|
assertEqual("foo", c.document("foo")._key);
|
||||||
|
assertEqual(1, c.document("foo").value);
|
||||||
|
assertEqual("bar", c.document("bar")._key);
|
||||||
|
assertEqual("a", c.document("bar").value);
|
||||||
|
},
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief test: rollback in case of a server-side fail
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
testRollbackRemoveSingle1 : function () {
|
||||||
|
c = db._create(cn);
|
||||||
|
|
||||||
|
c.save({ _key: "foo" });
|
||||||
|
|
||||||
|
internal.debugSetFailAt("TRI_WriteOperationDocumentCollection");
|
||||||
|
try {
|
||||||
|
c.remove("foo");
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
assertEqual(internal.errors.ERROR_INTERNAL.code, err.errorNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEqual(1, c.count());
|
||||||
|
assertEqual("foo", c.document("foo")._key);
|
||||||
|
},
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief test: rollback in case of a server-side fail
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
testRollbackRemoveSingle2 : function () {
|
||||||
|
c = db._create(cn);
|
||||||
|
|
||||||
|
c.save({ _key: "foo" });
|
||||||
|
c.save({ _key: "bar" });
|
||||||
|
|
||||||
|
internal.debugSetFailAt("TRI_WriteOperationDocumentCollection");
|
||||||
|
try {
|
||||||
|
c.remove("foo");
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
assertEqual(internal.errors.ERROR_INTERNAL.code, err.errorNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEqual(2, c.count());
|
||||||
|
assertEqual("foo", c.document("foo")._key);
|
||||||
|
assertEqual("bar", c.document("bar")._key);
|
||||||
|
},
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief test: rollback in case of a server-side fail
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
testRollbackRemoveMulti1 : function () {
|
||||||
|
c = db._create(cn);
|
||||||
|
|
||||||
|
c.save({ _key: "foo" });
|
||||||
|
c.save({ _key: "bar" });
|
||||||
|
|
||||||
|
var obj = {
|
||||||
|
collections : {
|
||||||
|
write: [ cn ]
|
||||||
|
},
|
||||||
|
action : function () {
|
||||||
|
c.remove("foo");
|
||||||
|
internal.debugSetFailAt("AddCollectionOperation-OOM");
|
||||||
|
c.remove("bar");
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
TRANSACTION(obj);
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
assertEqual(internal.errors.ERROR_OUT_OF_MEMORY.code, err.errorNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEqual(2, c.count());
|
||||||
|
assertEqual("foo", c.document("foo")._key);
|
||||||
|
assertEqual("bar", c.document("bar")._key);
|
||||||
|
},
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief test: rollback in case of a server-side fail
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
testRollbackRemoveMulti2 : function () {
|
||||||
|
c = db._create(cn);
|
||||||
|
|
||||||
|
c.save({ _key: "foo" });
|
||||||
|
c.save({ _key: "bar" });
|
||||||
|
|
||||||
|
var obj = {
|
||||||
|
collections : {
|
||||||
|
write: [ cn ]
|
||||||
|
},
|
||||||
|
action : function () {
|
||||||
|
internal.debugSetFailAt("AddCollectionOperation-OOM");
|
||||||
|
c.remove("foo");
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
TRANSACTION(obj);
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
assertEqual(internal.errors.ERROR_OUT_OF_MEMORY.code, err.errorNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEqual(2, c.count());
|
||||||
|
assertEqual("foo", c.document("foo")._key);
|
||||||
|
assertEqual("bar", c.document("bar")._key);
|
||||||
|
},
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief test: rollback in case of a server-side fail
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
testRollbackRemoveMixed1 : function () {
|
||||||
|
c = db._create(cn);
|
||||||
|
|
||||||
|
var i;
|
||||||
|
|
||||||
|
for (i = 0; i < 100; ++i) {
|
||||||
|
c.save({ _key: "key" + i, value: i });
|
||||||
|
}
|
||||||
|
|
||||||
|
var obj = {
|
||||||
|
collections : {
|
||||||
|
write: [ cn ]
|
||||||
|
},
|
||||||
|
action : function () {
|
||||||
|
|
||||||
|
for (i = 0; i < 50; ++i) {
|
||||||
|
c.remove("key" + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 50; i < 100; ++i) {
|
||||||
|
c.update("key" + i, { value: i - 50 });
|
||||||
|
}
|
||||||
|
|
||||||
|
internal.debugSetFailAt("AddCollectionOperation-OOM");
|
||||||
|
c.remove("key50");
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
TRANSACTION(obj);
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
assertEqual(internal.errors.ERROR_OUT_OF_MEMORY.code, err.errorNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEqual(100, c.count());
|
||||||
|
},
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief test: rollback in case of a server-side fail
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
testRollbackRemoveMixed2 : function () {
|
||||||
|
c = db._create(cn);
|
||||||
|
|
||||||
|
c.save({ _key: "foo" });
|
||||||
|
c.save({ _key: "bar" });
|
||||||
|
|
||||||
|
var obj = {
|
||||||
|
collections : {
|
||||||
|
write: [ cn ]
|
||||||
|
},
|
||||||
|
action : function () {
|
||||||
|
var i;
|
||||||
|
|
||||||
|
for (i = 0; i < 10; ++i) {
|
||||||
|
c.save({ _key: "key" + i, value: i });
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 5; ++i) {
|
||||||
|
c.remove("key" + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 5; i < 10; ++i) {
|
||||||
|
c.update("key" + i, { value: i - 5 });
|
||||||
|
}
|
||||||
|
|
||||||
|
internal.debugSetFailAt("AddCollectionOperation-OOM");
|
||||||
|
c.remove("key5");
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
TRANSACTION(obj);
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
assertEqual(internal.errors.ERROR_OUT_OF_MEMORY.code, err.errorNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEqual(2, c.count());
|
||||||
|
assertEqual("foo", c.document("foo")._key);
|
||||||
|
assertEqual("bar", c.document("bar")._key);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- main
|
// --SECTION-- main
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
@ -2915,6 +3541,11 @@ jsunity.run(transactionRollbackSuite);
|
||||||
jsunity.run(transactionCountSuite);
|
jsunity.run(transactionCountSuite);
|
||||||
jsunity.run(transactionCrossCollectionSuite);
|
jsunity.run(transactionCrossCollectionSuite);
|
||||||
|
|
||||||
|
// only run this test suite if server-side failures are enabled
|
||||||
|
if (internal.debugCanUseFailAt()) {
|
||||||
|
jsunity.run(transactionServerFailuresSuite);
|
||||||
|
}
|
||||||
|
|
||||||
return jsunity.done();
|
return jsunity.done();
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
|
@ -130,6 +130,7 @@ typedef long suseconds_t;
|
||||||
#define TRI_WITHIN_COMMON 1
|
#define TRI_WITHIN_COMMON 1
|
||||||
#include "BasicsC/voc-errors.h"
|
#include "BasicsC/voc-errors.h"
|
||||||
#include "BasicsC/error.h"
|
#include "BasicsC/error.h"
|
||||||
|
#include "BasicsC/debugging.h"
|
||||||
#include "BasicsC/memory.h"
|
#include "BasicsC/memory.h"
|
||||||
#include "BasicsC/mimetypes.h"
|
#include "BasicsC/mimetypes.h"
|
||||||
#include "BasicsC/structures.h"
|
#include "BasicsC/structures.h"
|
||||||
|
|
|
@ -0,0 +1,371 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief debugging helpers
|
||||||
|
///
|
||||||
|
/// @file
|
||||||
|
///
|
||||||
|
/// DISCLAIMER
|
||||||
|
///
|
||||||
|
/// Copyright 2004-2013 triAGENS GmbH, Cologne, Germany
|
||||||
|
///
|
||||||
|
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
/// you may not use this file except in compliance with the License.
|
||||||
|
/// You may obtain a copy of the License at
|
||||||
|
///
|
||||||
|
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
///
|
||||||
|
/// Unless required by applicable law or agreed to in writing, software
|
||||||
|
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
/// See the License for the specific language governing permissions and
|
||||||
|
/// limitations under the License.
|
||||||
|
///
|
||||||
|
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||||
|
///
|
||||||
|
/// @author Jan Steemann
|
||||||
|
/// @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "BasicsC/common.h"
|
||||||
|
|
||||||
|
#include "BasicsC/debugging.h"
|
||||||
|
#include "BasicsC/locks.h"
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- private variables
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @addtogroup Debugging
|
||||||
|
/// @{
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief a global string containing the currently registered failure points
|
||||||
|
/// the string is a comma-separated list of point names
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifdef TRI_ENABLE_MAINTAINER_MODE
|
||||||
|
|
||||||
|
static char* FailurePoints;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief a read-write lock for thread-safe access to the failure-points list
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifdef TRI_ENABLE_MAINTAINER_MODE
|
||||||
|
|
||||||
|
TRI_read_write_lock_t FailurePointsLock;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- private functions
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @addtogroup Debugging
|
||||||
|
/// @{
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief make a delimited value from a string, so we can unambigiously
|
||||||
|
/// search for it (e.g. searching for just "foo" would find "foo" and "foobar",
|
||||||
|
/// so we'll be putting the value inside some delimiter: ",foo,")
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifdef TRI_ENABLE_MAINTAINER_MODE
|
||||||
|
|
||||||
|
static char* MakeValue (char const* value) {
|
||||||
|
char* delimited;
|
||||||
|
|
||||||
|
if (value == NULL || strlen(value) == 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
delimited = TRI_Allocate(TRI_CORE_MEM_ZONE, strlen(value) + 3, false);
|
||||||
|
|
||||||
|
if (delimited != NULL) {
|
||||||
|
memcpy(delimited + 1, value, strlen(value));
|
||||||
|
delimited[0] = ',';
|
||||||
|
delimited[strlen(value) + 1] = ',';
|
||||||
|
delimited[strlen(value) + 2] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
return delimited;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- public functions
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @addtogroup Debugging
|
||||||
|
/// @{
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief check whether we should fail at a specific failure point
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifdef TRI_ENABLE_MAINTAINER_MODE
|
||||||
|
|
||||||
|
bool TRI_ShouldFailDebugging (char const* value) {
|
||||||
|
char* found;
|
||||||
|
char* checkValue;
|
||||||
|
|
||||||
|
checkValue = MakeValue(value);
|
||||||
|
|
||||||
|
if (checkValue == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRI_ReadLockReadWriteLock(&FailurePointsLock);
|
||||||
|
|
||||||
|
if (FailurePoints == NULL) {
|
||||||
|
found = NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
found = strstr(FailurePoints, checkValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
TRI_ReadUnlockReadWriteLock(&FailurePointsLock);
|
||||||
|
|
||||||
|
TRI_Free(TRI_CORE_MEM_ZONE, checkValue);
|
||||||
|
|
||||||
|
return (found != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief add a failure point
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void TRI_AddFailurePointDebugging (char const* value) {
|
||||||
|
|
||||||
|
#ifdef TRI_ENABLE_MAINTAINER_MODE
|
||||||
|
|
||||||
|
char* found;
|
||||||
|
char* checkValue;
|
||||||
|
|
||||||
|
checkValue = MakeValue(value);
|
||||||
|
|
||||||
|
if (checkValue == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRI_WriteLockReadWriteLock(&FailurePointsLock);
|
||||||
|
|
||||||
|
if (FailurePoints == NULL) {
|
||||||
|
found = NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
found = strstr(FailurePoints, checkValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found == NULL) {
|
||||||
|
// not yet found. so add it
|
||||||
|
char* copy;
|
||||||
|
size_t n;
|
||||||
|
|
||||||
|
n = strlen(checkValue);
|
||||||
|
|
||||||
|
if (FailurePoints == NULL) {
|
||||||
|
copy = TRI_Allocate(TRI_CORE_MEM_ZONE, n + 1, false);
|
||||||
|
|
||||||
|
if (copy == NULL) {
|
||||||
|
TRI_WriteUnlockReadWriteLock(&FailurePointsLock);
|
||||||
|
TRI_Free(TRI_CORE_MEM_ZONE, checkValue);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(copy, checkValue, n);
|
||||||
|
copy[n] = '\0';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
copy = TRI_Allocate(TRI_CORE_MEM_ZONE, n + strlen(FailurePoints), false);
|
||||||
|
|
||||||
|
if (copy == NULL) {
|
||||||
|
TRI_WriteUnlockReadWriteLock(&FailurePointsLock);
|
||||||
|
TRI_Free(TRI_CORE_MEM_ZONE, checkValue);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(copy, FailurePoints, strlen(FailurePoints));
|
||||||
|
memcpy(copy + strlen(FailurePoints) - 1, checkValue, n);
|
||||||
|
copy[strlen(FailurePoints) + n - 1] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
FailurePoints = copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRI_WriteUnlockReadWriteLock(&FailurePointsLock);
|
||||||
|
TRI_Free(TRI_CORE_MEM_ZONE, checkValue);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief remove a failure points
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void TRI_RemoveFailurePointDebugging (char const* value) {
|
||||||
|
|
||||||
|
#ifdef TRI_ENABLE_MAINTAINER_MODE
|
||||||
|
|
||||||
|
char* checkValue;
|
||||||
|
|
||||||
|
TRI_WriteLockReadWriteLock(&FailurePointsLock);
|
||||||
|
|
||||||
|
if (FailurePoints == NULL) {
|
||||||
|
TRI_WriteUnlockReadWriteLock(&FailurePointsLock);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
checkValue = MakeValue(value);
|
||||||
|
|
||||||
|
if (checkValue != NULL) {
|
||||||
|
char* found;
|
||||||
|
char* copy;
|
||||||
|
size_t n;
|
||||||
|
|
||||||
|
found = strstr(FailurePoints, checkValue);
|
||||||
|
|
||||||
|
if (found == NULL) {
|
||||||
|
TRI_WriteUnlockReadWriteLock(&FailurePointsLock);
|
||||||
|
TRI_Free(TRI_CORE_MEM_ZONE, checkValue);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen(FailurePoints) - strlen(checkValue) <= 2) {
|
||||||
|
TRI_Free(TRI_CORE_MEM_ZONE, FailurePoints);
|
||||||
|
FailurePoints = NULL;
|
||||||
|
|
||||||
|
TRI_WriteUnlockReadWriteLock(&FailurePointsLock);
|
||||||
|
TRI_Free(TRI_CORE_MEM_ZONE, checkValue);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
copy = TRI_Allocate(TRI_CORE_MEM_ZONE, strlen(FailurePoints) - strlen(checkValue) + 2, false);
|
||||||
|
|
||||||
|
if (copy == NULL) {
|
||||||
|
TRI_WriteUnlockReadWriteLock(&FailurePointsLock);
|
||||||
|
TRI_Free(TRI_CORE_MEM_ZONE, checkValue);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy start of string
|
||||||
|
n = found - FailurePoints;
|
||||||
|
memcpy(copy, FailurePoints, n);
|
||||||
|
|
||||||
|
// copy remainder of string
|
||||||
|
memcpy(copy + n, found + strlen(checkValue) - 1, strlen(FailurePoints) - strlen(checkValue) - n + 1);
|
||||||
|
|
||||||
|
copy[strlen(FailurePoints) - strlen(checkValue) + 1] = '\0';
|
||||||
|
TRI_Free(TRI_CORE_MEM_ZONE, FailurePoints);
|
||||||
|
FailurePoints = copy;
|
||||||
|
|
||||||
|
TRI_WriteUnlockReadWriteLock(&FailurePointsLock);
|
||||||
|
TRI_Free(TRI_CORE_MEM_ZONE, checkValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief clear all failure points
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void TRI_ClearFailurePointsDebugging () {
|
||||||
|
#ifdef TRI_ENABLE_MAINTAINER_MODE
|
||||||
|
|
||||||
|
TRI_WriteLockReadWriteLock(&FailurePointsLock);
|
||||||
|
|
||||||
|
if (FailurePoints != NULL) {
|
||||||
|
TRI_Free(TRI_CORE_MEM_ZONE, FailurePoints);
|
||||||
|
}
|
||||||
|
|
||||||
|
FailurePoints = NULL;
|
||||||
|
|
||||||
|
TRI_WriteUnlockReadWriteLock(&FailurePointsLock);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief returns whether failure point debugging can be used
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool TRI_CanUseFailurePointsDebugging () {
|
||||||
|
#ifdef TRI_ENABLE_MAINTAINER_MODE
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief initialise the debugging
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void TRI_InitialiseDebugging () {
|
||||||
|
#ifdef TRI_ENABLE_MAINTAINER_MODE
|
||||||
|
|
||||||
|
FailurePoints = NULL;
|
||||||
|
TRI_InitReadWriteLock(&FailurePointsLock);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief shutdown the debugging
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void TRI_ShutdownDebugging () {
|
||||||
|
#ifdef TRI_ENABLE_MAINTAINER_MODE
|
||||||
|
|
||||||
|
if (FailurePoints != NULL) {
|
||||||
|
TRI_Free(TRI_CORE_MEM_ZONE, FailurePoints);
|
||||||
|
}
|
||||||
|
|
||||||
|
FailurePoints = NULL;
|
||||||
|
|
||||||
|
TRI_DestroyReadWriteLock(&FailurePointsLock);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- END-OF-FILE
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Local Variables:
|
||||||
|
// mode: outline-minor
|
||||||
|
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||||
|
// End:
|
|
@ -0,0 +1,137 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief debugging helpers
|
||||||
|
///
|
||||||
|
/// @file
|
||||||
|
///
|
||||||
|
/// DISCLAIMER
|
||||||
|
///
|
||||||
|
/// Copyright 2004-2013 triAGENS GmbH, Cologne, Germany
|
||||||
|
///
|
||||||
|
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
/// you may not use this file except in compliance with the License.
|
||||||
|
/// You may obtain a copy of the License at
|
||||||
|
///
|
||||||
|
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
///
|
||||||
|
/// Unless required by applicable law or agreed to in writing, software
|
||||||
|
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
/// See the License for the specific language governing permissions and
|
||||||
|
/// limitations under the License.
|
||||||
|
///
|
||||||
|
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||||
|
///
|
||||||
|
/// @author Jan Steemann
|
||||||
|
/// @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef TRIAGENS_BASICS_C_DEBUGGING_H
|
||||||
|
#define TRIAGENS_BASICS_C_DEBUGGING_H 1
|
||||||
|
|
||||||
|
#ifndef TRI_WITHIN_COMMON
|
||||||
|
#error use <BasicsC/common.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- public defines
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @addtogroup Debugging
|
||||||
|
/// @{
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief macro TRI_DEBUG_INTENTIONAL_FAIL_IF
|
||||||
|
/// this macro can be used in maintainer mode to make the server fail at
|
||||||
|
/// certain locations in the C code. The points at which a failure is actually
|
||||||
|
/// triggered can be defined at runtime using TRI_AddFailurePointDebugging().
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifdef TRI_ENABLE_MAINTAINER_MODE
|
||||||
|
|
||||||
|
#define TRI_DEBUG_INTENTIONAL_FAIL_IF(what) if (TRI_ShouldFailDebugging(what))
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define TRI_DEBUG_INTENTIONAL_FAIL_IF(what) if (false)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- public functions
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @addtogroup Debugging
|
||||||
|
/// @{
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief check whether we should fail at a failure point
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifdef TRI_ENABLE_MAINTAINER_MODE
|
||||||
|
|
||||||
|
bool TRI_ShouldFailDebugging (char const*);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief add a failure point
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void TRI_AddFailurePointDebugging (char const*);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief remove a failure point
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void TRI_RemoveFailurePointDebugging (char const*);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief clear all failure points
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void TRI_ClearFailurePointsDebugging (void);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief returns whether failure point debugging can be used
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool TRI_CanUseFailurePointsDebugging (void);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief initialise the debugging
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void TRI_InitialiseDebugging (void);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief shutdown the debugging
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void TRI_ShutdownDebugging (void);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Local Variables:
|
||||||
|
// mode: outline-minor
|
||||||
|
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||||
|
// End:
|
|
@ -52,6 +52,7 @@
|
||||||
|
|
||||||
void TRI_InitialiseC (int argc, char* argv[]) {
|
void TRI_InitialiseC (int argc, char* argv[]) {
|
||||||
TRI_InitialiseMemory();
|
TRI_InitialiseMemory();
|
||||||
|
TRI_InitialiseDebugging();
|
||||||
TRI_InitialiseMersenneTwister();
|
TRI_InitialiseMersenneTwister();
|
||||||
TRI_InitialiseError();
|
TRI_InitialiseError();
|
||||||
TRI_InitialiseFiles();
|
TRI_InitialiseFiles();
|
||||||
|
@ -78,6 +79,7 @@ void TRI_ShutdownC () {
|
||||||
TRI_ShutdownMimetypes();
|
TRI_ShutdownMimetypes();
|
||||||
TRI_ShutdownFiles();
|
TRI_ShutdownFiles();
|
||||||
TRI_ShutdownError();
|
TRI_ShutdownError();
|
||||||
|
TRI_ShutdownDebugging();
|
||||||
TRI_ShutdownMemory();
|
TRI_ShutdownMemory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@ lib_libarango_a_SOURCES = \
|
||||||
lib/BasicsC/associative.c \
|
lib/BasicsC/associative.c \
|
||||||
lib/BasicsC/conversions.c \
|
lib/BasicsC/conversions.c \
|
||||||
lib/BasicsC/csv.c \
|
lib/BasicsC/csv.c \
|
||||||
|
lib/BasicsC/debugging.c \
|
||||||
lib/BasicsC/error.c \
|
lib/BasicsC/error.c \
|
||||||
lib/BasicsC/files.c \
|
lib/BasicsC/files.c \
|
||||||
lib/BasicsC/hashes.c \
|
lib/BasicsC/hashes.c \
|
||||||
|
|
|
@ -1959,6 +1959,92 @@ static v8::Handle<v8::Value> JS_Wait (v8::Arguments const& argv) {
|
||||||
return scope.Close(v8::Undefined());
|
return scope.Close(v8::Undefined());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief set a failure point
|
||||||
|
///
|
||||||
|
/// @FUN{internal.debugSetFailAt(@FA{point})}
|
||||||
|
///
|
||||||
|
/// Set a point for an intentional system failure
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static v8::Handle<v8::Value> JS_DebugSetFailAt (v8::Arguments const& argv) {
|
||||||
|
v8::HandleScope scope;
|
||||||
|
|
||||||
|
// extract arguments
|
||||||
|
if (argv.Length() != 1) {
|
||||||
|
TRI_V8_EXCEPTION_USAGE(scope, "debugSetFailAt(<point>)");
|
||||||
|
}
|
||||||
|
|
||||||
|
string point = TRI_ObjectToString(argv[0]);
|
||||||
|
|
||||||
|
TRI_AddFailurePointDebugging(point.c_str());
|
||||||
|
|
||||||
|
return scope.Close(v8::Undefined());
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief remove a failure point
|
||||||
|
///
|
||||||
|
/// @FUN{internal.debugRemoveFailAt(@FA{point})}
|
||||||
|
///
|
||||||
|
/// Remove a point for an intentional system failure
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static v8::Handle<v8::Value> JS_DebugRemoveFailAt (v8::Arguments const& argv) {
|
||||||
|
v8::HandleScope scope;
|
||||||
|
|
||||||
|
// extract arguments
|
||||||
|
if (argv.Length() != 1) {
|
||||||
|
TRI_V8_EXCEPTION_USAGE(scope, "debugRemoveFailAt(<point>)");
|
||||||
|
}
|
||||||
|
|
||||||
|
string point = TRI_ObjectToString(argv[0]);
|
||||||
|
|
||||||
|
TRI_RemoveFailurePointDebugging(point.c_str());
|
||||||
|
|
||||||
|
return scope.Close(v8::Undefined());
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief clear all failure points
|
||||||
|
///
|
||||||
|
/// @FUN{internal.debugClearFailAt()}
|
||||||
|
///
|
||||||
|
/// Remove all points for intentional system failures
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static v8::Handle<v8::Value> JS_DebugClearFailAt (v8::Arguments const& argv) {
|
||||||
|
v8::HandleScope scope;
|
||||||
|
|
||||||
|
// extract arguments
|
||||||
|
if (argv.Length() != 0) {
|
||||||
|
TRI_V8_EXCEPTION_USAGE(scope, "debugClearFailAt()");
|
||||||
|
}
|
||||||
|
|
||||||
|
TRI_ClearFailurePointsDebugging();
|
||||||
|
|
||||||
|
return scope.Close(v8::Undefined());
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief returns whether failure points can be used
|
||||||
|
///
|
||||||
|
/// @FUN{internal.debugCanUseFailAt()}
|
||||||
|
///
|
||||||
|
/// Returns whether failure points can be be used
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static v8::Handle<v8::Value> JS_DebugCanUseFailAt (v8::Arguments const& argv) {
|
||||||
|
v8::HandleScope scope;
|
||||||
|
|
||||||
|
// extract arguments
|
||||||
|
if (argv.Length() != 0) {
|
||||||
|
TRI_V8_EXCEPTION_USAGE(scope, "debugCanUseFailAt()");
|
||||||
|
}
|
||||||
|
|
||||||
|
return scope.Close(TRI_CanUseFailurePointsDebugging() ? v8::True() : v8::False());
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief returns the current request and connection statistics
|
/// @brief returns the current request and connection statistics
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -2481,6 +2567,12 @@ void TRI_InitV8Utils (v8::Handle<v8::Context> context,
|
||||||
TRI_AddGlobalFunctionVocbase(context, "SYS_TIME", JS_Time);
|
TRI_AddGlobalFunctionVocbase(context, "SYS_TIME", JS_Time);
|
||||||
TRI_AddGlobalFunctionVocbase(context, "SYS_WAIT", JS_Wait);
|
TRI_AddGlobalFunctionVocbase(context, "SYS_WAIT", JS_Wait);
|
||||||
|
|
||||||
|
// debugging functions
|
||||||
|
TRI_AddGlobalFunctionVocbase(context, "SYS_DEBUG_SET_FAILAT", JS_DebugSetFailAt);
|
||||||
|
TRI_AddGlobalFunctionVocbase(context, "SYS_DEBUG_REMOVE_FAILAT", JS_DebugRemoveFailAt);
|
||||||
|
TRI_AddGlobalFunctionVocbase(context, "SYS_DEBUG_CLEAR_FAILAT", JS_DebugClearFailAt);
|
||||||
|
TRI_AddGlobalFunctionVocbase(context, "SYS_DEBUG_CAN_USE_FAILAT", JS_DebugCanUseFailAt);
|
||||||
|
|
||||||
// .............................................................................
|
// .............................................................................
|
||||||
// create the global variables
|
// create the global variables
|
||||||
// .............................................................................
|
// .............................................................................
|
||||||
|
|
Loading…
Reference in New Issue