mirror of https://gitee.com/bigwinds/arangodb
Fixed minor inconsistency in AQL NEIGHBORS and adapted tests to the new version. It will now Return the list of vertices. not the pair<edge, vertex> any more
This commit is contained in:
parent
e1813327b5
commit
0b8e9eb59c
|
@ -381,86 +381,51 @@ unique_ptr<ArangoDBPathFinder::Path> TRI_RunShortestPathSearch (
|
|||
}
|
||||
|
||||
vector<VertexId> TRI_RunNeighborsSearch (
|
||||
v8::Isolate* isolate,
|
||||
TRI_vocbase_t* vocbase,
|
||||
std::string const& vertexCollectionName,
|
||||
std::string const& edgeCollectionName,
|
||||
std::string const& startVertex,
|
||||
CollectionNameResolver const* resolver,
|
||||
TRI_document_collection_t* ecol,
|
||||
vector<EdgeCollectionInfo*>& collectionInfos,
|
||||
NeighborsOptions& opts
|
||||
) {
|
||||
// Transform string ids to VertexIds
|
||||
// Needs refactoring!
|
||||
size_t split;
|
||||
char const* str = startVertex.c_str();
|
||||
vector<VertexId> result;
|
||||
|
||||
if (!TRI_ValidateDocumentIdKeyGenerator(str, &split)) {
|
||||
// TODO Error Handling
|
||||
return result;
|
||||
}
|
||||
string collectionName = startVertex.substr(0, split);
|
||||
|
||||
auto coli = resolver->getCollectionStruct(collectionName);
|
||||
if (coli == nullptr) {
|
||||
// collection not found
|
||||
throw TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND;
|
||||
}
|
||||
if (opts.distinct) {
|
||||
unordered_set<VertexId> distinct;
|
||||
if (opts.direction == "any") {
|
||||
auto edges = TRI_LookupEdgesDocumentCollection(ecol,
|
||||
TRI_EDGE_IN, coli->_cid, const_cast<char*>(str + split + 1));
|
||||
for (size_t j = 0; j < edges.size(); ++j) {
|
||||
distinct.insert(extractFromId(edges[j]));
|
||||
if (opts.direction == TRI_EDGE_IN || opts.direction == TRI_EDGE_ANY) {
|
||||
TRI_edge_direction_e dir = TRI_EDGE_IN;
|
||||
for (auto col : collectionInfos) {
|
||||
auto edges = col->getEdges(dir, opts.start);
|
||||
for (size_t j = 0; j < edges.size(); ++j) {
|
||||
distinct.insert(extractFromId(edges[j]));
|
||||
}
|
||||
}
|
||||
edges = TRI_LookupEdgesDocumentCollection(ecol,
|
||||
TRI_EDGE_OUT, coli->_cid, const_cast<char*>(str + split + 1));
|
||||
for (size_t j = 0; j < edges.size(); ++j) {
|
||||
distinct.insert(extractToId(edges[j]));
|
||||
}
|
||||
} else if (opts.direction == "inbound") {
|
||||
auto edges = TRI_LookupEdgesDocumentCollection(ecol,
|
||||
TRI_EDGE_IN, coli->_cid, const_cast<char*>(str + split + 1));
|
||||
for (size_t j = 0; j < edges.size(); ++j) {
|
||||
distinct.insert(extractFromId(edges[j]));
|
||||
}
|
||||
} else {
|
||||
auto edges = TRI_LookupEdgesDocumentCollection(ecol,
|
||||
TRI_EDGE_OUT, coli->_cid, const_cast<char*>(str + split + 1));
|
||||
for (size_t j = 0; j < edges.size(); ++j) {
|
||||
distinct.insert(extractToId(edges[j]));
|
||||
}
|
||||
if (opts.direction == TRI_EDGE_OUT || opts.direction == TRI_EDGE_ANY) {
|
||||
TRI_edge_direction_e dir = TRI_EDGE_OUT;
|
||||
for (auto col : collectionInfos) {
|
||||
auto edges = col->getEdges(dir, opts.start);
|
||||
for (size_t j = 0; j < edges.size(); ++j) {
|
||||
distinct.insert(extractToId(edges[j]));
|
||||
}
|
||||
}
|
||||
}
|
||||
copy(distinct.begin(), distinct.end(), back_inserter(result));
|
||||
} else {
|
||||
if (opts.direction == "any") {
|
||||
auto edges = TRI_LookupEdgesDocumentCollection(ecol,
|
||||
TRI_EDGE_IN, coli->_cid, const_cast<char*>(str + split + 1));
|
||||
for (size_t j = 0; j < edges.size(); ++j) {
|
||||
result.push_back(extractFromId(edges[j]));
|
||||
if (opts.direction == TRI_EDGE_IN || opts.direction == TRI_EDGE_ANY) {
|
||||
TRI_edge_direction_e dir = TRI_EDGE_IN;
|
||||
for (auto col : collectionInfos) {
|
||||
auto edges = col->getEdges(dir, opts.start);
|
||||
for (size_t j = 0; j < edges.size(); ++j) {
|
||||
result.push_back(extractFromId(edges[j]));
|
||||
}
|
||||
}
|
||||
edges = TRI_LookupEdgesDocumentCollection(ecol,
|
||||
TRI_EDGE_OUT, coli->_cid, const_cast<char*>(str + split + 1));
|
||||
for (size_t j = 0; j < edges.size(); ++j) {
|
||||
result.push_back(extractToId(edges[j]));
|
||||
}
|
||||
} else if (opts.direction == "inbound") {
|
||||
auto edges = TRI_LookupEdgesDocumentCollection(ecol,
|
||||
TRI_EDGE_IN, coli->_cid, const_cast<char*>(str + split + 1));
|
||||
for (size_t j = 0; j < edges.size(); ++j) {
|
||||
result.push_back(extractFromId(edges[j]));
|
||||
}
|
||||
} else {
|
||||
auto edges = TRI_LookupEdgesDocumentCollection(ecol,
|
||||
TRI_EDGE_OUT, coli->_cid, const_cast<char*>(str + split + 1));
|
||||
for (size_t j = 0; j < edges.size(); ++j) {
|
||||
result.push_back(extractToId(edges[j]));
|
||||
}
|
||||
if (opts.direction == TRI_EDGE_OUT || opts.direction == TRI_EDGE_ANY) {
|
||||
TRI_edge_direction_e dir = TRI_EDGE_OUT;
|
||||
for (auto col : collectionInfos) {
|
||||
auto edges = col->getEdges(dir, opts.start);
|
||||
for (size_t j = 0; j < edges.size(); ++j) {
|
||||
result.push_back(extractToId(edges[j]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
};
|
||||
|
|
|
@ -44,10 +44,10 @@ struct VertexId {
|
|||
TRI_voc_cid_t cid;
|
||||
char const* key;
|
||||
|
||||
VertexId() : cid(0), key(nullptr) {
|
||||
VertexId () : cid(0), key(nullptr) {
|
||||
}
|
||||
|
||||
VertexId( TRI_voc_cid_t cid, char const* key)
|
||||
VertexId (TRI_voc_cid_t cid, char const* key)
|
||||
: cid(cid), key(key) {
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@ struct VertexFilterInfo {
|
|||
TRI_transaction_collection_t* col;
|
||||
triagens::arango::ExampleMatcher* matcher;
|
||||
|
||||
VertexFilterInfo(
|
||||
VertexFilterInfo (
|
||||
triagens::arango::ExplicitTransaction* trx,
|
||||
TRI_transaction_collection_t* col,
|
||||
triagens::arango::ExampleMatcher* matcher
|
||||
|
@ -126,7 +126,7 @@ namespace triagens {
|
|||
useEdgeFilter(false) {
|
||||
}
|
||||
|
||||
void addEdgeFilter(
|
||||
void addEdgeFilter (
|
||||
v8::Isolate* isolate,
|
||||
v8::Handle<v8::Object> const& example,
|
||||
TRI_shaper_t* shaper,
|
||||
|
@ -134,7 +134,7 @@ namespace triagens {
|
|||
std::string& errorMessage
|
||||
);
|
||||
|
||||
void addVertexFilter(
|
||||
void addVertexFilter (
|
||||
v8::Isolate* isolate,
|
||||
v8::Handle<v8::Object> const& example,
|
||||
triagens::arango::ExplicitTransaction* trx,
|
||||
|
@ -144,20 +144,21 @@ namespace triagens {
|
|||
std::string& errorMessage
|
||||
);
|
||||
|
||||
void addFinalVertex(VertexId& v);
|
||||
void addFinalVertex (VertexId& v);
|
||||
|
||||
bool matchesEdge(EdgeId& e, TRI_doc_mptr_copy_t* edge) const;
|
||||
|
||||
bool matchesVertex(VertexId& v) const;
|
||||
bool matchesEdge (EdgeId& e, TRI_doc_mptr_copy_t* edge) const;
|
||||
|
||||
bool matchesVertex (VertexId& v) const;
|
||||
};
|
||||
struct NeighborsOptions {
|
||||
std::string direction;
|
||||
bool distinct;
|
||||
|
||||
NeighborsOptions() :
|
||||
direction("outbound"),
|
||||
distinct(false) {
|
||||
struct NeighborsOptions {
|
||||
TRI_edge_direction_e direction;
|
||||
bool distinct;
|
||||
VertexId start;
|
||||
|
||||
NeighborsOptions () :
|
||||
direction(TRI_EDGE_OUT),
|
||||
distinct(true) {
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -292,13 +293,7 @@ std::unique_ptr<ArangoDBPathFinder::Path> TRI_RunShortestPathSearch (
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::vector<VertexId> TRI_RunNeighborsSearch (
|
||||
v8::Isolate* isolate,
|
||||
TRI_vocbase_t* vocbase,
|
||||
std::string const& vertexCollectionName,
|
||||
std::string const& edgeCollectionName,
|
||||
std::string const& startVertex,
|
||||
triagens::arango::CollectionNameResolver const* resolver,
|
||||
TRI_document_collection_t* ecol,
|
||||
std::vector<EdgeCollectionInfo*>& collectionInfos,
|
||||
triagens::basics::traverser::NeighborsOptions& opts
|
||||
);
|
||||
|
||||
|
|
|
@ -1669,7 +1669,7 @@ static ExplicitTransaction* beginTransaction(
|
|||
// Abort the collection and free the pointers
|
||||
trx->abort();
|
||||
delete trx;
|
||||
throw e;
|
||||
throw;
|
||||
}
|
||||
return trx;
|
||||
}
|
||||
|
@ -1854,7 +1854,7 @@ static void JS_QueryShortestPath (const v8::FunctionCallbackInfo<v8::Value>& arg
|
|||
unordered_set<string> vertexCollectionNames;
|
||||
v8ArrayToStrings(args[0], vertexCollectionNames);
|
||||
|
||||
// get the vertex collections
|
||||
// get the edge collections
|
||||
if (! args[1]->IsArray()) {
|
||||
TRI_V8_THROW_TYPE_ERROR("expecting array for <edgecollections[]>");
|
||||
}
|
||||
|
@ -2033,8 +2033,15 @@ static void JS_QueryShortestPath (const v8::FunctionCallbackInfo<v8::Value>& arg
|
|||
}
|
||||
}
|
||||
|
||||
opts.start = idStringToVertexId(resolver, startVertex);
|
||||
opts.end = idStringToVertexId(resolver, targetVertex);
|
||||
try {
|
||||
opts.start = idStringToVertexId(resolver, startVertex);
|
||||
opts.end = idStringToVertexId(resolver, targetVertex);
|
||||
} catch (int e) {
|
||||
// Id string might have illegal collection name
|
||||
trx->finish(e);
|
||||
delete trx;
|
||||
TRI_V8_THROW_EXCEPTION(e);
|
||||
}
|
||||
|
||||
try {
|
||||
path = TRI_RunShortestPathSearch(
|
||||
|
@ -2074,54 +2081,27 @@ static v8::Handle<v8::Value> vertexIdsToV8(v8::Isolate* isolate,
|
|||
CollectionNameResolver const* resolver,
|
||||
vector<VertexId>& ids,
|
||||
unordered_map<TRI_voc_cid_t, CollectionBarrierInfo>& barriers,
|
||||
bool includeData = false,
|
||||
bool includeDuplicates = true) {
|
||||
bool includeData = false) {
|
||||
v8::EscapableHandleScope scope(isolate);
|
||||
v8::Handle<v8::Object> result = v8::Object::New(isolate);
|
||||
uint32_t const vn = static_cast<uint32_t>(ids.size());
|
||||
v8::Handle<v8::Array> vertices = v8::Array::New(isolate, static_cast<int>(vn));
|
||||
|
||||
if (includeDuplicates) {
|
||||
uint32_t const vn = static_cast<uint32_t>(ids.size());
|
||||
v8::Handle<v8::Array> vertices = v8::Array::New(isolate, static_cast<int>(vn));
|
||||
|
||||
if (includeData) {
|
||||
for (uint32_t j = 0; j < vn; ++j) {
|
||||
vertices->Set(j, vertexIdToData(isolate, resolver, trx, barriers, ids[j]));
|
||||
}
|
||||
} else {
|
||||
for (uint32_t j = 0; j < vn; ++j) {
|
||||
vertices->Set(j, vertexIdToString(isolate, resolver, ids[j]));
|
||||
}
|
||||
if (includeData) {
|
||||
for (uint32_t j = 0; j < vn; ++j) {
|
||||
vertices->Set(j, vertexIdToData(isolate, resolver, trx, barriers, ids[j]));
|
||||
}
|
||||
result->Set(TRI_V8_STRING("vertices"), vertices);
|
||||
return scope.Escape<v8::Value>(result);
|
||||
} else {
|
||||
// set<VertexId> uniqueIds(ids.begin(), ids.end());
|
||||
// TODO
|
||||
auto uniqueIds = ids;
|
||||
uint32_t const vn = static_cast<uint32_t>(uniqueIds.size());
|
||||
v8::Handle<v8::Array> vertices = v8::Array::New(isolate, static_cast<int>(vn));
|
||||
auto iterator = uniqueIds.begin();
|
||||
if (includeData) {
|
||||
for (uint32_t j = 0; j < vn; ++j) {
|
||||
vertices->Set(j, vertexIdToData(isolate, resolver, trx, barriers, *iterator));
|
||||
++iterator;
|
||||
}
|
||||
} else {
|
||||
for (uint32_t j = 0; j < vn; ++j) {
|
||||
vertices->Set(j, vertexIdToString(isolate, resolver, *iterator));
|
||||
++iterator;
|
||||
}
|
||||
for (uint32_t j = 0; j < vn; ++j) {
|
||||
vertices->Set(j, vertexIdToString(isolate, resolver, ids[j]));
|
||||
}
|
||||
result->Set(TRI_V8_STRING("vertices"), vertices);
|
||||
return scope.Escape<v8::Value>(result);
|
||||
|
||||
}
|
||||
return scope.Escape<v8::Value>(vertices);
|
||||
};
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Executes a shortest Path Traversal
|
||||
/// @brief Executes a Neighbors computation
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void JS_QueryNeighbors (const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
|
@ -2129,74 +2109,88 @@ static void JS_QueryNeighbors (const v8::FunctionCallbackInfo<v8::Value>& args)
|
|||
v8::HandleScope scope(isolate);
|
||||
|
||||
if (args.Length() < 3 || args.Length() > 4) {
|
||||
TRI_V8_THROW_EXCEPTION_USAGE("CPP_NEIGHBORS(<vertexcollection>, <edgecollection>, <start>, <options>)");
|
||||
TRI_V8_THROW_EXCEPTION_USAGE("CPP_NEIGHBORS(<vertexcollections[]>, <edgecollections[]>, <start>, <options>)");
|
||||
}
|
||||
|
||||
TRI_vocbase_t* vocbase;
|
||||
|
||||
vocbase = GetContextVocBase(isolate);
|
||||
|
||||
// get the vertex collection
|
||||
if (! args[0]->IsString()) {
|
||||
TRI_V8_THROW_TYPE_ERROR("expecting string for <vertexcollection>");
|
||||
// get the vertex collections
|
||||
if (! args[0]->IsArray()) {
|
||||
TRI_V8_THROW_TYPE_ERROR("expecting array for <vertexcollections[]>");
|
||||
}
|
||||
string vertexCollectionName = TRI_ObjectToString(args[0]);
|
||||
unordered_set<string> vertexCollectionNames;
|
||||
v8ArrayToStrings(args[0], vertexCollectionNames);
|
||||
|
||||
// get the edge collection
|
||||
if (! args[1]->IsString()) {
|
||||
TRI_V8_THROW_TYPE_ERROR("expecting string for <edgecollection>");
|
||||
// get the edge collections
|
||||
if (! args[1]->IsArray()) {
|
||||
TRI_V8_THROW_TYPE_ERROR("expecting array for <edgecollections[]>");
|
||||
}
|
||||
string const edgeCollectionName = TRI_ObjectToString(args[1]);
|
||||
unordered_set<string> edgeCollectionNames;
|
||||
v8ArrayToStrings(args[1], edgeCollectionNames);
|
||||
|
||||
vocbase = GetContextVocBase(isolate);
|
||||
TRI_vocbase_t* vocbase = GetContextVocBase(isolate);
|
||||
|
||||
if (vocbase == nullptr) {
|
||||
TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
if (! args[2]->IsString()) {
|
||||
TRI_V8_THROW_TYPE_ERROR("expecting string for <startVertex>");
|
||||
TRI_V8_THROW_TYPE_ERROR("expecting id for <startVertex>");
|
||||
}
|
||||
string const startVertex = TRI_ObjectToString(args[2]);
|
||||
|
||||
|
||||
// TODO Option parsing
|
||||
traverser::NeighborsOptions opts;
|
||||
bool includeData = false;
|
||||
v8::Handle<v8::Object> vertexExample;
|
||||
|
||||
if (args.Length() == 4) {
|
||||
if (! args[3]->IsObject()) {
|
||||
TRI_V8_THROW_TYPE_ERROR("expecting json for <options>");
|
||||
}
|
||||
v8::Handle<v8::Object> options = args[3]->ToObject();
|
||||
v8::Local<v8::String> keyDirection = TRI_V8_ASCII_STRING("direction");
|
||||
v8::Local<v8::String> keyDistinct= TRI_V8_ASCII_STRING("distinct");
|
||||
|
||||
// Parse direction
|
||||
v8::Local<v8::String> keyDirection = TRI_V8_ASCII_STRING("direction");
|
||||
if (options->Has(keyDirection) ) {
|
||||
opts.direction = TRI_ObjectToString(options->Get(keyDirection));
|
||||
if ( opts.direction != "outbound"
|
||||
&& opts.direction != "inbound"
|
||||
&& opts.direction != "any"
|
||||
) {
|
||||
string dir = TRI_ObjectToString(options->Get(keyDirection));
|
||||
if (dir == "outbound") {
|
||||
opts.direction = TRI_EDGE_OUT;
|
||||
} else if (dir == "inbound") {
|
||||
opts.direction = TRI_EDGE_IN;
|
||||
} else if (dir == "any") {
|
||||
opts.direction = TRI_EDGE_ANY;
|
||||
} else {
|
||||
TRI_V8_THROW_TYPE_ERROR("expecting direction to be 'outbound', 'inbound' or 'any'");
|
||||
}
|
||||
}
|
||||
|
||||
// Parse use distinct
|
||||
v8::Local<v8::String> keyDistinct= TRI_V8_ASCII_STRING("distinct");
|
||||
if (options->Has(keyDistinct) ) {
|
||||
opts.distinct = TRI_ObjectToBoolean(options->Get(keyDistinct));
|
||||
}
|
||||
|
||||
// Parse includeData
|
||||
v8::Local<v8::String> keyIncludeData = TRI_V8_ASCII_STRING("includeData");
|
||||
if (options->Has(keyIncludeData)) {
|
||||
includeData = TRI_ObjectToBoolean(options->Get(keyIncludeData));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
vector<TRI_voc_cid_t> readCollections;
|
||||
vector<TRI_voc_cid_t> writeCollections;
|
||||
|
||||
V8ResolverGuard resolverGuard(vocbase);
|
||||
CollectionNameResolver const* resolver = resolverGuard.getResolver();
|
||||
|
||||
readCollections.push_back(resolver->getCollectionId(vertexCollectionName));
|
||||
readCollections.push_back(resolver->getCollectionId(edgeCollectionName));
|
||||
|
||||
|
||||
ExplicitTransaction* trx = nullptr;
|
||||
int res = 0;
|
||||
CollectionNameResolver const* resolver = resolverGuard.getResolver();
|
||||
|
||||
for (auto it : edgeCollectionNames) {
|
||||
readCollections.push_back(resolver->getCollectionId(it));
|
||||
}
|
||||
for (auto it : vertexCollectionNames) {
|
||||
readCollections.push_back(resolver->getCollectionId(it));
|
||||
}
|
||||
|
||||
unordered_map<TRI_voc_cid_t, CollectionBarrierInfo> barriers;
|
||||
// Start the transaction
|
||||
|
@ -2204,21 +2198,43 @@ static void JS_QueryNeighbors (const v8::FunctionCallbackInfo<v8::Value>& args)
|
|||
trx = beginTransaction(vocbase, readCollections, writeCollections,
|
||||
resolver, barriers);
|
||||
} catch (int e) {
|
||||
// Nothing to clean up. Throw the error to V8
|
||||
TRI_V8_THROW_EXCEPTION(e);
|
||||
}
|
||||
|
||||
TRI_voc_cid_t edgeCid = resolver->getCollectionId(edgeCollectionName);
|
||||
TRI_ASSERT(barriers.find(edgeCid) != barriers.end());
|
||||
vector<EdgeCollectionInfo*> edgeCollectionInfos;
|
||||
for(auto it : edgeCollectionNames) {
|
||||
auto cid = resolver->getCollectionId(it);
|
||||
auto colObj = barriers.find(cid)->second.col->_collection->_collection;
|
||||
edgeCollectionInfos.push_back(new EdgeCollectionInfo(
|
||||
cid,
|
||||
colObj,
|
||||
HopWeightCalculator()
|
||||
));
|
||||
}
|
||||
|
||||
vector<VertexCollectionInfo*> vertexCollectionInfos;
|
||||
for(auto it : vertexCollectionNames) {
|
||||
auto cid = resolver->getCollectionId(it);
|
||||
auto colObj = barriers.find(cid)->second.col;
|
||||
vertexCollectionInfos.push_back(new VertexCollectionInfo(
|
||||
cid,
|
||||
colObj
|
||||
));
|
||||
}
|
||||
|
||||
try {
|
||||
opts.start = idStringToVertexId(resolver, startVertex);
|
||||
} catch (int e) {
|
||||
// Id string might have illegal collection name
|
||||
trx->finish(e);
|
||||
delete trx;
|
||||
TRI_V8_THROW_EXCEPTION(e);
|
||||
}
|
||||
vector<VertexId> neighbors;
|
||||
try {
|
||||
neighbors = TRI_RunNeighborsSearch(
|
||||
isolate,
|
||||
vocbase,
|
||||
vertexCollectionName,
|
||||
edgeCollectionName,
|
||||
startVertex,
|
||||
resolver,
|
||||
barriers.find(edgeCid)->second.col->_collection->_collection,
|
||||
edgeCollectionInfos,
|
||||
opts
|
||||
);
|
||||
} catch (int e) {
|
||||
|
@ -2227,7 +2243,7 @@ static void JS_QueryNeighbors (const v8::FunctionCallbackInfo<v8::Value>& args)
|
|||
TRI_V8_THROW_EXCEPTION(e);
|
||||
}
|
||||
|
||||
auto result = vertexIdsToV8(isolate, trx, resolver, neighbors, barriers, true);
|
||||
auto result = vertexIdsToV8(isolate, trx, resolver, neighbors, barriers, includeData);
|
||||
|
||||
trx->finish(res);
|
||||
delete trx;
|
||||
|
|
|
@ -6490,15 +6490,17 @@ function AQL_NEIGHBORS (vertexCollection,
|
|||
edgeCollection,
|
||||
vertex,
|
||||
direction,
|
||||
examples) {
|
||||
examples,
|
||||
options) {
|
||||
'use strict';
|
||||
|
||||
vertex = TO_ID(vertex, vertexCollection);
|
||||
/*
|
||||
options = options || {};
|
||||
options.direction = direction;
|
||||
options.examples = examples;
|
||||
if (examples === undefined) {
|
||||
return [CPP_NEIGHBORS(vertexCollection, edgeCollection, vertex, {direction: direction})];
|
||||
return CPP_NEIGHBORS([vertexCollection], [edgeCollection], vertex, options);
|
||||
}
|
||||
*/
|
||||
|
||||
var edges = AQL_EDGES(edgeCollection, vertex, direction);
|
||||
return FILTERED_EDGES(edges, vertex, direction, examples);
|
||||
|
|
|
@ -150,26 +150,38 @@ function ahuacatlQueryEdgesTestSuite () {
|
|||
|
||||
testNeighborsAny : function () {
|
||||
var actual;
|
||||
var v1 = "UnitTestsAhuacatlVertex/v1";
|
||||
var v2 = "UnitTestsAhuacatlVertex/v2";
|
||||
var v3 = "UnitTestsAhuacatlVertex/v3";
|
||||
var v4 = "UnitTestsAhuacatlVertex/v4";
|
||||
var v5 = "UnitTestsAhuacatlVertex/v5";
|
||||
var v6 = "UnitTestsAhuacatlVertex/v6";
|
||||
var v7 = "UnitTestsAhuacatlVertex/v7";
|
||||
var v8 = "UnitTestsAhuacatlVertex/v8";
|
||||
var theFox = "UnitTestsAhuacatlVertex/thefox";
|
||||
var queryStart = "FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, '";
|
||||
var queryEnd = "', 'any') SORT n RETURN n";
|
||||
|
||||
actual = getQueryResults("FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, 'UnitTestsAhuacatlVertex/v1', 'any') SORT n.vertex._key RETURN [ n.vertex._key, n.edge.what ]");
|
||||
assertEqual(actual, [ [ "v2", "v1->v2" ], [ "v3", "v1->v3" ] ]);
|
||||
actual = getQueryResults(queryStart + v1 + queryEnd);
|
||||
assertEqual(actual, [ v2, v3 ]);
|
||||
|
||||
actual = getQueryResults("FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, 'UnitTestsAhuacatlVertex/v2', 'any') SORT n.vertex._key RETURN [ n.vertex._key, n.edge.what ]");
|
||||
assertEqual(actual, [ [ "v1", "v1->v2" ], [ "v3", "v2->v3" ], [ "v4", "v4->v2" ] ]);
|
||||
actual = getQueryResults(queryStart + v2 + queryEnd);
|
||||
assertEqual(actual, [ v1, v3, v4 ]);
|
||||
|
||||
// v6 and v7 are neighbors twice
|
||||
actual = getQueryResults(queryStart + v3 + queryEnd);
|
||||
assertEqual(actual, [ v1, v2, v4, v6, v7 ]);
|
||||
|
||||
actual = getQueryResults("FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, 'UnitTestsAhuacatlVertex/v3', 'any') SORT n.vertex._key, n.edge.what RETURN [ n.vertex._key, n.edge.what ]");
|
||||
assertEqual(actual, [ [ "v1", "v1->v3"], [ "v2", "v2->v3" ], [ "v4", "v3->v4" ], [ "v6", "v3->v6" ], [ "v6", "v6->v3"], [ "v7", "v3->v7" ], [ "v7", "v7->v3" ] ]);
|
||||
|
||||
actual = getQueryResults("FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, 'UnitTestsAhuacatlVertex/v8', 'any') SORT n.vertex._key RETURN n.vertex._key");
|
||||
actual = getQueryResults(queryStart + v8 + queryEnd);
|
||||
assertEqual(actual, [ ]);
|
||||
|
||||
actual = getQueryResults("FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, 'UnitTestsAhuacatlVertex/v5', 'any') SORT n.vertex._key RETURN n.vertex._key");
|
||||
actual = getQueryResults(queryStart + v5 + queryEnd);
|
||||
assertEqual(actual, [ ]);
|
||||
|
||||
actual = getQueryResults("FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, 'UnitTestsAhuacatlVertex/thefox', 'any') SORT n.vertex._key RETURN n.vertex._key");
|
||||
actual = getQueryResults(queryStart + theFox + queryEnd);
|
||||
assertEqual(actual, [ ]);
|
||||
|
||||
assertQueryError(errors.ERROR_ARANGO_COLLECTION_NOT_FOUND.code, "FOR e IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, 'thefox/thefox', 'any') SORT n.vertex._key RETURN n.vertex._key");
|
||||
assertQueryError(errors.ERROR_ARANGO_COLLECTION_NOT_FOUND.code, queryStart + "thefox/thefox" + queryEnd);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -178,26 +190,37 @@ function ahuacatlQueryEdgesTestSuite () {
|
|||
|
||||
testNeighborsIn : function () {
|
||||
var actual;
|
||||
var v1 = "UnitTestsAhuacatlVertex/v1";
|
||||
var v2 = "UnitTestsAhuacatlVertex/v2";
|
||||
var v3 = "UnitTestsAhuacatlVertex/v3";
|
||||
var v4 = "UnitTestsAhuacatlVertex/v4";
|
||||
var v5 = "UnitTestsAhuacatlVertex/v5";
|
||||
var v6 = "UnitTestsAhuacatlVertex/v6";
|
||||
var v7 = "UnitTestsAhuacatlVertex/v7";
|
||||
var v8 = "UnitTestsAhuacatlVertex/v8";
|
||||
var theFox = "UnitTestsAhuacatlVertex/thefox";
|
||||
var queryStart = "FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, '";
|
||||
var queryEnd = "', 'inbound') SORT n RETURN n";
|
||||
|
||||
actual = getQueryResults("FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, 'UnitTestsAhuacatlVertex/v1', 'inbound') SORT n.vertex._key RETURN [ n.vertex._key, n.edge.what ]");
|
||||
actual = getQueryResults(queryStart + v1 + queryEnd);
|
||||
assertEqual(actual, [ ]);
|
||||
|
||||
actual = getQueryResults("FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, 'UnitTestsAhuacatlVertex/v2', 'inbound') SORT n.vertex._key RETURN [ n.vertex._key, n.edge.what ]");
|
||||
assertEqual(actual, [ [ "v1", "v1->v2" ], [ "v4", "v4->v2" ] ]);
|
||||
actual = getQueryResults(queryStart + v2 + queryEnd);
|
||||
assertEqual(actual, [v1, v4]);
|
||||
|
||||
actual = getQueryResults("FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, 'UnitTestsAhuacatlVertex/v3', 'inbound') SORT n.vertex._key RETURN [ n.vertex._key, n.edge.what ]");
|
||||
assertEqual(actual, [ [ "v1", "v1->v3"], [ "v2", "v2->v3" ], [ "v6", "v6->v3"], [ "v7", "v7->v3" ] ]);
|
||||
actual = getQueryResults(queryStart + v3 + queryEnd);
|
||||
assertEqual(actual, [v1, v2, v6, v7]);
|
||||
|
||||
actual = getQueryResults("FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, 'UnitTestsAhuacatlVertex/v8', 'inbound') SORT n.vertex._key RETURN n.vertex._key");
|
||||
actual = getQueryResults(queryStart + v8 + queryEnd);
|
||||
assertEqual(actual, [ ]);
|
||||
|
||||
actual = getQueryResults("FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, 'UnitTestsAhuacatlVertex/v5', 'inbound') SORT n.vertex._key RETURN n.vertex._key");
|
||||
actual = getQueryResults(queryStart + v5 + queryEnd);
|
||||
assertEqual(actual, [ ]);
|
||||
|
||||
actual = getQueryResults("FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, 'UnitTestsAhuacatlVertex/thefox', 'inbound') SORT n.vertex._key RETURN n.vertex._key");
|
||||
actual = getQueryResults(queryStart + theFox + queryEnd);
|
||||
assertEqual(actual, [ ]);
|
||||
|
||||
assertQueryError(errors.ERROR_ARANGO_COLLECTION_NOT_FOUND.code, "FOR e IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, 'thefox/thefox', 'inbound') SORT n.vertex._key RETURN n.vertex._key");
|
||||
assertQueryError(errors.ERROR_ARANGO_COLLECTION_NOT_FOUND.code, queryStart + "thefox/thefox" + queryEnd);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -234,26 +257,37 @@ function ahuacatlQueryEdgesTestSuite () {
|
|||
|
||||
testNeighborsOut : function () {
|
||||
var actual;
|
||||
var v1 = "UnitTestsAhuacatlVertex/v1";
|
||||
var v2 = "UnitTestsAhuacatlVertex/v2";
|
||||
var v3 = "UnitTestsAhuacatlVertex/v3";
|
||||
var v4 = "UnitTestsAhuacatlVertex/v4";
|
||||
var v5 = "UnitTestsAhuacatlVertex/v5";
|
||||
var v6 = "UnitTestsAhuacatlVertex/v6";
|
||||
var v7 = "UnitTestsAhuacatlVertex/v7";
|
||||
var v8 = "UnitTestsAhuacatlVertex/v8";
|
||||
var theFox = "UnitTestsAhuacatlVertex/thefox";
|
||||
var queryStart = "FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, '";
|
||||
var queryEnd = "', 'outbound') SORT n RETURN n";
|
||||
|
||||
actual = getQueryResults("FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, 'UnitTestsAhuacatlVertex/v1', 'outbound') SORT n.vertex._key RETURN [ n.vertex._key, n.edge.what ]");
|
||||
assertEqual(actual, [ [ "v2", "v1->v2" ], [ "v3", "v1->v3" ] ]);
|
||||
actual = getQueryResults(queryStart + v1 + queryEnd);
|
||||
assertEqual(actual, [ v2, v3 ]);
|
||||
|
||||
actual = getQueryResults("FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, 'UnitTestsAhuacatlVertex/v2', 'outbound') SORT n.vertex._key RETURN [ n.vertex._key, n.edge.what ]");
|
||||
assertEqual(actual, [ [ "v3", "v2->v3" ] ]);
|
||||
actual = getQueryResults(queryStart + v2 + queryEnd);
|
||||
assertEqual(actual, [ v3 ]);
|
||||
|
||||
actual = getQueryResults("FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, 'UnitTestsAhuacatlVertex/v3', 'outbound') SORT n.vertex._key RETURN n.vertex._key");
|
||||
assertEqual(actual, [ "v4", "v6", "v7" ]);
|
||||
actual = getQueryResults(queryStart + v3 + queryEnd);
|
||||
assertEqual(actual, [ v4, v6, v7 ]);
|
||||
|
||||
actual = getQueryResults("FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, 'UnitTestsAhuacatlVertex/v8', 'outbound') SORT n.vertex._key RETURN n.vertex._key");
|
||||
assertEqual(actual, [ ]);
|
||||
|
||||
actual = getQueryResults("FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, 'UnitTestsAhuacatlVertex/v5', 'outbound') SORT n.vertex._key RETURN n.vertex._key");
|
||||
actual = getQueryResults(queryStart + v8 + queryEnd);
|
||||
assertEqual(actual, [ ]);
|
||||
|
||||
actual = getQueryResults("FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, 'UnitTestsAhuacatlVertex/thefox', 'outbound') SORT n.vertex._key RETURN n.vertex._key");
|
||||
actual = getQueryResults(queryStart + v5 + queryEnd);
|
||||
assertEqual(actual, [ ]);
|
||||
|
||||
assertQueryError(errors.ERROR_ARANGO_COLLECTION_NOT_FOUND.code, "FOR e IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, 'thefox/thefox', 'outbound') SORT n.vertex._key RETURN n.vertex._key");
|
||||
actual = getQueryResults(queryStart + theFox + queryEnd);
|
||||
assertEqual(actual, [ ]);
|
||||
|
||||
assertQueryError(errors.ERROR_ARANGO_COLLECTION_NOT_FOUND.code, queryStart + "thefox/thefox" + queryEnd);
|
||||
}
|
||||
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue