1
0
Fork 0

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

This commit is contained in:
Frank Celler 2014-05-09 17:15:11 +02:00
commit 65ad94d9cf
50 changed files with 5206 additions and 4121 deletions

View File

@ -17,9 +17,9 @@ import (
// event happens between the end of the first watch command and the start
// of the second command.
type watcherHub struct {
count int64 // current number of watchers.
mutex sync.Mutex // protect the hash map
watchers map[string]*list.List
count int64 // current number of watchers.
EventHistory *EventHistory
}

View File

@ -26,12 +26,12 @@ import (
// Logger is user-immutable immutable struct which can log to several outputs
type Logger struct {
seq uint64 // sequential number of log message, starting at 1
sinks []Sink // the sinks this logger will log to
verbose bool // gather expensive logging data?
prefix string // static field available to all log sinks under this logger
created time.Time // time when this logger was created
seq uint64 // sequential number of log message, starting at 1
executable string // executable name
}

View File

@ -77,11 +77,11 @@ func (NilEWMA) Update(n int64) {}
// of uncounted events and processes them on each tick. It uses the
// sync/atomic package to manage uncounted events.
type StandardEWMA struct {
uncounted int64
alpha float64
init bool
mutex sync.Mutex
rate float64
uncounted int64
}
// Rate returns the moving average rate of events per second.

View File

@ -37,8 +37,8 @@ type Sample interface {
//
// <http://www.research.att.com/people/Cormode_Graham/library/publications/CormodeShkapenyukSrivastavaXu09.pdf>
type ExpDecaySample struct {
alpha float64
count int64
alpha float64
mutex sync.Mutex
reservoirSize int
t0, t1 time.Time
@ -390,9 +390,9 @@ func SampleVariance(values []int64) float64 {
// <http://www.cs.umd.edu/~samir/498/vitter.pdf>
type UniformSample struct {
count int64
values []int64
mutex sync.Mutex
reservoirSize int
values []int64
}
// NewUniformSample constructs a new uniform sample with the given reservoir
@ -519,8 +519,8 @@ func (s *UniformSample) Variance() float64 {
// expDecaySample represents an individual sample in a heap.
type expDecaySample struct {
k float64
v int64
k float64
}
// expDecaySampleHeap is a min-heap of expDecaySamples.

View File

@ -1,6 +1,10 @@
v2.1.0 (XXXX-XX-XX)
-------------------
* decrease the size of some seldomly used system collections on creation.
This will make these collections use less disk space and mapped memory.
* fixed issue #848: db.someEdgeCollection.inEdge does not return correct
value when called the 2nd time after a .save to the edge collection
@ -105,7 +109,26 @@ v2.1.0 (XXXX-XX-XX)
* export the sort attribute for graph traversals to the HTTP interface
v2.0.7 (XXXX-XX-XX)
v2.0.8 (XXXX-XX-XX)
-------------------
* fixed timeout overflows on 32 bit systems
this bug has led to problems when select was called with a high timeout
value (2000+ seconds) on 32bit systems that don't have a forgiving select
implementation. when the call was made on these systems, select failed
so no data would be read or sent over the connection
this might have affected some cluster-internal operations.
* fixed ETCD issues on 32 bit systems
ETCD was non-functional on 32 bit systems at all. The first call to the
watch API crashed it. This was because atomic operations worked on data
structures that were not properly aligned on 32 bit systems.
v2.0.7 (2014-05-05)
-------------------
* issue #839: Foxx Manager missing "unfetch"

View File

@ -101,6 +101,14 @@ namespace triagens {
return triagens::basics::JsonHelper::stringUInt64(_json, "id");
}
////////////////////////////////////////////////////////////////////////////////
/// @brief returns the collection id as a string
////////////////////////////////////////////////////////////////////////////////
string id_as_string () const {
return triagens::basics::JsonHelper::getStringValue(_json, "id", "");
}
////////////////////////////////////////////////////////////////////////////////
/// @brief returns the collection name
////////////////////////////////////////////////////////////////////////////////

View File

@ -45,6 +45,7 @@
#include "VocBase/replication-logger.h"
#include "VocBase/server.h"
#include "VocBase/update-policy.h"
#include "VocBase/index.h"
#ifdef TRI_ENABLE_CLUSTER
#include "Cluster/ClusterMethods.h"
@ -2158,7 +2159,7 @@ int RestReplicationHandler::processRestoreCollectionCoordinator (
return TRI_ERROR_HTTP_BAD_PARAMETER;
}
TRI_json_t const* parameters = JsonHelper::getArrayElement(collection, "parameters");
TRI_json_t* parameters = JsonHelper::getArrayElement(collection, "parameters");
if (! JsonHelper::isArray(parameters)) {
errorMsg = "collection parameters declaration is invalid";
@ -2166,14 +2167,6 @@ int RestReplicationHandler::processRestoreCollectionCoordinator (
return TRI_ERROR_HTTP_BAD_PARAMETER;
}
TRI_json_t const* indexes = JsonHelper::getArrayElement(collection, "indexes");
if (! JsonHelper::isList(indexes)) {
errorMsg = "collection indexes declaration is invalid";
return TRI_ERROR_HTTP_BAD_PARAMETER;
}
const string name = JsonHelper::getStringValue(parameters, "name", "");
if (name.empty()) {
@ -2187,56 +2180,24 @@ int RestReplicationHandler::processRestoreCollectionCoordinator (
return TRI_ERROR_NO_ERROR;
}
TRI_vocbase_col_t* col = 0;
string dbName = _vocbase->_name;
if (reuseId) {
TRI_json_t const* idString = JsonHelper::getArrayElement(parameters, "cid");
if (! JsonHelper::isString(idString)) {
errorMsg = "collection id is missing";
return TRI_ERROR_HTTP_BAD_PARAMETER;
}
TRI_voc_cid_t cid = StringUtils::uint64(idString->_value._string.data, idString->_value._string.length - 1);
// first look up the collection by the cid
col = TRI_LookupCollectionByIdVocBase(_vocbase, cid);
}
if (col == 0) {
// not found, try name next
col = TRI_LookupCollectionByNameVocBase(_vocbase, name.c_str());
}
// in a cluster, we only look up by name:
ClusterInfo* ci = ClusterInfo::instance();
TRI_shared_ptr<CollectionInfo> col = ci->getCollection(dbName, name);
// drop an existing collection if it exists
if (col != 0) {
if (! col->empty()) {
if (dropExisting) {
int res = TRI_DropCollectionVocBase(_vocbase, col, remoteServerId);
int res = ci->dropCollectionCoordinator(dbName, col->id_as_string(),
errorMsg, 0.0);
if (res == TRI_ERROR_FORBIDDEN) {
// some collections must not be dropped
// instead, truncate them
CollectionNameResolver resolver(_vocbase);
SingleCollectionWriteTransaction<EmbeddableTransaction<RestTransactionContext>, UINT64_MAX> trx(_vocbase, resolver, col->_cid);
res = trx.begin();
if (res != TRI_ERROR_NO_ERROR) {
return res;
}
TRI_barrier_t* barrier = TRI_CreateBarrierElement(&(trx.primaryCollection()->_barrierList));
if (barrier == 0) {
return TRI_ERROR_INTERNAL;
}
res = trx.truncate(false);
res = trx.finish(res);
TRI_FreeBarrier(barrier);
// ...
// do a fanout to all shards and truncate them, use col and asyncreq.
// return res;
return res;
}
@ -2256,7 +2217,78 @@ int RestReplicationHandler::processRestoreCollectionCoordinator (
}
// now re-create the collection
int res = createCollection(parameters, &col, reuseId, remoteServerId);
// dig out number of shards:
TRI_json_t const* shards = JsonHelper::getArrayElement(parameters, "shards");
if (0 == shards) {
errorMsg = "did not find \"shards\" attribute in parameters";
return TRI_ERROR_INTERNAL;
}
if (! TRI_IsArrayJson(shards)) {
errorMsg = "\"shards\" attribute in parameters is not an array";
return TRI_ERROR_INTERNAL;
}
uint64_t numberOfShards = TRI_LengthVector(&shards->_value._objects)/2;
TRI_voc_tick_t new_id_tick = ci->uniqid(1);
string new_id = StringUtils::itoa(new_id_tick);
TRI_ReplaceArrayJson(TRI_UNKNOWN_MEM_ZONE, parameters, "id",
TRI_CreateString2CopyJson(TRI_UNKNOWN_MEM_ZONE,
new_id.c_str(), new_id.size()));
// Now put in the primary and an edge index if needed:
TRI_json_t* indexes = TRI_CreateListJson(TRI_UNKNOWN_MEM_ZONE);
if (indexes == 0) {
errorMsg = "out of memory";
return TRI_ERROR_OUT_OF_MEMORY;
}
// create a dummy primary index
TRI_index_t* idx = TRI_CreatePrimaryIndex(0);
if (idx == 0) {
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, indexes);
errorMsg = "out of memory";
return TRI_ERROR_OUT_OF_MEMORY;
}
TRI_json_t* idxJson = idx->json(idx);
TRI_FreeIndex(idx);
TRI_PushBack3ListJson(TRI_UNKNOWN_MEM_ZONE, indexes, TRI_CopyJson(TRI_UNKNOWN_MEM_ZONE, idxJson));
TRI_FreeJson(TRI_CORE_MEM_ZONE, idxJson);
TRI_json_t* type = TRI_LookupArrayJson(parameters, "type");
TRI_col_type_e collectionType;
if (TRI_IsNumberJson(type)) {
collectionType = (TRI_col_type_e) type->_value._number;
}
else {
errorMsg = "collection type not given or wrong";
return TRI_ERROR_HTTP_BAD_PARAMETER;
}
if (collectionType == TRI_COL_TYPE_EDGE) {
// create a dummy edge index
idx = TRI_CreateEdgeIndex(0, new_id_tick);
if (idx == 0) {
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, indexes);
errorMsg = "cannot create edge index";
return TRI_ERROR_INTERNAL;
}
idxJson = idx->json(idx);
TRI_FreeIndex(idx);
TRI_PushBack3ListJson(TRI_UNKNOWN_MEM_ZONE, indexes, TRI_CopyJson(TRI_UNKNOWN_MEM_ZONE, idxJson));
TRI_FreeJson(TRI_CORE_MEM_ZONE, idxJson);
}
TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, parameters, "indexes", indexes);
int res = ci->createCollectionCoordinator(dbName, new_id, numberOfShards,
parameters, errorMsg, 0.0);
if (res != TRI_ERROR_NO_ERROR) {
errorMsg = "unable to create collection: " + string(TRI_errno_string(res));
@ -2422,57 +2454,30 @@ int RestReplicationHandler::processRestoreIndexesCoordinator (
return TRI_ERROR_NO_ERROR;
}
// look up the collection
TRI_vocbase_col_t* col = TRI_LookupCollectionByNameVocBase(_vocbase, name.c_str());
string dbName = _vocbase->_name;
if (col == 0) {
// in a cluster, we only look up by name:
ClusterInfo* ci = ClusterInfo::instance();
TRI_shared_ptr<CollectionInfo> col = ci->getCollection(dbName, name);
if (col->empty()) {
errorMsg = "could not find collection '" + name + "'";
return TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND;
}
int res = TRI_UseCollectionVocBase(_vocbase, col);
if (res != TRI_ERROR_NO_ERROR) {
return res;
}
TRI_primary_collection_t* primary = col->_collection;
TRI_ReadLockReadWriteLock(&_vocbase->_inventoryLock);
TRI_WRITE_LOCK_DOCUMENTS_INDEXES_PRIMARY_COLLECTION(primary);
int res = TRI_ERROR_NO_ERROR;
for (size_t i = 0; i < n; ++i) {
TRI_json_t const* idxDef = (TRI_json_t const*) TRI_AtVector(&indexes->_value._objects, i);
TRI_index_t* idx = 0;
// {"id":"229907440927234","type":"hash","unique":false,"fields":["x","Y"]}
res = TRI_FromJsonIndexDocumentCollection((TRI_document_collection_t*) primary, idxDef, &idx);
TRI_json_t* res_json = 0;
res = ci->ensureIndexCoordinator(dbName, col->id_as_string(), idxDef,
true, IndexComparator, res_json, errorMsg, 3600.0);
if (res != TRI_ERROR_NO_ERROR) {
errorMsg = "could not create index: " + string(TRI_errno_string(res));
break;
}
else {
assert(idx != 0);
res = TRI_SaveIndex(primary, idx, remoteServerId);
if (res != TRI_ERROR_NO_ERROR) {
errorMsg = "could not save index: " + string(TRI_errno_string(res));
break;
}
}
}
TRI_WRITE_UNLOCK_DOCUMENTS_INDEXES_PRIMARY_COLLECTION(primary);
TRI_ReadUnlockReadWriteLock(&_vocbase->_inventoryLock);
TRI_ReleaseCollectionVocBase(_vocbase, col);
return TRI_ERROR_NO_ERROR;
return res;
}
#endif
@ -2825,47 +2830,246 @@ void RestReplicationHandler::handleCommandRestoreData () {
#ifdef TRI_ENABLE_CLUSTER
void RestReplicationHandler::handleCommandRestoreDataCoordinator () {
char const* value = _request->value("collection");
char const* name = _request->value("collection");
if (value == 0) {
if (name == 0) {
generateError(HttpResponse::BAD,
TRI_ERROR_HTTP_BAD_PARAMETER,
"invalid collection parameter");
return;
}
CollectionNameResolver resolver(_vocbase);
TRI_voc_cid_t cid = resolver.getCollectionId(value);
if (cid == 0) {
generateError(HttpResponse::BAD,
TRI_ERROR_HTTP_BAD_PARAMETER,
"invalid collection parameter");
return;
}
bool recycleIds = false;
value = _request->value("recycleIds");
if (value != 0) {
recycleIds = StringUtils::boolean(value);
}
bool force = false;
value = _request->value("force");
if (value != 0) {
force = StringUtils::boolean(value);
}
TRI_server_id_t remoteServerId = 0; // TODO
string dbName = _vocbase->_name;
string errorMsg;
int res = processRestoreData(resolver, cid, remoteServerId, recycleIds, force, errorMsg);
// in a cluster, we only look up by name:
ClusterInfo* ci = ClusterInfo::instance();
TRI_shared_ptr<CollectionInfo> col = ci->getCollection(dbName, name);
if (res != TRI_ERROR_NO_ERROR) {
generateError(HttpResponse::SERVER_ERROR, res);
if (col->empty()) {
generateError(HttpResponse::BAD, TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND);
return;
}
// We need to distribute the documents we get over the shards:
map<ShardID, ServerID> shardIdsMap = col->shardIds();
map<string, size_t> shardTab;
vector<string> shardIds;
map<ShardID, ServerID>::iterator it;
map<string, size_t>::iterator it2;
for (it = shardIdsMap.begin(); it != shardIdsMap.end(); it++) {
shardTab.insert(make_pair(it->first,shardIds.size()));
shardIds.push_back(it->first);
}
vector<StringBuffer*> bufs;
size_t j;
for (j = 0; j < shardIds.size(); j++) {
bufs.push_back(new StringBuffer(TRI_UNKNOWN_MEM_ZONE));
}
const string invalidMsg = string("received invalid JSON data for collection ")
+ name;
char const* ptr = _request->body();
char const* end = ptr + _request->bodySize();
int res = TRI_ERROR_NO_ERROR;
while (ptr < end) {
char const* pos = strchr(ptr, '\n');
if (pos == 0) {
pos = end;
}
else {
*((char*) pos) = '\0';
}
if (pos - ptr > 1) {
// found something
TRI_json_t* json = TRI_JsonString(TRI_CORE_MEM_ZONE, ptr);
if (! JsonHelper::isArray(json)) {
if (json != 0) {
TRI_FreeJson(TRI_CORE_MEM_ZONE, json);
}
errorMsg = invalidMsg;
res = TRI_ERROR_HTTP_CORRUPTED_JSON;
break;
}
const char* key = 0;
TRI_json_t const* doc = 0;
TRI_replication_operation_e type;
const size_t n = json->_value._objects._length;
for (size_t i = 0; i < n; i += 2) {
TRI_json_t const* element
= (TRI_json_t const*) TRI_AtVector(&json->_value._objects, i);
if (! JsonHelper::isString(element)) {
TRI_FreeJson(TRI_CORE_MEM_ZONE, json);
errorMsg = invalidMsg;
res = TRI_ERROR_HTTP_CORRUPTED_JSON;
break;
}
const char* attributeName = element->_value._string.data;
TRI_json_t const* value = (TRI_json_t const*) TRI_AtVector(&json->_value._objects, i + 1);
if (TRI_EqualString(attributeName, "type")) {
if (JsonHelper::isNumber(value)) {
type = (TRI_replication_operation_e) (int) value->_value._number;
}
}
else if (TRI_EqualString(attributeName, "key")) {
if (JsonHelper::isString(value)) {
key = value->_value._string.data;
}
}
else if (TRI_EqualString(attributeName, "data")) {
if (JsonHelper::isArray(value)) {
doc = value;
}
}
}
if (res != TRI_ERROR_NO_ERROR) {
break;
}
// key must not be 0, but doc can be 0!
if (key == 0) {
TRI_FreeJson(TRI_CORE_MEM_ZONE, json);
errorMsg = invalidMsg;
res = TRI_ERROR_HTTP_BAD_PARAMETER;
break;
}
if (0 != doc && type != MARKER_REMOVE) {
ShardID responsibleShard;
bool usesDefaultSharding;
res = ci->getResponsibleShard(col->id_as_string(), doc, true,
responsibleShard, usesDefaultSharding);
if (res != TRI_ERROR_NO_ERROR) {
TRI_FreeJson(TRI_CORE_MEM_ZONE, json);
errorMsg = "error during determining responsible shard";
res = TRI_ERROR_INTERNAL;
break;
}
else {
it2 = shardTab.find(responsibleShard);
if (it2 == shardTab.end()) {
TRI_FreeJson(TRI_CORE_MEM_ZONE, json);
errorMsg = "cannot find responsible shard";
res = TRI_ERROR_INTERNAL;
break;
}
else {
bufs[it2->second]->appendText(ptr, pos-ptr);
bufs[it2->second]->appendText("\n");
}
}
}
else if (type == MARKER_REMOVE) {
// A remove marker, this has to be appended to all!
for (j = 0; j < bufs.size(); j++) {
bufs[j]->appendText(ptr, pos-ptr);
bufs[j]->appendText("\n");
}
}
else {
// How very strange!
TRI_FreeJson(TRI_CORE_MEM_ZONE, json);
errorMsg = invalidMsg;
res = TRI_ERROR_HTTP_BAD_PARAMETER;
break;
}
TRI_FreeJson(TRI_CORE_MEM_ZONE, json);
}
ptr = pos + 1;
}
if (res == TRI_ERROR_NO_ERROR) {
// Set a few variables needed for our work:
ClusterComm* cc = ClusterComm::instance();
// Send a synchronous request to that shard using ClusterComm:
ClusterCommResult* result;
CoordTransactionID coordTransactionID = TRI_NewTickServer();
for (it = shardIdsMap.begin(); it != shardIdsMap.end(); ++it) {
map<string, string>* headers = new map<string, string>;
it2 = shardTab.find(it->first);
if (it2 == shardTab.end()) {
errorMsg = "cannot find shard";
res = TRI_ERROR_INTERNAL;
}
else {
j = it2->second;
result = cc->asyncRequest("", coordTransactionID, "shard:" + it->first,
triagens::rest::HttpRequest::HTTP_REQUEST_PUT,
"/_db/" + StringUtils::urlEncode(dbName) +
"/_api/replication/restore-data?collection=" +
it->first,
new string(bufs[j]->c_str(), bufs[j]->length()),
true, headers, NULL, 300.0);
delete result;
}
}
// Now listen to the results:
int count;
int nrok = 0;
for (count = (int) shardIdsMap.size(); count > 0; count--) {
result = cc->wait( "", coordTransactionID, 0, "", 0.0);
if (result->status == CL_COMM_RECEIVED) {
if (result->answer_code == triagens::rest::HttpResponse::OK ||
result->answer_code == triagens::rest::HttpResponse::CREATED) {
TRI_json_t* json = TRI_JsonString(TRI_UNKNOWN_MEM_ZONE,
result->answer->body());
if (JsonHelper::isArray(json)) {
TRI_json_t const* r = TRI_LookupArrayJson(json, "result");
if (TRI_IsBooleanJson(r)) {
if (r->_value._boolean) {
nrok++;
}
}
}
if (json != 0) {
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
}
}
}
delete result;
}
if (nrok != shardIdsMap.size()) {
errorMsg = "some shard produced an error";
res = TRI_ERROR_INTERNAL;
}
}
// Free all the string buffers:
for (j = 0; j < shardIds.size(); j++) {
delete bufs[j];
}
if (res != TRI_ERROR_NO_ERROR) {
generateError(HttpResponse::BAD, res, errorMsg);
}
TRI_json_t result;
TRI_InitArrayJson(TRI_CORE_MEM_ZONE, &result);
@ -2873,7 +3077,6 @@ void RestReplicationHandler::handleCommandRestoreDataCoordinator () {
generateResult(&result);
}
}
#endif
////////////////////////////////////////////////////////////////////////////////

View File

@ -529,7 +529,7 @@ static v8::Handle<v8::Object> RequestCppToV8 ( TRI_v8_global_t const* v8g,
////////////////////////////////////////////////////////////////////////////////
static HttpResponse* ResponseV8ToCpp (TRI_v8_global_t const* v8g,
v8::Handle<v8::Object> const& res,
v8::Handle<v8::Object> const res,
uint32_t compatibility) {
HttpResponse::HttpResponseCode code = HttpResponse::OK;

View File

@ -229,7 +229,7 @@ static void CleanupExampleObject (TRI_memory_zone_t* zone,
/// @brief sets up the example object
////////////////////////////////////////////////////////////////////////////////
static int SetupExampleObject (v8::Handle<v8::Object> const& example,
static int SetupExampleObject (v8::Handle<v8::Object> const example,
TRI_shaper_t* shaper,
size_t& n,
TRI_shape_pid_t*& pids,

View File

@ -73,6 +73,7 @@
#include "VocBase/replication-logger.h"
#include "VocBase/server.h"
#include "VocBase/voc-shaper.h"
#include "VocBase/index.h"
#include "v8.h"
#include "V8/JSLoader.h"
@ -202,7 +203,7 @@ static int32_t const WRP_SHAPED_JSON_TYPE = 4;
////////////////////////////////////////////////////////////////////////////////
#ifdef TRI_ENABLE_CLUSTER
static int ParseKeyAndRef (v8::Handle<v8::Value> const& arg,
static int ParseKeyAndRef (v8::Handle<v8::Value> const arg,
string& key,
TRI_voc_rid_t& rev) {
TRI_v8_global_t* v8g = (TRI_v8_global_t*) v8::Isolate::GetCurrent()->GetData();
@ -497,7 +498,7 @@ static inline TRI_vocbase_t* GetContextVocBase () {
/// @brief checks if argument is a document identifier
////////////////////////////////////////////////////////////////////////////////
static bool ParseDocumentHandle (v8::Handle<v8::Value> const& arg,
static bool ParseDocumentHandle (v8::Handle<v8::Value> const arg,
string& collectionName,
TRI_voc_key_t& key) {
assert(collectionName == "");
@ -534,7 +535,7 @@ static bool ParseDocumentHandle (v8::Handle<v8::Value> const& arg,
/// @brief extracts a document key from a document
////////////////////////////////////////////////////////////////////////////////
static int ExtractDocumentKey (v8::Handle<v8::Value> const& arg,
static int ExtractDocumentKey (v8::Handle<v8::Value> const arg,
TRI_voc_key_t& key) {
TRI_v8_global_t* v8g = (TRI_v8_global_t*) v8::Isolate::GetCurrent()->GetData();
key = 0;
@ -576,7 +577,7 @@ static int ExtractDocumentKey (v8::Handle<v8::Value> const& arg,
/// @brief parse document or document handle from a v8 value (string | object)
////////////////////////////////////////////////////////////////////////////////
static bool ExtractDocumentHandle (v8::Handle<v8::Value> const& val,
static bool ExtractDocumentHandle (v8::Handle<v8::Value> const val,
string& collectionName,
TRI_voc_key_t& key,
TRI_voc_rid_t& rid) {
@ -656,7 +657,7 @@ static v8::Handle<v8::Value> ParseDocumentOrDocumentHandle (TRI_vocbase_t* vocba
TRI_vocbase_col_t const*& collection,
TRI_voc_key_t& key,
TRI_voc_rid_t& rid,
v8::Handle<v8::Value> const& val) {
v8::Handle<v8::Value> const val) {
v8::HandleScope scope;
assert(key == 0);
@ -745,7 +746,7 @@ static v8::Handle<v8::Value> ParseDocumentOrDocumentHandle (TRI_vocbase_t* vocba
/// @brief checks if argument is an index identifier
////////////////////////////////////////////////////////////////////////////////
static bool IsIndexHandle (v8::Handle<v8::Value> const& arg,
static bool IsIndexHandle (v8::Handle<v8::Value> const arg,
string& collectionName,
TRI_idx_iid_t& iid) {
@ -876,162 +877,11 @@ static v8::Handle<v8::Value> IndexRep (string const& collectionName,
return scope.Close(rep);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief index comparator, used by the coordinator to detect if two index
/// contents are the same
////////////////////////////////////////////////////////////////////////////////
#ifdef TRI_ENABLE_CLUSTER
static bool IndexComparator (TRI_json_t const* lhs,
TRI_json_t const* rhs) {
TRI_json_t* typeJson = TRI_LookupArrayJson(lhs, "type");
assert(TRI_IsStringJson(typeJson));
// type must be identical
if (! TRI_CheckSameValueJson(typeJson, TRI_LookupArrayJson(rhs, "type"))) {
return false;
}
TRI_idx_type_e type = TRI_TypeIndex(typeJson->_value._string.data);
// unique must be identical if present
TRI_json_t* value = TRI_LookupArrayJson(lhs, "unique");
if (TRI_IsBooleanJson(value)) {
if (! TRI_CheckSameValueJson(value, TRI_LookupArrayJson(rhs, "unique"))) {
return false;
}
}
if (type == TRI_IDX_TYPE_GEO1_INDEX) {
// geoJson must be identical if present
value = TRI_LookupArrayJson(lhs, "geoJson");
if (TRI_IsBooleanJson(value)) {
if (! TRI_CheckSameValueJson(value, TRI_LookupArrayJson(rhs, "geoJson"))) {
return false;
}
}
value = TRI_LookupArrayJson(lhs, "ignoreNull");
if (TRI_IsBooleanJson(value)) {
if (! TRI_CheckSameValueJson(value, TRI_LookupArrayJson(rhs, "ignoreNull"))) {
return false;
}
}
}
else if (type == TRI_IDX_TYPE_GEO2_INDEX) {
value = TRI_LookupArrayJson(lhs, "ignoreNull");
if (TRI_IsBooleanJson(value)) {
if (! TRI_CheckSameValueJson(value, TRI_LookupArrayJson(rhs, "ignoreNull"))) {
return false;
}
}
}
else if (type == TRI_IDX_TYPE_FULLTEXT_INDEX) {
// minLength
value = TRI_LookupArrayJson(lhs, "minLength");
if (TRI_IsNumberJson(value)) {
if (! TRI_CheckSameValueJson(value, TRI_LookupArrayJson(rhs, "minLength"))) {
return false;
}
}
}
else if (type == TRI_IDX_TYPE_CAP_CONSTRAINT) {
// size, byteSize
value = TRI_LookupArrayJson(lhs, "size");
if (TRI_IsNumberJson(value)) {
if (! TRI_CheckSameValueJson(value, TRI_LookupArrayJson(rhs, "size"))) {
return false;
}
}
value = TRI_LookupArrayJson(lhs, "byteSize");
if (TRI_IsNumberJson(value)) {
if (! TRI_CheckSameValueJson(value, TRI_LookupArrayJson(rhs, "byteSize"))) {
return false;
}
}
}
if (type == TRI_IDX_TYPE_BITARRAY_INDEX) {
// bitarray indexes are considered identical if they are based on the same attributes
TRI_json_t const* r = TRI_LookupArrayJson(rhs, "fields");
value = TRI_LookupArrayJson(lhs, "fields");
if (TRI_IsListJson(value) &&
TRI_IsListJson(r) &&
value->_value._objects._length == r->_value._objects._length) {
for (size_t i = 0; i < value->_value._objects._length; ++i) {
TRI_json_t const* l1 = TRI_LookupListJson(value, i);
TRI_json_t const* r1 = TRI_LookupListJson(r, i);
if (TRI_IsListJson(l1) &&
TRI_IsListJson(r1) &&
l1->_value._objects._length == 2 &&
r1->_value._objects._length == 2) {
// element at position 0 is the attribute name
if (! TRI_CheckSameValueJson(TRI_LookupListJson(l1, 0), TRI_LookupListJson(r1, 0))) {
return false;
}
}
}
}
// we must always exit here to avoid the "regular" fields comparison
return true;
}
// other index types: fields must be identical if present
value = TRI_LookupArrayJson(lhs, "fields");
if (TRI_IsListJson(value)) {
if (type == TRI_IDX_TYPE_HASH_INDEX) {
// compare fields in arbitrary order
TRI_json_t const* r = TRI_LookupArrayJson(rhs, "fields");
if (! TRI_IsListJson(r) ||
value->_value._objects._length != r->_value._objects._length) {
return false;
}
for (size_t i = 0; i < value->_value._objects._length; ++i) {
TRI_json_t const* v = TRI_LookupListJson(value, i);
bool found = false;
for (size_t j = 0; j < r->_value._objects._length; ++j) {
if (TRI_CheckSameValueJson(v, TRI_LookupListJson(r, j))) {
found = true;
break;
}
}
if (! found) {
return false;
}
}
}
else {
if (! TRI_CheckSameValueJson(value, TRI_LookupArrayJson(rhs, "fields"))) {
return false;
}
}
}
return true;
}
#endif
////////////////////////////////////////////////////////////////////////////////
/// @brief extract the unique flag from the data
////////////////////////////////////////////////////////////////////////////////
bool ExtractBoolFlag (v8::Handle<v8::Object> const& obj,
bool ExtractBoolFlag (v8::Handle<v8::Object> const obj,
char const* name,
bool defaultValue) {
// extract unique flag
@ -1046,7 +896,7 @@ bool ExtractBoolFlag (v8::Handle<v8::Object> const& obj,
/// @brief process the fields list and add them to the json
////////////////////////////////////////////////////////////////////////////////
int ProcessBitarrayIndexFields (v8::Handle<v8::Object> const& obj,
int ProcessBitarrayIndexFields (v8::Handle<v8::Object> const obj,
TRI_json_t* json,
bool create) {
vector<string> fields;
@ -1136,7 +986,7 @@ int ProcessBitarrayIndexFields (v8::Handle<v8::Object> const& obj,
/// @brief process the fields list and add them to the json
////////////////////////////////////////////////////////////////////////////////
int ProcessIndexFields (v8::Handle<v8::Object> const& obj,
int ProcessIndexFields (v8::Handle<v8::Object> const obj,
TRI_json_t* json,
int numFields,
bool create) {
@ -1189,7 +1039,7 @@ int ProcessIndexFields (v8::Handle<v8::Object> const& obj,
/// @brief process the geojson flag and add it to the json
////////////////////////////////////////////////////////////////////////////////
int ProcessIndexGeoJsonFlag (v8::Handle<v8::Object> const& obj,
int ProcessIndexGeoJsonFlag (v8::Handle<v8::Object> const obj,
TRI_json_t* json) {
bool geoJson = ExtractBoolFlag(obj, "geoJson", false);
TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, json, "geoJson", TRI_CreateBooleanJson(TRI_UNKNOWN_MEM_ZONE, geoJson));
@ -1201,7 +1051,7 @@ int ProcessIndexGeoJsonFlag (v8::Handle<v8::Object> const& obj,
/// @brief process the unique flag and add it to the json
////////////////////////////////////////////////////////////////////////////////
int ProcessIndexUniqueFlag (v8::Handle<v8::Object> const& obj,
int ProcessIndexUniqueFlag (v8::Handle<v8::Object> const obj,
TRI_json_t* json,
bool fillConstraint = false) {
bool unique = ExtractBoolFlag(obj, "unique", false);
@ -1217,7 +1067,7 @@ int ProcessIndexUniqueFlag (v8::Handle<v8::Object> const& obj,
/// @brief process the ignoreNull flag and add it to the json
////////////////////////////////////////////////////////////////////////////////
int ProcessIndexIgnoreNullFlag (v8::Handle<v8::Object> const& obj,
int ProcessIndexIgnoreNullFlag (v8::Handle<v8::Object> const obj,
TRI_json_t* json) {
bool ignoreNull = ExtractBoolFlag(obj, "ignoreNull", false);
TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, json, "ignoreNull", TRI_CreateBooleanJson(TRI_UNKNOWN_MEM_ZONE, ignoreNull));
@ -1229,7 +1079,7 @@ int ProcessIndexIgnoreNullFlag (v8::Handle<v8::Object> const& obj,
/// @brief process the undefined flag and add it to the json
////////////////////////////////////////////////////////////////////////////////
int ProcessIndexUndefinedFlag (v8::Handle<v8::Object> const& obj,
int ProcessIndexUndefinedFlag (v8::Handle<v8::Object> const obj,
TRI_json_t* json) {
bool undefined = ExtractBoolFlag(obj, "undefined", false);
TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, json, "undefined", TRI_CreateBooleanJson(TRI_UNKNOWN_MEM_ZONE, undefined));
@ -1241,7 +1091,7 @@ int ProcessIndexUndefinedFlag (v8::Handle<v8::Object> const& obj,
/// @brief enhances the json of a geo1 index
////////////////////////////////////////////////////////////////////////////////
static int EnhanceJsonIndexGeo1 (v8::Handle<v8::Object> const& obj,
static int EnhanceJsonIndexGeo1 (v8::Handle<v8::Object> const obj,
TRI_json_t* json,
bool create) {
int res = ProcessIndexFields(obj, json, 1, create);
@ -1255,7 +1105,7 @@ static int EnhanceJsonIndexGeo1 (v8::Handle<v8::Object> const& obj,
/// @brief enhances the json of a geo2 index
////////////////////////////////////////////////////////////////////////////////
static int EnhanceJsonIndexGeo2 (v8::Handle<v8::Object> const& obj,
static int EnhanceJsonIndexGeo2 (v8::Handle<v8::Object> const obj,
TRI_json_t* json,
bool create) {
int res = ProcessIndexFields(obj, json, 2, create);
@ -1268,7 +1118,7 @@ static int EnhanceJsonIndexGeo2 (v8::Handle<v8::Object> const& obj,
/// @brief enhances the json of a hash index
////////////////////////////////////////////////////////////////////////////////
static int EnhanceJsonIndexHash (v8::Handle<v8::Object> const& obj,
static int EnhanceJsonIndexHash (v8::Handle<v8::Object> const obj,
TRI_json_t* json,
bool create) {
int res = ProcessIndexFields(obj, json, 0, create);
@ -1280,7 +1130,7 @@ static int EnhanceJsonIndexHash (v8::Handle<v8::Object> const& obj,
/// @brief enhances the json of a skiplist index
////////////////////////////////////////////////////////////////////////////////
static int EnhanceJsonIndexSkiplist (v8::Handle<v8::Object> const& obj,
static int EnhanceJsonIndexSkiplist (v8::Handle<v8::Object> const obj,
TRI_json_t* json,
bool create) {
int res = ProcessIndexFields(obj, json, 0, create);
@ -1292,7 +1142,7 @@ static int EnhanceJsonIndexSkiplist (v8::Handle<v8::Object> const& obj,
/// @brief enhances the json of a bitarray index
////////////////////////////////////////////////////////////////////////////////
static int EnhanceJsonIndexBitarray (v8::Handle<v8::Object> const& obj,
static int EnhanceJsonIndexBitarray (v8::Handle<v8::Object> const obj,
TRI_json_t* json,
bool create) {
int res = ProcessBitarrayIndexFields(obj, json, create);
@ -1308,7 +1158,7 @@ static int EnhanceJsonIndexBitarray (v8::Handle<v8::Object> const& obj,
/// @brief enhances the json of a fulltext index
////////////////////////////////////////////////////////////////////////////////
static int EnhanceJsonIndexFulltext (v8::Handle<v8::Object> const& obj,
static int EnhanceJsonIndexFulltext (v8::Handle<v8::Object> const obj,
TRI_json_t* json,
bool create) {
int res = ProcessIndexFields(obj, json, 1, create);
@ -1327,7 +1177,7 @@ static int EnhanceJsonIndexFulltext (v8::Handle<v8::Object> const& obj,
/// @brief enhances the json of a cap constraint
////////////////////////////////////////////////////////////////////////////////
static int EnhanceJsonIndexCap (v8::Handle<v8::Object> const& obj,
static int EnhanceJsonIndexCap (v8::Handle<v8::Object> const obj,
TRI_json_t* json) {
// handle "size" attribute
size_t count = 0;
@ -5380,9 +5230,6 @@ static v8::Handle<v8::Value> JS_RunAhuacatl (v8::Arguments const& argv) {
TRI_ObjectToString(tryCatch.Exception()).c_str());
return scope.Close(v8::ThrowException(errorObject));
}
else {
return scope.Close(result);
}
}
return scope.Close(result);
@ -6425,7 +6272,7 @@ static v8::Handle<v8::Value> JS_DropVocbaseCol (v8::Arguments const& argv) {
#ifdef TRI_ENABLE_CLUSTER
static v8::Handle<v8::Value> DropIndexCoordinator (CollectionNameResolver const& resolver,
TRI_vocbase_col_t const* collection,
v8::Handle<v8::Value> const& val) {
v8::Handle<v8::Value> const val) {
v8::HandleScope scope;
string collectionName = "";
@ -7755,7 +7602,7 @@ static v8::Handle<v8::Value> SaveVocbaseColCoordinator (TRI_vocbase_col_t* colle
/// @brief extract a key from a v8 object
////////////////////////////////////////////////////////////////////////////////
static string GetId (v8::Handle<v8::Value> const& arg) {
static string GetId (v8::Handle<v8::Value> const arg) {
if (arg->IsObject() && ! arg->IsArray()) {
v8::Local<v8::Object> obj = arg->ToObject();
@ -8402,7 +8249,7 @@ static v8::Handle<v8::Value> MapGetVocBase (v8::Local<v8::String> const name,
////////////////////////////////////////////////////////////////////////////////
static TRI_vocbase_col_t* GetCollectionFromArgument (TRI_vocbase_t* vocbase,
v8::Handle<v8::Value> const& val) {
v8::Handle<v8::Value> const val) {
// number
if (val->IsNumber() || val->IsNumberObject()) {
uint64_t cid = (uint64_t) TRI_ObjectToUInt64(val, true);
@ -9228,13 +9075,17 @@ static v8::Handle<v8::Value> ListDatabasesCoordinator (v8::Arguments const& argv
res = cc->syncRequest("", 0, "server:" + sid,
triagens::rest::HttpRequest::HTTP_REQUEST_GET,
"/_api/database/user", string(""), headers, 0.0);
if (res->status == CL_COMM_SENT) {
// We got an array back as JSON, let's parse it and build a v8
StringBuffer& body = res->result->getBody();
delete res;
TRI_json_t* json = JsonHelper::fromString(body.c_str());
delete res;
if (json != 0 && JsonHelper::isArray(json)) {
TRI_json_t const* dotresult = JsonHelper::getArrayElement(json, "result");
if (dotresult != 0) {
vector<string> list = JsonHelper::stringList(dotresult);
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
@ -10122,7 +9973,7 @@ static v8::Handle<v8::Value> MapGetIndexedShapedJson (uint32_t idx,
int TRI_ParseVertex (CollectionNameResolver const& resolver,
TRI_voc_cid_t& cid,
TRI_voc_key_t& key,
v8::Handle<v8::Value> const& val,
v8::Handle<v8::Value> const val,
bool translateName) {
v8::HandleScope scope;

View File

@ -60,7 +60,7 @@ namespace triagens {
int TRI_ParseVertex (triagens::arango::CollectionNameResolver const&,
TRI_voc_cid_t&,
TRI_voc_key_t&,
v8::Handle<v8::Value> const&,
v8::Handle<v8::Value> const,
bool);
////////////////////////////////////////////////////////////////////////////////

View File

@ -30,6 +30,7 @@
#include "BasicsC/conversions.h"
#include "BasicsC/files.h"
#include "BasicsC/json.h"
#include "BasicsC/json-utilities.h"
#include "BasicsC/linked-list.h"
#include "BasicsC/logging.h"
#include "BasicsC/string-buffer.h"
@ -2680,6 +2681,156 @@ void TRI_FreeBitarrayIndex (TRI_index_t* idx) {
TRI_Free(TRI_CORE_MEM_ZONE, idx);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief index comparator, used by the coordinator to detect if two index
/// contents are the same
////////////////////////////////////////////////////////////////////////////////
#ifdef TRI_ENABLE_CLUSTER
bool IndexComparator (TRI_json_t const* lhs,
TRI_json_t const* rhs) {
TRI_json_t* typeJson = TRI_LookupArrayJson(lhs, "type");
assert(TRI_IsStringJson(typeJson));
// type must be identical
if (! TRI_CheckSameValueJson(typeJson, TRI_LookupArrayJson(rhs, "type"))) {
return false;
}
TRI_idx_type_e type = TRI_TypeIndex(typeJson->_value._string.data);
// unique must be identical if present
TRI_json_t* value = TRI_LookupArrayJson(lhs, "unique");
if (TRI_IsBooleanJson(value)) {
if (! TRI_CheckSameValueJson(value, TRI_LookupArrayJson(rhs, "unique"))) {
return false;
}
}
if (type == TRI_IDX_TYPE_GEO1_INDEX) {
// geoJson must be identical if present
value = TRI_LookupArrayJson(lhs, "geoJson");
if (TRI_IsBooleanJson(value)) {
if (! TRI_CheckSameValueJson(value, TRI_LookupArrayJson(rhs, "geoJson"))) {
return false;
}
}
value = TRI_LookupArrayJson(lhs, "ignoreNull");
if (TRI_IsBooleanJson(value)) {
if (! TRI_CheckSameValueJson(value, TRI_LookupArrayJson(rhs, "ignoreNull"))) {
return false;
}
}
}
else if (type == TRI_IDX_TYPE_GEO2_INDEX) {
value = TRI_LookupArrayJson(lhs, "ignoreNull");
if (TRI_IsBooleanJson(value)) {
if (! TRI_CheckSameValueJson(value, TRI_LookupArrayJson(rhs, "ignoreNull"))) {
return false;
}
}
}
else if (type == TRI_IDX_TYPE_FULLTEXT_INDEX) {
// minLength
value = TRI_LookupArrayJson(lhs, "minLength");
if (TRI_IsNumberJson(value)) {
if (! TRI_CheckSameValueJson(value, TRI_LookupArrayJson(rhs, "minLength"))) {
return false;
}
}
}
else if (type == TRI_IDX_TYPE_CAP_CONSTRAINT) {
// size, byteSize
value = TRI_LookupArrayJson(lhs, "size");
if (TRI_IsNumberJson(value)) {
if (! TRI_CheckSameValueJson(value, TRI_LookupArrayJson(rhs, "size"))) {
return false;
}
}
value = TRI_LookupArrayJson(lhs, "byteSize");
if (TRI_IsNumberJson(value)) {
if (! TRI_CheckSameValueJson(value, TRI_LookupArrayJson(rhs, "byteSize"))) {
return false;
}
}
}
if (type == TRI_IDX_TYPE_BITARRAY_INDEX) {
// bitarray indexes are considered identical if they are based on the same attributes
TRI_json_t const* r = TRI_LookupArrayJson(rhs, "fields");
value = TRI_LookupArrayJson(lhs, "fields");
if (TRI_IsListJson(value) &&
TRI_IsListJson(r) &&
value->_value._objects._length == r->_value._objects._length) {
for (size_t i = 0; i < value->_value._objects._length; ++i) {
TRI_json_t const* l1 = TRI_LookupListJson(value, i);
TRI_json_t const* r1 = TRI_LookupListJson(r, i);
if (TRI_IsListJson(l1) &&
TRI_IsListJson(r1) &&
l1->_value._objects._length == 2 &&
r1->_value._objects._length == 2) {
// element at position 0 is the attribute name
if (! TRI_CheckSameValueJson(TRI_LookupListJson(l1, 0), TRI_LookupListJson(r1, 0))) {
return false;
}
}
}
}
// we must always exit here to avoid the "regular" fields comparison
return true;
}
// other index types: fields must be identical if present
value = TRI_LookupArrayJson(lhs, "fields");
if (TRI_IsListJson(value)) {
if (type == TRI_IDX_TYPE_HASH_INDEX) {
// compare fields in arbitrary order
TRI_json_t const* r = TRI_LookupArrayJson(rhs, "fields");
if (! TRI_IsListJson(r) ||
value->_value._objects._length != r->_value._objects._length) {
return false;
}
for (size_t i = 0; i < value->_value._objects._length; ++i) {
TRI_json_t const* v = TRI_LookupListJson(value, i);
bool found = false;
for (size_t j = 0; j < r->_value._objects._length; ++j) {
if (TRI_CheckSameValueJson(v, TRI_LookupListJson(r, j))) {
found = true;
break;
}
}
if (! found) {
return false;
}
}
}
else {
if (! TRI_CheckSameValueJson(value, TRI_LookupArrayJson(rhs, "fields"))) {
return false;
}
}
}
return true;
}
#endif
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

View File

@ -600,6 +600,15 @@ void TRI_DestroyBitarrayIndex (TRI_index_t*);
void TRI_FreeBitarrayIndex (TRI_index_t*);
////////////////////////////////////////////////////////////////////////////////
/// @brief index comparator, used by the coordinator to detect if two index
/// contents are the same
////////////////////////////////////////////////////////////////////////////////
#ifdef TRI_ENABLE_CLUSTER
bool IndexComparator (TRI_json_t const* lhs, TRI_json_t const* rhs);
#endif
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

View File

@ -16,7 +16,7 @@
<input type="checkbox" value="useSSLonDBservers" class="useSSLonDBservers" <%=useSSLonDBservers?'checked="checked"':''%>> on DBServers
</label>
<label class="checkbox inline">
<input type="checkbox" value="useSSLonCoordinators" class="useSSLonCoordinators" <%=useSSLonCoordinators?'checked="checked"':''%>> on Coordinators
<input type="checkbox" disabled=true value="useSSLonCoordinators" class="useSSLonCoordinators" <%=useSSLonCoordinators?'checked="checked"':''%>> on Coordinators
</label>
</div>
</div>

View File

@ -251,12 +251,16 @@
"test/specs/views/dbSelectionViewSpec.js",
"test/specs/views/navigationViewSpec.js",
"test/specs/views/graphViewSpec.js",
"test/specs/views/loginViewSpec.js",
"test/specs/views/userBarViewSpec.js",
"test/specs/views/documentsViewSpec.js",
"test/specs/views/documentViewSpec.js",
"test/specs/views/dashboardViewSpec.js",
"test/specs/views/graphManagementViewSpec.js",
"test/specs/views/newLogsViewSpec.js",
"test/specs/views/notificationViewSpec.js",
"test/specs/views/statisticBarViewSpec.js",
"test/clusterSpecs/views/shutdownButtonViewSpec.js",

View File

@ -15,8 +15,10 @@
div.id = "clusterCollections";
document.body.appendChild(div);
shardsView = {
render: function() {},
unrender: function() {}
render: function () {
},
unrender: function () {
}
};
shardCol = {
__refId: "testId"

View File

@ -13,7 +13,8 @@
div.id = "content";
document.body.appendChild(div);
overview = {
render: function(){}
render: function () {
}
};
spyOn(window, "ClusterOverviewView").andReturn(overview);
});

View File

@ -14,8 +14,10 @@
div.id = "clusterDatabases";
document.body.appendChild(div);
colView = {
render: function() {},
unrender: function() {}
render: function () {
},
unrender: function () {
}
};
colCol = {
__id: "refId"

View File

@ -17,12 +17,16 @@
div.id = "clusterOverview";
document.body.appendChild(div);
serverView = {
render: function() {},
unrender: function() {}
render: function () {
},
unrender: function () {
}
};
coordinatorView = {
render: function() {},
unrender: function() {}
render: function () {
},
unrender: function () {
}
};
serverStatus = "warning";
serverHaving = 3;

View File

@ -13,8 +13,10 @@
div.id = "clusterServers";
document.body.appendChild(div);
dbView = {
render: function() {},
unrender: function() {}
render: function () {
},
unrender: function () {
}
};
dbCol = {
__id: "testId"

View File

@ -43,7 +43,8 @@
var cols = [edgeCol, docCol, sysCol];
spyOn($, "ajax").andCallFake(function (url) {
return {done:function() {}};
return {done: function () {
}};
});
myStore = new window.arangoCollections(cols);
spyOn(window, "isCoordinator").andReturn(isCoordinator);
@ -338,8 +339,10 @@
it("test toggleView", function () {
myView.render();
var a = {
toggleClass : function() {},
slideToggle : function() {}
toggleClass: function () {
},
slideToggle: function () {
}
};
spyOn(window, "$").andReturn(a);
@ -359,7 +362,8 @@
}
},
a = {
click : function() {}
click: function () {
}
};
spyOn(window, "$").andReturn(a);
@ -370,14 +374,18 @@
});
it(
"test set #collectionsToggle is deactivated when #collectionsDropdown2 is invisible",
"test set #collectionsToggle is deactivated when " +
"#collectionsDropdown2 is invisible",
function () {
var a = {
css: function () {
return 'none';
},
is : function(){return true;},
show : function(){},
is: function () {
return true;
},
show: function () {
},
append: function () {
return {
render: function () {
@ -385,11 +393,16 @@
}
};
},
removeClass : function() {},
val : function(){},
focus : function(){},
html : function(){},
attr : function(){}
removeClass: function () {
},
val: function () {
},
focus: function () {
},
html: function () {
},
attr: function () {
}
};
spyOn(window, "CollectionListItemView").andReturn({

View File

@ -624,8 +624,7 @@
{1: "blub"}
];
expect(view.getFilterContent()).toEqual([
{ attribute : 'name0', operator : 'operator0', value :
{ jsonval : 1 } },
{ attribute: 'name0', operator: 'operator0', value: { jsonval: 1 } },
{ attribute: 'name1', operator: 'operator1', value: 'stringval' }
]);
expect(window.$).toHaveBeenCalledWith("#attribute_value0");
@ -654,8 +653,7 @@
spyOn(window, "$").andReturn(jQueryDummy);
spyOn(view, "getFilterContent").andReturn(
[
{ attribute : 'name0', operator : 'operator0', value :
{ jsonval : 1 } },
{ attribute: 'name0', operator: 'operator0', value: { jsonval: 1 } },
{ attribute: 'name1', operator: 'operator1', value: 'stringval' }
]
@ -2798,7 +2796,8 @@
spyOn(view, "drawTable");
spyOn(view, "renderPagination");
view.collection = {
getDocuments : function () {}
getDocuments: function () {
}
};
spyOn(view.collection, "getDocuments");
@ -2826,8 +2825,10 @@
it("setCollectionId", function () {
view.collection = {
setCollection : function () {},
getDocuments : function () {}
setCollection: function () {
},
getDocuments: function () {
}
};
var arangoCollectionsDummy = {
@ -2852,7 +2853,9 @@
it("renderPaginationElements", function () {
view.collection = {
getTotal: function() {return 5;}
getTotal: function () {
return 5;
}
};
spyOn(view.collection, "getTotal").andCallThrough();
@ -2880,7 +2883,9 @@
it("renderPaginationElements with total = 0", function () {
view.collection = {
getTotal : function () {return 5;}
getTotal: function () {
return 5;
}
};
spyOn(view.collection, "getTotal").andCallThrough();
@ -2925,8 +2930,6 @@
});
});
}());

View File

@ -236,7 +236,10 @@
it("should be able to display an array of arrays", function () {
key = "myKey";
val = [[1, 2, 3], ["string"]];
val = [
[1, 2, 3],
["string"]
];
var view = new ViewClass({
key: key,
value: val,
@ -262,7 +265,10 @@
it("should be able to store an array of arrays", function () {
key = "myKey";
val = [[1, 2, 3], ["string"]];
val = [
[1, 2, 3],
["string"]
];
var view = new ViewClass({
key: key,
value: "",

View File

@ -216,7 +216,8 @@
};
spyOn(window.App, "navigate");
$("#manageGraphs").click();
expect(window.App.navigate).toHaveBeenCalledWith("graphManagement", {trigger: true});
expect(window.App.navigate).toHaveBeenCalledWith(
"graphManagement", {trigger: true});
delete window.App;
});
});

View File

@ -0,0 +1,269 @@
/*jslint indent: 2, nomen: true, maxlen: 100, white: true plusplus: true*/
/*global describe, beforeEach, afterEach, it, spyOn, expect, jasmine*/
/*global window, document, hljs, $*/
(function () {
"use strict";
describe("The loginView", function () {
var view;
beforeEach(function () {
window.App = {
navigate: function () {
throw "This should be a spy";
}
};
view = new window.loginView();
expect(view.events).toEqual({
"click #submitLogin": "login",
"keydown #loginUsername": "checkKey",
"keydown #loginPassword": "checkKey"
});
});
afterEach(function () {
delete window.App;
});
it("should render", function () {
view.template = {
render: function () {
}
};
var collectionDummy = {
add: function () {
}
}, jqueryDummy = {
html: function () {
},
hide: function () {
},
focus: function () {
},
val: function () {
}
};
view.collection = collectionDummy;
spyOn(view.template, "render").andReturn(1);
spyOn(collectionDummy, "add");
spyOn(jqueryDummy, "html");
spyOn(jqueryDummy, "hide");
spyOn(jqueryDummy, "focus");
spyOn(jqueryDummy, "val");
spyOn(view, "addDummyUser").andCallThrough();
spyOn(window, "$").andReturn(jqueryDummy);
view.render();
expect(view.collection.add).toHaveBeenCalledWith({
"userName": "admin",
"sessionId": "abc123",
"password": "admin",
"userId": 1
});
expect(window.$).toHaveBeenCalledWith(".header");
expect(window.$).toHaveBeenCalledWith(".footer");
expect(window.$).toHaveBeenCalledWith('#loginUsername');
expect(window.$).toHaveBeenCalledWith('#loginPassword');
expect(jqueryDummy.html).toHaveBeenCalledWith(1);
expect(jqueryDummy.hide).toHaveBeenCalled();
expect(jqueryDummy.focus).toHaveBeenCalled();
expect(jqueryDummy.val).toHaveBeenCalledWith('admin');
expect(view.addDummyUser).toHaveBeenCalled();
expect(view.template.render).toHaveBeenCalledWith({});
});
it("should checkKey", function () {
spyOn(view, "login");
view.checkKey({keyCode: 13});
expect(view.login).toHaveBeenCalled();
});
it("should checkKey with invalid key", function () {
spyOn(view, "login");
view.checkKey({keyCode: 12});
expect(view.login).not.toHaveBeenCalled();
});
it("should login", function () {
var collectionDummy = {
login: function () {
},
loadUserSettings: function () {
}
}, jqueryDummy = {
show: function () {
},
text: function () {
},
val: function () {
}
};
view.collection = collectionDummy;
spyOn(collectionDummy, "login").andReturn(true);
spyOn(collectionDummy, "loadUserSettings");
spyOn(jqueryDummy, "show");
spyOn(jqueryDummy, "text");
spyOn(jqueryDummy, "val").andReturn("someData");
spyOn(window, "$").andReturn(jqueryDummy);
spyOn(window.App, "navigate");
view.login();
expect(view.collection.login).toHaveBeenCalledWith("someData", "someData");
expect(view.collection.loadUserSettings).toHaveBeenCalled();
expect(window.$).toHaveBeenCalledWith(".header");
expect(window.$).toHaveBeenCalledWith(".footer");
expect(window.$).toHaveBeenCalledWith('#loginUsername');
expect(window.$).toHaveBeenCalledWith('#loginPassword');
expect(window.$).toHaveBeenCalledWith('#currentUser');
expect(window.App.navigate).toHaveBeenCalledWith("/", {trigger: true});
expect(jqueryDummy.show).toHaveBeenCalled();
expect(jqueryDummy.text).toHaveBeenCalledWith("someData");
expect(jqueryDummy.val).toHaveBeenCalled();
});
it("should login but fail", function () {
var collectionDummy = {
login: function () {
},
loadUserSettings: function () {
}
}, jqueryDummy = {
show: function () {
},
text: function () {
},
val: function () {
}
};
view.collection = collectionDummy;
spyOn(collectionDummy, "login").andReturn(false);
spyOn(collectionDummy, "loadUserSettings");
spyOn(jqueryDummy, "show");
spyOn(jqueryDummy, "text");
spyOn(jqueryDummy, "val").andReturn("someData");
spyOn(window, "$").andReturn(jqueryDummy);
spyOn(window.App, "navigate");
view.login();
expect(view.collection.login).toHaveBeenCalledWith("someData", "someData");
expect(view.collection.loadUserSettings).not.toHaveBeenCalled();
expect(window.$).toHaveBeenCalledWith('#loginUsername');
expect(window.$).toHaveBeenCalledWith('#loginPassword');
expect(window.App.navigate).not.toHaveBeenCalled();
expect(jqueryDummy.show).not.toHaveBeenCalled();
expect(jqueryDummy.text).not.toHaveBeenCalled();
expect(jqueryDummy.val).toHaveBeenCalled();
});
it("should not login due to mnissing data", function () {
var collectionDummy = {
login: function () {
},
loadUserSettings: function () {
}
}, jqueryDummy = {
show: function () {
},
text: function () {
},
val: function () {
}
};
view.collection = collectionDummy;
spyOn(collectionDummy, "login").andReturn(false);
spyOn(collectionDummy, "loadUserSettings");
spyOn(jqueryDummy, "show");
spyOn(jqueryDummy, "text");
spyOn(jqueryDummy, "val").andReturn("");
spyOn(window, "$").andReturn(jqueryDummy);
spyOn(window.App, "navigate");
view.login();
expect(view.collection.login).not.toHaveBeenCalled();
expect(view.collection.loadUserSettings).not.toHaveBeenCalled();
expect(window.$).toHaveBeenCalledWith('#loginUsername');
expect(window.$).toHaveBeenCalledWith('#loginPassword');
expect(window.App.navigate).not.toHaveBeenCalled();
expect(jqueryDummy.show).not.toHaveBeenCalled();
expect(jqueryDummy.text).not.toHaveBeenCalled();
expect(jqueryDummy.val).toHaveBeenCalled();
});
});
}());

View File

@ -385,7 +385,8 @@
};
expect(testee.events).not.toEqual(myEvents);
spyOn(testee, "delegateEvents");
testee.show("modalTable.ejs", "Delegate Events", undefined, undefined, undefined, myEvents);
testee.show("modalTable.ejs", "Delegate Events",
undefined, undefined, undefined, myEvents);
expect(testee.events).toEqual(myEvents);
expect(testee.delegateEvents).toHaveBeenCalled();
});
@ -394,7 +395,8 @@
spyOn(testee, "createModalHotkeys");
spyOn(testee, "createInitModalHotkeys");
testee.enabledHotkey = false;
testee.show("modalTable.ejs", "Delegate Events", undefined, undefined, undefined, undefined);
testee.show("modalTable.ejs", "Delegate Events",
undefined, undefined, undefined, undefined);
expect(testee.createModalHotkeys).toHaveBeenCalled();
expect(testee.createInitModalHotkeys).toHaveBeenCalled();
@ -404,7 +406,8 @@
spyOn(testee, "createModalHotkeys");
spyOn(testee, "createInitModalHotkeys");
testee.enabledHotkey = true;
testee.show("modalTable.ejs", "Delegate Events", undefined, undefined, undefined, undefined);
testee.show("modalTable.ejs", "Delegate Events",
undefined, undefined, undefined, undefined);
expect(testee.createModalHotkeys).toHaveBeenCalled();
expect(testee.createInitModalHotkeys).not.toHaveBeenCalled();
});
@ -432,7 +435,6 @@
btn = $(".button-" + btnObj.type, $(div));
spyOn($.fn, "click");
$(testee.el).trigger(e);

View File

@ -22,36 +22,42 @@
spyOn(window.App, "navigate");
window.currentDB = window.currentDB || {
get: function() {}
get: function () {
}
};
DBSelectionViewDummy = {
id: "DBSelectionViewDummy",
render : function(){}
render: function () {
}
};
UserBarViewDummy = {
id: "UserBarViewDummy",
render : function(){}
render: function () {
}
};
StatisticBarViewDummy = {
id: "StatisticBarViewDummy",
render : function(){}
render: function () {
}
};
NotificationViewDummy = {
id: "NotificationViewDummy",
render : function(){}
render: function () {
}
};
UserCollectionDummy = {
id: "UserCollectionDummy",
whoAmI : function () {return "root";}
whoAmI: function () {
return "root";
}
};
spyOn(window, "UserBarView").andReturn(UserBarViewDummy);
spyOn(window, "StatisticBarView").andReturn(StatisticBarViewDummy);
spyOn(window, "DBSelectionView").andReturn(DBSelectionViewDummy);

View File

@ -0,0 +1,188 @@
/*jslint indent: 2, nomen: true, maxlen: 100, white: true plusplus: true*/
/*global describe, beforeEach, afterEach, it, spyOn, expect, jasmine*/
/*global window, document, hljs, $*/
(function () {
"use strict";
describe("The StatisticBarView", function () {
var view;
beforeEach(function () {
window.App = {
navigate: function () {
throw "This should be a spy";
}
};
view = new window.StatisticBarView(
{
currentDB: {
get: function () {
return true;
}
}
});
expect(view.events).toEqual({
"change #arangoCollectionSelect": "navigateBySelect",
"click .tab": "navigateByTab"
});
});
afterEach(function () {
delete window.App;
});
it("should render", function () {
view.template = {
render: function () {
}
};
spyOn(view.template, "render").andReturn(1);
spyOn($.fn, "html");
spyOn($.fn, "find").andCallThrough();
spyOn($.fn, "attr").andCallThrough();
spyOn($.fn, "each").andCallFake(function (a) {
a();
});
spyOn($, "get").andCallFake(function (a, b, c) {
b();
});
view.render();
expect($.fn.html).toHaveBeenCalledWith(1);
expect($.fn.find).toHaveBeenCalledWith('svg');
expect($.fn.attr).toHaveBeenCalledWith('id');
expect($.fn.attr).toHaveBeenCalledWith('class');
expect($.fn.attr).toHaveBeenCalledWith('src');
expect(view.template.render).toHaveBeenCalledWith({
isSystem: true
});
});
it("should navigateBySelect", function () {
var jquerDummy = {
find: function () {
return jquerDummy;
},
val: function () {
return "bla";
}
};
spyOn(jquerDummy, "find").andCallThrough();
spyOn(jquerDummy, "val").andCallThrough();
spyOn(window, "$").andReturn(jquerDummy);
spyOn(window.App, "navigate");
view.navigateBySelect();
expect(window.$).toHaveBeenCalledWith("#arangoCollectionSelect");
expect(jquerDummy.find).toHaveBeenCalledWith("option:selected");
expect(jquerDummy.val).toHaveBeenCalled();
expect(window.App.navigate).toHaveBeenCalledWith("bla", {trigger: true});
});
it("should navigateByTab", function () {
var p = {
srcElement: {id: "bla"},
preventDefault: function () {
}
};
spyOn(window.App, "navigate");
spyOn(p, "preventDefault");
view.navigateByTab(p);
expect(p.preventDefault).toHaveBeenCalled();
expect(window.App.navigate).toHaveBeenCalledWith("bla", {trigger: true});
});
it("should navigateByTab to links", function () {
var p = {
srcElement: {id: "links"},
preventDefault: function () {
}
};
spyOn(window.App, "navigate");
spyOn(p, "preventDefault");
view.navigateByTab(p);
expect(p.preventDefault).toHaveBeenCalled();
expect(window.App.navigate).not.toHaveBeenCalled();
});
it("should navigateByTab to tools", function () {
var p = {
srcElement: {id: "tools"},
preventDefault: function () {
}
};
spyOn(p, "preventDefault");
view.navigateByTab(p);
expect(p.preventDefault).toHaveBeenCalled();
});
it("should handleSelectNavigation", function () {
var jQueryDummy = {
change: function () {
},
find: function () {
return jQueryDummy;
},
val: function () {
}
};
spyOn(window, "$").andReturn(jQueryDummy);
spyOn(window.App, "navigate");
spyOn(jQueryDummy, "val").andReturn("bla");
spyOn(jQueryDummy, "find").andCallThrough();
spyOn(jQueryDummy, "change").andCallFake(function (a) {
a();
});
view.handleSelectNavigation();
expect(window.$).toHaveBeenCalledWith("#arangoCollectionSelect");
expect(jQueryDummy.find).toHaveBeenCalledWith("option:selected");
expect(jQueryDummy.change).toHaveBeenCalled();
expect(jQueryDummy.val).toHaveBeenCalled();
expect(window.App.navigate).toHaveBeenCalledWith("bla", {trigger: true});
});
it("should selectMenuItem", function () {
var jQueryDummy = {
removeClass: function () {
},
addClass: function () {
}
};
spyOn(window, "$").andReturn(jQueryDummy);
spyOn(jQueryDummy, "removeClass");
spyOn(jQueryDummy, "addClass");
view.selectMenuItem("mm");
expect(window.$).toHaveBeenCalledWith('.navlist li');
expect(window.$).toHaveBeenCalledWith(".mm");
expect(jQueryDummy.removeClass).toHaveBeenCalledWith('active');
expect(jQueryDummy.addClass).toHaveBeenCalledWith('active');
});
});
}());

View File

@ -0,0 +1,315 @@
/*jslint indent: 2, nomen: true, maxlen: 100, white: true plusplus: true*/
/*global describe, beforeEach, afterEach, it, spyOn, expect, jasmine*/
/*global window, document, hljs, $*/
(function () {
"use strict";
describe("The loginView", function () {
var view, collectionDummy;
beforeEach(function () {
window.App = {
navigate: function () {
throw "This should be a spy";
}
};
collectionDummy = {
fetch: function () {
},
bind: function () {
},
whoAmI: function () {
},
logout: function () {
},
findWhere : function () {
}
};
spyOn(collectionDummy, "fetch");
spyOn(collectionDummy, "bind");
view = new window.UserBarView({userCollection: collectionDummy});
expect(collectionDummy.fetch).toHaveBeenCalledWith({async: false});
expect(collectionDummy.bind).toHaveBeenCalled();
expect(view.events).toEqual({
"change #userBarSelect": "navigateBySelect",
"click .tab": "navigateByTab",
"mouseenter .dropdown": "showDropdown",
"mouseleave .dropdown": "hideDropdown",
"click #userLogout": "userLogout"
});
});
afterEach(function () {
delete window.App;
});
it("should navigateBySelect", function () {
var jquerDummy = {
find: function () {
return jquerDummy;
},
val: function () {
return "bla";
}
};
spyOn(jquerDummy, "find").andCallThrough();
spyOn(jquerDummy, "val").andCallThrough();
spyOn(window, "$").andReturn(jquerDummy);
spyOn(window.App, "navigate");
view.navigateBySelect();
expect(window.$).toHaveBeenCalledWith("#arangoCollectionSelect");
expect(jquerDummy.find).toHaveBeenCalledWith("option:selected");
expect(jquerDummy.val).toHaveBeenCalled();
expect(window.App.navigate).toHaveBeenCalledWith("bla", {trigger: true});
});
it("should navigateByTab", function () {
var p = {
srcElement: {id: "bla"},
preventDefault: function () {
}
},jqueryDummy = {
closest : function () {
return jqueryDummy;
},
attr : function () {
},
slideToggle : function () {
}
};
spyOn(window, "$").andReturn(jqueryDummy);
spyOn(jqueryDummy, "closest").andCallThrough();
spyOn(jqueryDummy, "attr").andReturn("bla");
spyOn(window.App, "navigate");
spyOn(p, "preventDefault");
view.navigateByTab(p);
expect (window.$).toHaveBeenCalledWith({id: "bla"});
expect (jqueryDummy.closest).toHaveBeenCalledWith("a");
expect (jqueryDummy.attr).toHaveBeenCalledWith("id");
expect(p.preventDefault).toHaveBeenCalled();
expect(window.App.navigate).toHaveBeenCalledWith("bla", {trigger: true});
});
it("should navigateByTab to links", function () {
var p = {
srcElement: {id: "user"},
preventDefault: function () {
}
},jqueryDummy = {
closest : function () {
return jqueryDummy;
},
attr : function () {
},
slideToggle : function () {
}
};
spyOn(window, "$").andReturn(jqueryDummy);
spyOn(jqueryDummy, "closest").andCallThrough();
spyOn(jqueryDummy, "attr").andReturn("user");
spyOn(jqueryDummy, "slideToggle");
spyOn(window.App, "navigate");
spyOn(p, "preventDefault");
view.navigateByTab(p);
expect (window.$).toHaveBeenCalledWith({id: "user"});
expect (jqueryDummy.closest).toHaveBeenCalledWith("a");
expect (jqueryDummy.slideToggle).toHaveBeenCalledWith(200);
expect (jqueryDummy.attr).toHaveBeenCalledWith("id");
expect(p.preventDefault).toHaveBeenCalled();
expect(window.App.navigate).not.toHaveBeenCalled();
});
it("should navigateByTab to links", function () {
var p = {
srcElement: {id: "user"}
},jqueryDummy = {
show : function () {
}
};
spyOn(window, "$").andReturn(jqueryDummy);
spyOn(jqueryDummy, "show");
view.showDropdown(p);
expect (window.$).toHaveBeenCalledWith("#user_dropdown");
expect (jqueryDummy.show).toHaveBeenCalledWith(200);
});
it("should hideDropdown", function () {
var jqueryDummy = {
hide : function () {
}
};
spyOn(window, "$").andReturn(jqueryDummy);
spyOn(jqueryDummy, "hide");
view.hideDropdown();
expect (window.$).toHaveBeenCalledWith("#user_dropdown");
expect (jqueryDummy.hide).toHaveBeenCalled();
});
it("should userLogout", function () {
spyOn(collectionDummy, "whoAmI");
spyOn(collectionDummy, "logout");
view.userLogout();
expect (collectionDummy.whoAmI).toHaveBeenCalled();
expect (collectionDummy.logout).toHaveBeenCalled();
});
it("should render", function () {
view.template = {
render: function () {
}
};
var userDummy = {
set : function () {
},
get : function () {
}
};
spyOn(collectionDummy, "whoAmI").andReturn("userName");
spyOn(collectionDummy, "findWhere").andReturn(userDummy);
spyOn(userDummy, "set");
spyOn(userDummy, "get").andCallFake(function (a) {
if (a === "active") {
return true;
}
return {
img : undefined,
name : undefined
};
});
spyOn(view.template, "render").andReturn(1);
view.render();
expect (userDummy.set).toHaveBeenCalledWith({loggedIn : true});
expect (userDummy.get).toHaveBeenCalledWith("extra");
expect (userDummy.get).toHaveBeenCalledWith("active");
expect (collectionDummy.whoAmI).toHaveBeenCalled();
expect (collectionDummy.findWhere).toHaveBeenCalledWith({user: "userName"});
expect(view.template.render).toHaveBeenCalledWith({
img : "img/arangodblogoAvatar_24.png",
name : "",
username : "userName",
active : true
});
});
it("should render with image", function () {
view.template = {
render: function () {
}
};
var userDummy = {
set : function () {
},
get : function () {
}
};
spyOn(collectionDummy, "whoAmI").andReturn("userName");
spyOn(collectionDummy, "findWhere").andReturn(userDummy);
spyOn(userDummy, "set");
spyOn(userDummy, "get").andCallFake(function (a) {
if (a === "active") {
return true;
}
return {
img : "bla",
name : "name"
};
});
spyOn(view.template, "render").andReturn(1);
view.render();
expect (userDummy.set).toHaveBeenCalledWith({loggedIn : true});
expect (userDummy.get).toHaveBeenCalledWith("extra");
expect (userDummy.get).toHaveBeenCalledWith("active");
expect (collectionDummy.whoAmI).toHaveBeenCalled();
expect (collectionDummy.findWhere).toHaveBeenCalledWith({user: "userName"});
expect(view.template.render).toHaveBeenCalledWith({
img : "https://s.gravatar.com/avatar/bla?s=24",
name : "name",
username : "userName",
active : true
});
});
});
}());

View File

@ -114,6 +114,17 @@ function getAuthorization (dispatcher) {
return getAuthorizationHeader(dispatcher.username, dispatcher.passwd);
}
function endpointToURL (endpoint) {
if (endpoint.substr(0,6) === "ssl://") {
return "https://" + endpoint.substr(6);
}
var pos = endpoint.indexOf("://");
if (pos === -1) {
return "http://" + endpoint;
}
return "http" + endpoint.substr(pos);
}
PortFinder.prototype.next = function () {
while (true) { // will be left by return when port is found
if (this.pos < this.list.length) {
@ -135,7 +146,7 @@ PortFinder.prototype.next = function () {
available = testPort("tcp://0.0.0.0:"+this.port);
}
else {
var url = "http" + this.dispatcher.endpoint.substr(3) +
var url = endpointToURL(this.dispatcher.endpoint) +
"/_admin/clusterCheckPort?port="+this.port;
var hdrs = {};
if (this.dispatcher.username !== undefined &&
@ -183,17 +194,6 @@ function getAddrPort (endpoint) {
return endpoint;
}
function endpointToURL (endpoint) {
if (endpoint.substr(0,6) === "ssl://") {
return "https://" + endpoint.substr(6);
}
var pos = endpoint.indexOf("://");
if (pos === -1) {
return "http://" + endpoint;
}
return "http" + endpoint.substr(pos);
}
function getAddr (endpoint) {
var addrPort = getAddrPort(endpoint);
var pos = addrPort.indexOf(":");

View File

@ -341,7 +341,10 @@
// set up the collection _graphs
addTask("setupGraphs", "setup _graphs collection", function () {
return createSystemCollection("_graphs", { waitForSync : true });
return createSystemCollection("_graphs", {
waitForSync : true,
journalSize: 1024 * 1024
});
});
////////////////////////////////////////////////////////////////////////////////
@ -413,7 +416,9 @@
// create the _modules collection
addTask("createModules", "setup _modules collection", function () {
return createSystemCollection("_modules");
return createSystemCollection("_modules", {
journalSize: 1024 * 1024
});
});
////////////////////////////////////////////////////////////////////////////////
@ -423,7 +428,9 @@
// create the _routing collection
addTask("createRouting", "setup _routing collection", function () {
// needs to be big enough for assets
return createSystemCollection("_routing", { journalSize: 32 * 1024 * 1024 });
return createSystemCollection("_routing", {
journalSize: 32 * 1024 * 1024
});
});
////////////////////////////////////////////////////////////////////////////////
@ -434,7 +441,9 @@
addTask("createKickstarterConfiguration",
"setup _cluster_kickstarter_plans collection", function () {
//TODO add check if this is the main dispatcher
return createSystemCollection("_cluster_kickstarter_plans");
return createSystemCollection("_cluster_kickstarter_plans", {
journalSize: 4 * 1024 * 1024
});
});
////////////////////////////////////////////////////////////////////////////////
@ -557,7 +566,9 @@
// set up the collection _aqlfunctions
addTask("setupAqlFunctions", "setup _aqlfunctions collection", function () {
return createSystemCollection("_aqlfunctions");
return createSystemCollection("_aqlfunctions", {
journalSize: 4 * 1024 * 1024
});
});
////////////////////////////////////////////////////////////////////////////////
@ -663,7 +674,10 @@
// create the _statistics collection
addTask("createConfiguration", "setup _configuration collection", function () {
var name = "_configuration";
var result = createSystemCollection(name, { waitForSync: true });
var result = createSystemCollection(name, {
waitForSync: true,
journalSize: 1024 * 1024
});
return result;
});

View File

@ -350,7 +350,7 @@ bool Endpoint::setTimeout (TRI_socket_t s, double timeout) {
// shut up Valgrind
memset(&tv, 0, sizeof(tv));
tv.tv_sec = (long) timeout;
tv.tv_usec = ((suseconds_t) (timeout * 1000000.0)) % 1000000;
tv.tv_usec = (long) ((timeout - (double) tv.tv_sec) * 1000000.0);
// conversion to (const char*) ensures windows does not complain
if (TRI_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (const char*)(&tv), sizeof(tv)) != 0) {

View File

@ -174,7 +174,7 @@ bool ClientConnection::prepare (const double timeout, const bool isWrite) const
assert(TRI_isvalidsocket(_socket));
tv.tv_sec = (long) timeout;
tv.tv_usec = ((long) (timeout * 1000000.0)) % 1000000;
tv.tv_usec = (long) ((timeout - (double) tv.tv_sec) * 1000000.0);
FD_ZERO(&fdset);
FD_SET(TRI_get_fd_or_handle_of_socket(_socket), &fdset);
@ -205,6 +205,10 @@ bool ClientConnection::prepare (const double timeout, const bool isWrite) const
}
}
if (res < 0) {
TRI_set_errno(errno);
}
return false;
}
@ -229,6 +233,11 @@ bool ClientConnection::writeClientConnection (void* buffer, size_t length, size_
if (status < 0) {
TRI_set_errno(errno);
_isConnected = false;
return false;
}
else if (status == 0) {
_isConnected = false;
return false;
}

View File

@ -207,7 +207,7 @@ bool SslClientConnection::prepare (const double timeout, const bool isWrite) con
fd_set fdset;
tv.tv_sec = (long) timeout;
tv.tv_usec = ((long) (timeout * 1000000.0)) % 1000000;
tv.tv_usec = (long) ((timeout - (double) tv.tv_sec) * 1000000.0);
FD_ZERO(&fdset);
FD_SET(TRI_get_fd_or_handle_of_socket(_socket), &fdset);

View File

@ -48,7 +48,7 @@ using namespace triagens::basics;
static int FillShapeValueJson (TRI_shaper_t* shaper,
TRI_shape_value_t* dst,
v8::Handle<v8::Value> const& json,
v8::Handle<v8::Value> const json,
set<int>& seenHashes,
vector< v8::Handle<v8::Object> >& seenObjects,
bool create,
@ -102,7 +102,7 @@ static int FillShapeValueNull (TRI_shaper_t* shaper,
static int FillShapeValueBoolean (TRI_shaper_t* shaper,
TRI_shape_value_t* dst,
v8::Handle<v8::Boolean> const& json) {
v8::Handle<v8::Boolean> const json) {
TRI_shape_boolean_t* ptr;
dst->_type = TRI_SHAPE_BOOLEAN;
@ -126,7 +126,7 @@ static int FillShapeValueBoolean (TRI_shaper_t* shaper,
static int FillShapeValueBoolean (TRI_shaper_t* shaper,
TRI_shape_value_t* dst,
v8::Handle<v8::BooleanObject> const& json) {
v8::Handle<v8::BooleanObject> const json) {
TRI_shape_boolean_t* ptr;
dst->_type = TRI_SHAPE_BOOLEAN;
@ -150,7 +150,7 @@ static int FillShapeValueBoolean (TRI_shaper_t* shaper,
static int FillShapeValueNumber (TRI_shaper_t* shaper,
TRI_shape_value_t* dst,
v8::Handle<v8::Number> const& json) {
v8::Handle<v8::Number> const json) {
TRI_shape_number_t* ptr;
dst->_type = TRI_SHAPE_NUMBER;
@ -174,7 +174,7 @@ static int FillShapeValueNumber (TRI_shaper_t* shaper,
static int FillShapeValueNumber (TRI_shaper_t* shaper,
TRI_shape_value_t* dst,
v8::Handle<v8::NumberObject> const& json) {
v8::Handle<v8::NumberObject> const json) {
TRI_shape_number_t* ptr;
dst->_type = TRI_SHAPE_NUMBER;
@ -198,7 +198,7 @@ static int FillShapeValueNumber (TRI_shaper_t* shaper,
static int FillShapeValueString (TRI_shaper_t* shaper,
TRI_shape_value_t* dst,
v8::Handle<v8::String> const& json) {
v8::Handle<v8::String> const json) {
char* ptr;
TRI_Utf8ValueNFC str(TRI_UNKNOWN_MEM_ZONE, json);
@ -259,7 +259,7 @@ static int FillShapeValueString (TRI_shaper_t* shaper,
static int FillShapeValueList (TRI_shaper_t* shaper,
TRI_shape_value_t* dst,
v8::Handle<v8::Array> const& json,
v8::Handle<v8::Array> const json,
set<int>& seenHashes,
vector< v8::Handle<v8::Object> >& seenObjects,
bool create,
@ -577,7 +577,7 @@ static int FillShapeValueList (TRI_shaper_t* shaper,
static int FillShapeValueArray (TRI_shaper_t* shaper,
TRI_shape_value_t* dst,
v8::Handle<v8::Object> const& json,
v8::Handle<v8::Object> const json,
set<int>& seenHashes,
vector< v8::Handle<v8::Object> >& seenObjects,
bool create,
@ -827,7 +827,7 @@ static int FillShapeValueArray (TRI_shaper_t* shaper,
static int FillShapeValueJson (TRI_shaper_t* shaper,
TRI_shape_value_t* dst,
v8::Handle<v8::Value> const& json,
v8::Handle<v8::Value> const json,
set<int>& seenHashes,
vector< v8::Handle<v8::Object> >& seenObjects,
bool create,
@ -1452,7 +1452,7 @@ v8::Handle<v8::Value> TRI_JsonShapeData (TRI_shaper_t* shaper,
/// @brief converts a V8 object to a TRI_shaped_json_t
////////////////////////////////////////////////////////////////////////////////
TRI_shaped_json_t* TRI_ShapedJsonV8Object (v8::Handle<v8::Value> const& object,
TRI_shaped_json_t* TRI_ShapedJsonV8Object (v8::Handle<v8::Value> const object,
TRI_shaper_t* shaper,
bool create,
bool isLocked) {
@ -1489,7 +1489,7 @@ TRI_shaped_json_t* TRI_ShapedJsonV8Object (v8::Handle<v8::Value> const& object,
/// @brief converts a V8 object to a TRI_shaped_json_t in place
////////////////////////////////////////////////////////////////////////////////
int TRI_FillShapedJsonV8Object (v8::Handle<v8::Value> const& object,
int TRI_FillShapedJsonV8Object (v8::Handle<v8::Value> const object,
TRI_shaped_json_t* result,
TRI_shaper_t* shaper,
bool create,
@ -1518,7 +1518,7 @@ int TRI_FillShapedJsonV8Object (v8::Handle<v8::Value> const& object,
/// @brief convert a V8 value to a json_t value
////////////////////////////////////////////////////////////////////////////////
static TRI_json_t* ObjectToJson (v8::Handle<v8::Value> const& parameter,
static TRI_json_t* ObjectToJson (v8::Handle<v8::Value> const parameter,
set<int>& seenHashes,
vector<v8::Handle<v8::Object> >& seenObjects) {
if (parameter->IsBoolean()) {
@ -1629,7 +1629,7 @@ static TRI_json_t* ObjectToJson (v8::Handle<v8::Value> const& parameter,
/// @brief convert a V8 value to a json_t value
////////////////////////////////////////////////////////////////////////////////
TRI_json_t* TRI_ObjectToJson (v8::Handle<v8::Value> const& parameter) {
TRI_json_t* TRI_ObjectToJson (v8::Handle<v8::Value> const parameter) {
set<int> seenHashes;
vector< v8::Handle<v8::Object> > seenObjects;
@ -1640,7 +1640,7 @@ TRI_json_t* TRI_ObjectToJson (v8::Handle<v8::Value> const& parameter) {
/// @brief converts an V8 object to a string
////////////////////////////////////////////////////////////////////////////////
string TRI_ObjectToString (v8::Handle<v8::Value> const& value) {
string TRI_ObjectToString (v8::Handle<v8::Value> const value) {
TRI_Utf8ValueNFC utf8Value(TRI_UNKNOWN_MEM_ZONE, value);
if (*utf8Value == 0) {
@ -1655,7 +1655,7 @@ string TRI_ObjectToString (v8::Handle<v8::Value> const& value) {
/// @brief converts an V8 object to a character
////////////////////////////////////////////////////////////////////////////////
char TRI_ObjectToCharacter (v8::Handle<v8::Value> const& value, bool& error) {
char TRI_ObjectToCharacter (v8::Handle<v8::Value> const value, bool& error) {
error = false;
if (! value->IsString() && ! value->IsStringObject()) {
@ -1677,7 +1677,7 @@ char TRI_ObjectToCharacter (v8::Handle<v8::Value> const& value, bool& error) {
/// @brief converts an V8 object to an int64_t
////////////////////////////////////////////////////////////////////////////////
int64_t TRI_ObjectToInt64 (v8::Handle<v8::Value> const& value) {
int64_t TRI_ObjectToInt64 (v8::Handle<v8::Value> const value) {
if (value->IsNumber()) {
return (int64_t) value->ToNumber()->Value();
}
@ -1694,7 +1694,7 @@ int64_t TRI_ObjectToInt64 (v8::Handle<v8::Value> const& value) {
/// @brief converts an V8 object to a uint64_t
////////////////////////////////////////////////////////////////////////////////
uint64_t TRI_ObjectToUInt64 (v8::Handle<v8::Value> const& value,
uint64_t TRI_ObjectToUInt64 (v8::Handle<v8::Value> const value,
const bool allowStringConversion) {
if (value->IsNumber()) {
return (uint64_t) value->ToNumber()->Value();
@ -1717,7 +1717,7 @@ uint64_t TRI_ObjectToUInt64 (v8::Handle<v8::Value> const& value,
/// @brief converts an V8 object to a double
////////////////////////////////////////////////////////////////////////////////
double TRI_ObjectToDouble (v8::Handle<v8::Value> const& value) {
double TRI_ObjectToDouble (v8::Handle<v8::Value> const value) {
if (value->IsNumber()) {
return value->ToNumber()->Value();
}
@ -1734,7 +1734,7 @@ double TRI_ObjectToDouble (v8::Handle<v8::Value> const& value) {
/// @brief converts an V8 object to a double with error handling
////////////////////////////////////////////////////////////////////////////////
double TRI_ObjectToDouble (v8::Handle<v8::Value> const& value, bool& error) {
double TRI_ObjectToDouble (v8::Handle<v8::Value> const value, bool& error) {
error = false;
if (value->IsNumber()) {
@ -1755,7 +1755,7 @@ double TRI_ObjectToDouble (v8::Handle<v8::Value> const& value, bool& error) {
/// @brief converts an V8 object to a boolean
////////////////////////////////////////////////////////////////////////////////
bool TRI_ObjectToBoolean (v8::Handle<v8::Value> const& value) {
bool TRI_ObjectToBoolean (v8::Handle<v8::Value> const value) {
if (value->IsBoolean()) {
return value->ToBoolean()->Value();
}

View File

@ -66,7 +66,7 @@ v8::Handle<v8::Value> TRI_JsonShapeData (TRI_shaper_t*,
/// @brief converts an V8 object to a TRI_shaped_json_t
////////////////////////////////////////////////////////////////////////////////
TRI_shaped_json_t* TRI_ShapedJsonV8Object (v8::Handle<v8::Value> const&,
TRI_shaped_json_t* TRI_ShapedJsonV8Object (v8::Handle<v8::Value> const,
TRI_shaper_t*,
bool,
bool);
@ -75,7 +75,7 @@ TRI_shaped_json_t* TRI_ShapedJsonV8Object (v8::Handle<v8::Value> const&,
/// @brief converts a V8 object to a TRI_shaped_json_t in place
////////////////////////////////////////////////////////////////////////////////
int TRI_FillShapedJsonV8Object (v8::Handle<v8::Value> const&,
int TRI_FillShapedJsonV8Object (v8::Handle<v8::Value> const,
TRI_shaped_json_t*,
TRI_shaper_t*,
bool,
@ -85,52 +85,52 @@ int TRI_FillShapedJsonV8Object (v8::Handle<v8::Value> const&,
/// @brief convert a V8 value to a json_t value
////////////////////////////////////////////////////////////////////////////////
TRI_json_t* TRI_ObjectToJson (v8::Handle<v8::Value> const&);
TRI_json_t* TRI_ObjectToJson (v8::Handle<v8::Value> const);
////////////////////////////////////////////////////////////////////////////////
/// @brief converts an V8 object to a string
////////////////////////////////////////////////////////////////////////////////
std::string TRI_ObjectToString (v8::Handle<v8::Value> const&);
std::string TRI_ObjectToString (v8::Handle<v8::Value> const);
////////////////////////////////////////////////////////////////////////////////
/// @brief converts an V8 object to a character
////////////////////////////////////////////////////////////////////////////////
char TRI_ObjectToCharacter (v8::Handle<v8::Value> const&,
char TRI_ObjectToCharacter (v8::Handle<v8::Value> const,
bool& error);
////////////////////////////////////////////////////////////////////////////////
/// @brief converts an V8 object to an int64_t
////////////////////////////////////////////////////////////////////////////////
int64_t TRI_ObjectToInt64 (v8::Handle<v8::Value> const&);
int64_t TRI_ObjectToInt64 (v8::Handle<v8::Value> const);
////////////////////////////////////////////////////////////////////////////////
/// @brief converts an V8 object to a uint64_t
////////////////////////////////////////////////////////////////////////////////
uint64_t TRI_ObjectToUInt64 (v8::Handle<v8::Value> const&,
uint64_t TRI_ObjectToUInt64 (v8::Handle<v8::Value> const,
const bool);
////////////////////////////////////////////////////////////////////////////////
/// @brief converts a V8 object to a double
////////////////////////////////////////////////////////////////////////////////
double TRI_ObjectToDouble (v8::Handle<v8::Value> const&);
double TRI_ObjectToDouble (v8::Handle<v8::Value> const);
////////////////////////////////////////////////////////////////////////////////
/// @brief converts a V8 object to a double with error handling
////////////////////////////////////////////////////////////////////////////////
double TRI_ObjectToDouble (v8::Handle<v8::Value> const&,
double TRI_ObjectToDouble (v8::Handle<v8::Value> const,
bool& error);
////////////////////////////////////////////////////////////////////////////////
/// @brief converts a V8 object to a boolean
////////////////////////////////////////////////////////////////////////////////
bool TRI_ObjectToBoolean (v8::Handle<v8::Value> const&);
bool TRI_ObjectToBoolean (v8::Handle<v8::Value> const);
// -----------------------------------------------------------------------------
// --SECTION-- GENERAL

View File

@ -3057,8 +3057,8 @@ bool TRI_ParseJavaScriptFile (char const* filename) {
////////////////////////////////////////////////////////////////////////////////
v8::Handle<v8::Value> TRI_ExecuteJavaScriptString (v8::Handle<v8::Context> context,
v8::Handle<v8::String> const& source,
v8::Handle<v8::Value> const& name,
v8::Handle<v8::String> const source,
v8::Handle<v8::Value> const name,
bool printResult) {
v8::HandleScope scope;

View File

@ -153,8 +153,8 @@ bool TRI_ParseJavaScriptFile (char const*);
////////////////////////////////////////////////////////////////////////////////
v8::Handle<v8::Value> TRI_ExecuteJavaScriptString (v8::Handle<v8::Context> context,
v8::Handle<v8::String> const& source,
v8::Handle<v8::Value> const& name,
v8::Handle<v8::String> const source,
v8::Handle<v8::Value> const name,
bool printResult);
////////////////////////////////////////////////////////////////////////////////