1
0
Fork 0

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

This commit is contained in:
Jan Steemann 2014-05-22 10:52:37 +02:00
commit dc742f255a
18 changed files with 987 additions and 473 deletions

View File

@ -17,9 +17,9 @@ fashion. The collection `_users` contains all users and a salted SHA256 hash
of their passwords. A user can be active or inactive. A typical document of this
collection is
@EXAMPLE_ARANGOSH_OUTPUT{AuthenticationExample1}
db._users.firstExample("user", "root")
@END_EXAMPLE_ARANGOSH_OUTPUT
@EXAMPLE_ARANGOSH_RUN{AuthenticationExample1}
log(db._users.firstExample("user", "root"));
@END_EXAMPLE_ARANGOSH_RUN
Command-Line Options for the Authentication and Authorisation{#DbaManualAuthenticationCommandLine}
--------------------------------------------------------------------------------------------------

View File

@ -60,12 +60,18 @@ OutputDir = "/tmp/"
################################################################################
### @brief arangosh output
###
### A list of commands that are executed in order to produce the output. The
### commands and there output is logged.
################################################################################
ArangoshOutput = {}
################################################################################
### @brief arangosh run
###
### A list of commands that are executed in order to produce the output. This
### is mostly used for HTTP request examples.
################################################################################
ArangoshRun = {}
@ -150,7 +156,7 @@ for filename in argv:
print >> sys.stderr, "%s\nduplicate file name '%s'\n%s\n" % ('#' * 80, name, '#' * 80)
ArangoshFiles[name] = True
ArangoshOutput[name] = ""
ArangoshOutput[name] = []
state = STATE_ARANGOSH_OUTPUT
continue
@ -179,7 +185,7 @@ for filename in argv:
line = line[len(strip):]
ArangoshOutput[name] += line + "\n"
ArangoshOutput[name].append(line)
elif state == STATE_ARANGOSH_RUN:
m = r4.match(line)
@ -221,6 +227,8 @@ for filename in argv:
### @brief generate arangosh example
################################################################################
gr1 = re.compile(r'^[ \n]*var ')
def generateArangoshOutput():
print "var internal = require('internal');"
print "var fs = require('fs');"
@ -242,7 +250,21 @@ def generateArangoshOutput():
print "(function() {"
print "internal.startCaptureMode();";
print "try { var value = %s; print(value); } catch (err) { print(err); }" % value
print "try {"
print " var XXX;"
for l in value:
m = gr1.match(l)
print "print('arangosh> %s');" % l.replace("\\", "\\\\").replace("'", "\\'")
if m:
print "%s" % l
else:
print "XXX = %s" % l
print "print(XXX);"
print "} catch (err) { print(err); }"
print "var output = internal.stopCaptureMode();";
print "ArangoshOutput['%s'] = output;" % key
if JS_DEBUG:
@ -279,12 +301,13 @@ def generateArangoshRun():
print "internal.output('RUN STARTING: %s\\n');" % key
print "var output = '';"
print "var appender = function(text) { output += text; };"
print "var logCurlRequestRaw = require('internal').appendCurlRequest(appender);"
print "var log = function (a) { internal.startCaptureMode(); print(a); appender(internal.stopCaptureMode()); };"
print "var logCurlRequestRaw = internal.appendCurlRequest(appender);"
print "var logCurlRequest = function () { var r = logCurlRequestRaw.apply(logCurlRequestRaw, arguments); db._collections(); return r; };"
print "var curlRequestRaw = require('internal').appendCurlRequest(function (text) { });"
print "var curlRequestRaw = internal.appendCurlRequest(function (text) {});"
print "var curlRequest = function () { return curlRequestRaw.apply(curlRequestRaw, arguments); };"
print "var logJsonResponse = require('internal').appendJsonResponse(appender);"
print "var logRawResponse = require('internal').appendRawResponse(appender);"
print "var logJsonResponse = internal.appendJsonResponse(appender);"
print "var logRawResponse = internal.appendRawResponse(appender);"
print "var assert = function(a) { if (! a) { internal.output('%s\\nASSERTION FAILED: %s\\n%s\\n'); throw new Error('assertion failed'); } };" % ('#' * 80, key, '#' * 80)
print "try { %s internal.output('RUN SUCCEEDED: %s\\n'); } catch (err) { print('%s\\nRUN FAILED: %s, ', err, '\\n%s\\n'); }" % (value, key, '#' * 80, key, '#' * 80)
print "ArangoshRun['%s'] = output;" % key

View File

@ -15,9 +15,9 @@ corresponding language API.
For example:
@EXAMPLE_ARANGOSH_OUTPUT{HandlingDocumentsExample1}
db.demo.document("demo/schlonz")
@END_EXAMPLE_ARANGOSH_OUTPUT
@EXAMPLE_ARANGOSH_RUN{HandlingDocumentsExample1}
log(db.demo.document("demo/schlonz"));
@END_EXAMPLE_ARANGOSH_RUN
All documents contain special attributes: the document handle in `_id`, the
document's unique key in `_key` and and the ETag aka document revision in

View File

@ -344,6 +344,7 @@ SHELL_COMMON = \
@top_srcdir@/js/common/tests/shell-edge.js \
@top_srcdir@/js/common/tests/shell-errors.js \
@top_srcdir@/js/common/tests/shell-fs.js \
@top_srcdir@/js/common/tests/shell-general-graph.js \
@top_srcdir@/js/common/tests/shell-graph-traversal.js \
@top_srcdir@/js/common/tests/shell-graph-algorithms.js \
@top_srcdir@/js/common/tests/shell-graph-measurement.js \
@ -454,6 +455,7 @@ SHELL_SERVER_AHUACATL = @top_srcdir@/js/server/tests/ahuacatl-ranges.js \
@top_srcdir@/js/server/tests/ahuacatl-hash.js \
@top_srcdir@/js/server/tests/ahuacatl-skiplist.js \
@top_srcdir@/js/server/tests/ahuacatl-cross.js \
@top_srcdir@/js/server/tests/ahuacatl-general-graph.js \
@top_srcdir@/js/server/tests/ahuacatl-graph.js \
@top_srcdir@/js/server/tests/ahuacatl-edges.js \
@top_srcdir@/js/server/tests/ahuacatl-refaccess-variable.js \

View File

@ -438,6 +438,19 @@ static TRI_doc_update_policy_e ExtractUpdatePolicy (v8::Arguments const& argv,
return policy;
}
TRI_doc_update_policy_e ExtractUpdatePolicy (bool overwrite) {
TRI_doc_update_policy_e policy ;
if (overwrite) {
// overwrite!
policy = TRI_DOC_UPDATE_LAST_WRITE;
}
else {
policy = TRI_DOC_UPDATE_CONFLICT;
}
return policy;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief wraps a C++ into a v8::Object
////////////////////////////////////////////////////////////////////////////////
@ -2508,6 +2521,17 @@ static v8::Handle<v8::Value> SaveEdgeCol (
return scope.Close(result);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief internal struct which is used for reading the different option
/// parameters for the update function
////////////////////////////////////////////////////////////////////////////////
struct UpdateOptions {
bool overwrite = true;
bool keepNull = true;
bool waitForSync = false;
};
////////////////////////////////////////////////////////////////////////////////
/// @brief updates (patches) a document
////////////////////////////////////////////////////////////////////////////////
@ -2515,18 +2539,43 @@ static v8::Handle<v8::Value> SaveEdgeCol (
static v8::Handle<v8::Value> UpdateVocbaseCol (bool useCollection,
v8::Arguments const& argv) {
v8::HandleScope scope;
UpdateOptions options;
TRI_doc_update_policy_e policy = TRI_DOC_UPDATE_ERROR;
// check the arguments
if (argv.Length() < 2 || argv.Length() > 5) {
TRI_V8_EXCEPTION_USAGE(scope, "update(<document>, <data>, <overwrite>, <keepnull>, <waitForSync>)");
TRI_V8_EXCEPTION_USAGE(scope, "update(<document>, <data>, <overwrite>, <keepNull>, <waitForSync>)");
}
const TRI_doc_update_policy_e policy = ExtractUpdatePolicy(argv, 3);
if (argv.Length() > 2) {
if (argv[2]->IsObject()) {
v8::Handle<v8::Object> optionsObject = argv[2].As<v8::Object>();
if (optionsObject->Has(v8::String::New("overwrite"))) {
options.overwrite = TRI_ObjectToBoolean(optionsObject->Get(v8::String::New("overwrite")));
policy = ExtractUpdatePolicy(options.overwrite);
}
if (optionsObject->Has(v8::String::New("keepNull"))) {
options.keepNull = TRI_ObjectToBoolean(optionsObject->Get(v8::String::New("keepNull")));
}
if (optionsObject->Has(v8::String::New("waitForSync"))) {
options.waitForSync = TRI_ObjectToBoolean(optionsObject->Get(v8::String::New("waitForSync")));
}
} else { // old variant update(<document>, <data>, <overwrite>, <keepNull>, <waitForSync>)
if (argv.Length() > 2 ) {
options.overwrite = TRI_ObjectToBoolean(argv[2]);
policy = ExtractUpdatePolicy(options.overwrite);
}
if (argv.Length() > 3 ) {
options.keepNull = TRI_ObjectToBoolean(argv[3]);
}
if (argv.Length() > 4 ) {
options.waitForSync = TRI_ObjectToBoolean(argv[4]);
}
}
}
// LOG_ERROR ( "overwrite %d keepNull %d waitForSync %d" , options.overwrite , options.keepNull , options.waitForSync);
// delete null attributes
// default value: null values are saved as Null
const bool nullMeansRemove = (argv.Length() >= 4 && ! TRI_ObjectToBoolean(argv[3]));
const bool forceSync = ExtractForceSync(argv, 5);
TRI_voc_key_t key = 0;
TRI_voc_rid_t rid;
@ -2573,9 +2622,9 @@ static v8::Handle<v8::Value> UpdateVocbaseCol (bool useCollection,
if (ServerState::instance()->isCoordinator()) {
return scope.Close(ModifyVocbaseColCoordinator(col,
policy,
forceSync,
options.waitForSync,
true, // isPatch
! nullMeansRemove, // keepNull
! options.keepNull,
argv));
}
@ -2641,7 +2690,7 @@ static v8::Handle<v8::Value> UpdateVocbaseCol (bool useCollection,
}
}
TRI_json_t* patchedJson = TRI_MergeJson(TRI_UNKNOWN_MEM_ZONE, old, json, nullMeansRemove);
TRI_json_t* patchedJson = TRI_MergeJson(TRI_UNKNOWN_MEM_ZONE, old, json, ! options.keepNull);
TRI_FreeJson(zone, old);
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
@ -2650,7 +2699,7 @@ static v8::Handle<v8::Value> UpdateVocbaseCol (bool useCollection,
TRI_V8_EXCEPTION_MEMORY(scope);
}
res = trx.updateDocument(key, &document, patchedJson, policy, forceSync, rid, &actualRevision);
res = trx.updateDocument(key, &document, patchedJson, policy, options.waitForSync, rid, &actualRevision);
res = trx.finish(res);
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, patchedJson);

View File

@ -512,13 +512,16 @@ function delete_graph_graph (req, res) {
////////////////////////////////////////////////////////////////////////////////
/// @brief creates a graph vertex
///
/// @RESTHEADER{POST /_api/graph/`graph-name`/vertex,create vertex}
/// @RESTHEADER{POST /_api/graph/`graph-name`/`vertex-name`,create vertex}
///
/// @RESTURLPARAMETERS
///
/// @RESTURLPARAM{graph-name,string,required}
/// The name of the graph
///
/// @RESTURLPARAM{vertex-name,string,required}
/// The name of the vertex
///
/// @RESTQUERYPARAMETERS
///
/// @RESTQUERYPARAM{waitForSync,boolean,optional}
@ -600,7 +603,7 @@ function post_graph_vertex (req, res, g) {
////////////////////////////////////////////////////////////////////////////////
/// @brief gets the vertex properties
///
/// @RESTHEADER{GET /_api/graph/`graph-name`/vertex,get vertex}
/// @RESTHEADER{GET /_api/graph/`graph-name`/`vertex-name`,get vertex}
///
/// @RESTURLPARAMETERS
///
@ -694,13 +697,16 @@ function get_graph_vertex (req, res, g) {
////////////////////////////////////////////////////////////////////////////////
/// @brief delete vertex
///
/// @RESTHEADER{DELETE /_api/graph/`graph-name`/vertex,delete vertex}
/// @RESTHEADER{DELETE /_api/graph/`graph-name`/`vertex-name`,delete vertex}
///
/// @RESTURLPARAMETERS
///
/// @RESTURLPARAM{graph-name,string,required}
/// The name of the graph
///
/// @RESTURLPARAM{vertex-name,string,required}
/// The name of the vertex
///
/// @RESTQUERYPARAMETERS
///
/// @RESTQUERYPARAM{waitForSync,boolean,optional}
@ -858,13 +864,16 @@ function update_graph_vertex (req, res, g, isPatch) {
////////////////////////////////////////////////////////////////////////////////
/// @brief updates a vertex
///
/// @RESTHEADER{PUT /_api/graph/`graph-name`/vertex,update vertex}
/// @RESTHEADER{PUT /_api/graph/`graph-name`/`vertex-name`,update vertex}
///
/// @RESTURLPARAMETERS
///
/// @RESTURLPARAM{graph-name,string,required}
/// The name of the graph
///
/// @RESTURLPARAM{vertex-name,string,required}
/// The name of the vertex
///
/// @RESTQUERYPARAMETERS
///
/// @RESTQUERYPARAM{waitForSync,boolean,optional}
@ -933,13 +942,16 @@ function put_graph_vertex (req, res, g) {
////////////////////////////////////////////////////////////////////////////////
/// @brief updates a vertex
///
/// @RESTHEADER{PATCH /_api/graph/`graph-name`/vertex,update vertex}
/// @RESTHEADER{PATCH /_api/graph/`graph-name`/`vertex-name`,update vertex}
///
/// @RESTURLPARAMETERS
///
/// @RESTURLPARAM{graph-name,string,required}
/// The name of the graph
///
/// @RESTURLPARAM{vertex-name,string,required}
/// The name of the vertex
///
/// @RESTQUERYPARAMETERS
///
/// @RESTQUERYPARAM{waitForSync,boolean,optional}
@ -1389,13 +1401,16 @@ function post_graph_vertex_vertices (req, res, g) {
////////////////////////////////////////////////////////////////////////////////
/// @brief creates an edge
///
/// @RESTHEADER{POST /_api/graph/`graph-name`/edge,create edge}
/// @RESTHEADER{POST /_api/graph/`graph-name`/`edge-name`,create edge}
///
/// @RESTURLPARAMETERS
///
/// @RESTURLPARAM{graph-name,string,required}
/// The name of the graph
///
/// @RESTURLPARAM{edge-name,string,required}
/// The name of the edge
///
/// @RESTQUERYPARAMETERS
///
/// @RESTQUERYPARAM{waitForSync,boolean,optional}
@ -1587,13 +1602,16 @@ function get_graph_edge (req, res, g) {
////////////////////////////////////////////////////////////////////////////////
/// @brief deletes an edge
///
/// @RESTHEADER{DELETE /_api/graph/`graph-name`/edge,delete edge}
/// @RESTHEADER{DELETE /_api/graph/`graph-name`/`edge-name`,delete edge}
///
/// @RESTURLPARAMETERS
///
/// @RESTURLPARAM{graph-name,string,required}
/// The name of the graph
///
/// @RESTURLPARAM{edge-name,string,required}
/// The name of the edge
///
/// @RESTQUERYPARAMETERS
///
/// @RESTQUERYPARAM{waitForSync,boolean,optional}
@ -1754,13 +1772,16 @@ function update_graph_edge (req, res, g, isPatch) {
////////////////////////////////////////////////////////////////////////////////
/// @brief updates an edge
///
/// @RESTHEADER{PUT /_api/graph/`graph-name`/edge,update edge}
/// @RESTHEADER{PUT /_api/graph/`graph-name`/`edge-name`,update edge}
///
/// @RESTURLPARAMETERS
///
/// @RESTURLPARAM{graph-name,string,required}
/// The name of the graph
///
/// @RESTURLPARAM{edge-name,string,required}
/// The name of the edge
///
/// @RESTQUERYPARAMETERS
///
/// @RESTQUERYPARAM{waitForSync,boolean,optional}
@ -1833,13 +1854,16 @@ function put_graph_edge (req, res, g) {
////////////////////////////////////////////////////////////////////////////////
/// @brief updates an edge
///
/// @RESTHEADER{PATCH /_api/graph/`graph-name`/edge,update edge}
/// @RESTHEADER{PATCH /_api/graph/`graph-name`/`edge-name`,update edge}
///
/// @RESTURLPARAMETERS
///
/// @RESTURLPARAM{graph-name,string,required}
/// The name of the graph
///
/// @RESTURLPARAM{edge-name,string,required}
/// The name of the edge
///
/// @RESTQUERYPARAMETERS
///
/// @RESTQUERYPARAM{waitForSync,boolean,optional}

View File

@ -1200,12 +1200,29 @@ ArangoCollection.prototype.update = function (id, data, overwrite, keepNull, wai
id = id._id;
}
// set default value for keepNull
var keepNullValue = ((typeof keepNull === "undefined") ? true : keepNull);
var params = "?keepNull=" + (keepNullValue ? "true" : "false");
var params = "";
if (typeof overwrite === "object") {
// we assume the caller uses new signature (id, data, options)
var options = overwrite;
if (! options.hasOwnProperty("keepNull")) {
options.keepNull = true;
}
params = "?keepNull=" + options.keepNull;
if (options.hasOwnProperty("overwrite") && options.overwrite) {
params += "&policy=last";
}
} else {
// set default value for keepNull
var keepNullValue = ((typeof keepNull === "undefined") ? true : keepNull);
params = "?keepNull=" + (keepNullValue ? "true" : "false");
if (overwrite) {
params += "&policy=last";
}
if (overwrite) {
params += "&policy=last";
}
var url = this._documenturl(id) + params;

View File

@ -747,14 +747,27 @@ ArangoDatabase.prototype._update = function (id, data, overwrite, keepNull, wait
id = id._id;
}
// set default value for keepNull
var keepNullValue = ((typeof keepNull === "undefined") ? true : keepNull);
var params = "?keepNull=" + (keepNullValue ? "true" : "false");
var params = "";
if (typeof overwrite === "object") {
// we assume the caller uses new signature (id, data, options)
var options = overwrite;
if (! options.hasOwnProperty("keepNull")) {
options.keepNull = true;
}
params = "?keepNull=" + options.keepNull;
if (overwrite) {
params += "&policy=last";
if (options.hasOwnProperty("overwrite") && options.overwrite) {
params += "&policy=last";
}
} else {
// set default value for keepNull
var keepNullValue = ((typeof keepNull === "undefined") ? true : keepNull);
params = "?keepNull=" + (keepNullValue ? "true" : "false");
if (overwrite) {
params += "&policy=last";
}
}
var url = this._documenturl(id) + params;
url = this._appendSyncParameter(url, waitForSync);

View File

@ -1,5 +0,0 @@
<script id="modalWarning.ejs" type="text/template">
<p>
There is no statistical data yet, please wait a few seconds and try again.</b>.
</p>
</script>

View File

@ -97,7 +97,8 @@
undefined,
this.events
);
window.modalView.hideFooter = false;
window.modalView.hideFooter = false;
$('#modal-dialog').on('hidden', function () {
self.hidden();
@ -411,13 +412,7 @@
if (d.times.length > 0) {
self.isUpdating = true;
self.mergeHistory(d);
} else if (self.isUpdating !== true) {
window.modalView.show(
"modalWarning.ejs",
"WARNING !"
);
self.isUpdating = false;
}
}
}
);
},

View File

@ -47,7 +47,6 @@
"frontend/js/templates/modalCollectionInfo.ejs",
"frontend/js/templates/modalGraph.ejs",
"frontend/js/templates/modalNewVersion.ejs",
"frontend/js/templates/modalWarning.ejs",
"frontend/js/templates/modalTable.ejs",
"frontend/js/templates/modalHotkeys.ejs",
"frontend/js/templates/navigationView.ejs",

View File

@ -712,32 +712,6 @@
});
it("getStatistics without nextStart and no data yet", function () {
view.server = {
endpoint: "abcde",
target: "xyz"
};
spyOn(view, "mergeHistory");
spyOn(modalDummy, "show");
spyOn($, "ajax").andCallFake(function (url, opt) {
expect(opt.async).toEqual(false);
return {
done: function (y) {
y({
times: []
});
}
};
});
view.getStatistics();
expect(view.mergeHistory).not.toHaveBeenCalled();
expect(modalDummy.show).toHaveBeenCalledWith("modalWarning.ejs",
"WARNING !");
expect(view.isUpdating).toEqual(false);
});
it("prepare D3Charts", function () {
spyOn(nv, "addGraph").andCallFake(function (a, b) {
a();

View File

@ -1199,12 +1199,29 @@ ArangoCollection.prototype.update = function (id, data, overwrite, keepNull, wai
id = id._id;
}
// set default value for keepNull
var keepNullValue = ((typeof keepNull === "undefined") ? true : keepNull);
var params = "?keepNull=" + (keepNullValue ? "true" : "false");
var params = "";
if (typeof overwrite === "object") {
// we assume the caller uses new signature (id, data, options)
var options = overwrite;
if (! options.hasOwnProperty("keepNull")) {
options.keepNull = true;
}
params = "?keepNull=" + options.keepNull;
if (options.hasOwnProperty("overwrite") && options.overwrite) {
params += "&policy=last";
}
} else {
// set default value for keepNull
var keepNullValue = ((typeof keepNull === "undefined") ? true : keepNull);
params = "?keepNull=" + (keepNullValue ? "true" : "false");
if (overwrite) {
params += "&policy=last";
}
if (overwrite) {
params += "&policy=last";
}
var url = this._documenturl(id) + params;

View File

@ -746,14 +746,27 @@ ArangoDatabase.prototype._update = function (id, data, overwrite, keepNull, wait
id = id._id;
}
// set default value for keepNull
var keepNullValue = ((typeof keepNull === "undefined") ? true : keepNull);
var params = "?keepNull=" + (keepNullValue ? "true" : "false");
var params = "";
if (typeof overwrite === "object") {
// we assume the caller uses new signature (id, data, options)
var options = overwrite;
if (! options.hasOwnProperty("keepNull")) {
options.keepNull = true;
}
params = "?keepNull=" + options.keepNull;
if (overwrite) {
params += "&policy=last";
if (options.hasOwnProperty("overwrite") && options.overwrite) {
params += "&policy=last";
}
} else {
// set default value for keepNull
var keepNullValue = ((typeof keepNull === "undefined") ? true : keepNull);
params = "?keepNull=" + (keepNullValue ? "true" : "false");
if (overwrite) {
params += "&policy=last";
}
}
var url = this._documenturl(id) + params;
url = this._appendSyncParameter(url, waitForSync);

View File

@ -24,7 +24,7 @@
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Florian Bartels
/// @author Florian Bartels, Michael Hackstein, Guido Schwab
/// @author Copyright 2011-2014, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
@ -123,7 +123,7 @@ var findOrCreateCollectionsByEdgeDefinitions = function (edgeDefinitions, noCrea
/// @brief internal function to get graphs collection
////////////////////////////////////////////////////////////////////////////////
var _getGraphCollection = function() {
var getGraphCollection = function() {
var gCol = db._graphs;
if (gCol === null || gCol === undefined) {
throw "_graphs collection does not exist.";
@ -131,6 +131,20 @@ var _getGraphCollection = function() {
return gCol;
};
////////////////////////////////////////////////////////////////////////////////
/// @brief internal function to wrap arango collections for overwrite
////////////////////////////////////////////////////////////////////////////////
var wrapCollection = function(col) {
var wrapper = {};
_.each(_.functions(col), function(func) {
wrapper[func] = function() {
return col[func].apply(col, arguments);
};
});
return wrapper;
};
// -----------------------------------------------------------------------------
@ -164,10 +178,25 @@ var AQLGenerator = function(graph) {
"graphName": graph.__name
};
this.graph = graph;
this.cursor = null;
this.lastEdgeVar = "";
};
AQLGenerator.prototype._clearCursor = function() {
if (this.cursor) {
this.cursor.dispose();
this.cursor = null;
}
};
AQLGenerator.prototype._createCursor = function() {
if (!this.cursor) {
this.cursor = this.execute();
}
};
AQLGenerator.prototype.edges = function(startVertex, direction) {
this._clearCursor();
var edgeName = "edges_" + this.stack.length;
var query = "FOR " + edgeName
+ " IN GRAPH_EDGES(@graphName,@startVertex_"
@ -188,6 +217,7 @@ AQLGenerator.prototype.getLastEdgeVar = function() {
};
AQLGenerator.prototype.restrict = function(restrictions) {
this._clearCursor();
var rest = stringToArray(restrictions);
var unknown = [];
var g = this.graph;
@ -215,6 +245,7 @@ AQLGenerator.prototype.restrict = function(restrictions) {
};
AQLGenerator.prototype.filter = function(example) {
this._clearCursor();
var ex = [];
if (Object.prototype.toString.call(example) !== "[object Array]") {
if (Object.prototype.toString.call(example) !== "[object Object]") {
@ -254,14 +285,31 @@ AQLGenerator.prototype.printQuery = function() {
};
AQLGenerator.prototype.execute = function() {
this._clearCursor();
var query = this.printQuery();
var bindVars = this.bindVars;
query += " RETURN " + this.getLastEdgeVar();
return db._query(query, bindVars);
return db._query(query, bindVars, {count: true});
};
AQLGenerator.prototype.toArray = function() {
return this.execute().toArray();
this._createCursor();
return this.cursor.toArray();
};
AQLGenerator.prototype.count = function() {
this._createCursor();
return this.cursor.count();
};
AQLGenerator.prototype.hasNext = function() {
this._createCursor();
return this.cursor.hasNext();
};
AQLGenerator.prototype.next = function() {
this._createCursor();
return this.cursor.next();
};
// -----------------------------------------------------------------------------
@ -269,7 +317,32 @@ AQLGenerator.prototype.toArray = function() {
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @fn JSF_general_graph_undirectedRelationDefinition
/// @brief define an undirected relation.
///
/// @FUN{general-graph._undirectedRelationDefinition(@FA{relationName}, @FA{vertexCollections})}
///
/// Defines an undirected relation with the name @FA{relationName} using the
/// list of @FA{vertexCollections}. This relation allows the user to store
/// edges in any direction between any pair of vertices within the
/// @FA{vertexCollections}.
///
/// @EXAMPLES
///
/// To define simple relation with only one vertex collection:
///
/// @EXAMPLE_ARANGOSH_OUTPUT{generalGraphUndirectedRelationDefinition1}
/// var graph = require("org/arangodb/general-graph");
/// graph._undirectedRelationDefinition("friend", "user");
/// @END_EXAMPLE_ARANGOSH_OUTPUT
///
/// To define a relation between several vertex collections:
///
/// @EXAMPLE_ARANGOSH_OUTPUT{generalGraphUndirectedRelationDefinition2}
/// var graph = require("org/arangodb/general-graph");
/// graph._undirectedRelationDefinition("marriage", ["female", "male"]);
/// @END_EXAMPLE_ARANGOSH_OUTPUT
///
////////////////////////////////////////////////////////////////////////////////
@ -331,7 +404,7 @@ var _directedRelationDefinition = function (
////////////////////////////////////////////////////////////////////////////////
var edgeDefinitions = function () {
var _edgeDefinitions = function () {
var res = [], args = arguments;
Object.keys(args).forEach(function (x) {
@ -342,6 +415,20 @@ var edgeDefinitions = function () {
};
////////////////////////////////////////////////////////////////////////////////
/// @brief extend an edge definitions
////////////////////////////////////////////////////////////////////////////////
var _extendEdgeDefinitions = function () {
var args = arguments;
var res = args[0];
args = args.slice(1);
res.concat(args);
};
////////////////////////////////////////////////////////////////////////////////
/// @brief create a new graph
////////////////////////////////////////////////////////////////////////////////
@ -349,7 +436,7 @@ var edgeDefinitions = function () {
var _create = function (graphName, edgeDefinitions) {
var gdb = _getGraphCollection(),
var gdb = getGraphCollection(),
g,
graphAlreadyExists = true,
collections;
@ -396,11 +483,10 @@ var Graph = function(graphName, edgeDefinitions, vertexCollections, edgeCollecti
this.__edgeCollections = edgeCollections;
this.__edgeDefinitions = edgeDefinitions;
_.each(vertexCollections, function(obj, key) {
self[key] = obj;
var old_remove = obj.remove.bind(obj);
obj.remove = function(vertexId, options) {
var wrap = wrapCollection(obj);
var old_remove = wrap.remove;
wrap.remove = function(vertexId, options) {
var myEdges = self._EDGES(vertexId);
myEdges.forEach(
function(edgeObj) {
@ -417,12 +503,13 @@ var Graph = function(graphName, edgeDefinitions, vertexCollections, edgeCollecti
}
return old_remove(vertexId, options);
};
self[key] = wrap;
});
_.each(edgeCollections, function(obj, key) {
self[key] = obj;
var old_save = obj.save.bind(obj);
obj.save = function(from, to, data) {
var wrap = wrapCollection(obj);
var old_save = wrap.save;
wrap.save = function(from, to, data) {
edgeDefinitions.forEach(
function(edgeDefinition) {
if (edgeDefinition.collection === key) {
@ -437,6 +524,7 @@ var Graph = function(graphName, edgeDefinitions, vertexCollections, edgeCollecti
);
return old_save(from, to, data);
};
self[key] = wrap;
});
};
@ -448,7 +536,7 @@ var Graph = function(graphName, edgeDefinitions, vertexCollections, edgeCollecti
var _graph = function(graphName) {
var gdb = _getGraphCollection(),
var gdb = getGraphCollection(),
g, collections;
try {
@ -471,17 +559,46 @@ var _graph = function(graphName) {
////////////////////////////////////////////////////////////////////////////////
var _exists = function(graphId) {
var gCol = _getGraphCollection();
var gCol = getGraphCollection();
return gCol.exists(graphId);
};
////////////////////////////////////////////////////////////////////////////////
/// @brief Helper for dropping collections of a graph.
////////////////////////////////////////////////////////////////////////////////
var checkIfMayBeDropped = function(colName, graphName, graphs) {
var result = true;
graphs.forEach(
function(graph) {
if (graph._key === graphName) {
return;
}
var edgeDefinitions = graph.edgeDefinitions;
if (graph.edgeDefinitions) {
edgeDefinitions.forEach(
function(edgeDefinition) {
var from = edgeDefinition.from;
var to = edgeDefinition.to;
var collection = edgeDefinition.collection;
if (collection === colName || from.indexOf(colName) !== -1 || to.indexOf(colName) !== -1) {
result = false;
}
}
);
}
}
);
return result;
};
////////////////////////////////////////////////////////////////////////////////
/// @brief drop a graph.
////////////////////////////////////////////////////////////////////////////////
var _drop = function(graphId, dropCollections) {
var gdb = _getGraphCollection();
var gdb = getGraphCollection();
if (!gdb.exists(graphId)) {
throw "Graph " + graphId + " does not exist.";
@ -494,16 +611,23 @@ var _drop = function(graphId, dropCollections) {
function(edgeDefinition) {
var from = edgeDefinition.from;
var to = edgeDefinition.to;
var edge = edgeDefinition.collection;
db._drop(edge);
var collection = edgeDefinition.collection;
var graphs = getGraphCollection().toArray();
if (checkIfMayBeDropped(collection, graph._key, graphs)) {
db._drop(collection);
}
from.forEach(
function(col) {
db._drop(col);
if (checkIfMayBeDropped(col, graph._key, graphs)) {
db._drop(col);
}
}
);
to.forEach(
function(col) {
db._drop(col);
if (checkIfMayBeDropped(col, graph._key, graphs)) {
db._drop(col);
}
}
);
}
@ -669,7 +793,8 @@ Graph.prototype._getVertexCollectionByName = function(name) {
exports._undirectedRelationDefinition = _undirectedRelationDefinition;
exports._directedRelationDefinition = _directedRelationDefinition;
exports._graph = _graph;
exports.edgeDefinitions = edgeDefinitions;
exports._edgeDefinitions = _edgeDefinitions;
exports._extendEdgeDefinitions = _extendEdgeDefinitions;
exports._create = _create;
exports._drop = _drop;
exports._exists = _exists;

View File

@ -855,6 +855,123 @@ function CollectionDocumentSuite () {
assertEqual(a1._id, a10._id);
assertNotEqual(a9._rev, a10._rev);
var doc10 = collection.document(a1._id);
assertEqual(a1._id, doc10._id);
assertEqual(a10._rev, doc10._rev);
assertEqual({"one": -1, "three": 3, "five": 5}, doc10.d);
assertEqual({"e1": 1, "e3": 3}, doc10.e);
assertEqual({"one": 1, "three": 3}, doc10.f);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief update a document
////////////////////////////////////////////////////////////////////////////////
testNewSignatureUpdateDocument : function () {
var a1 = collection.save({ a : 1});
assertTypeOf("string", a1._id);
assertTypeOf("string", a1._rev);
var a2 = collection.update(a1, { a : 2 });
assertEqual(a1._id, a2._id);
assertNotEqual(a1._rev, a2._rev);
try {
collection.update(a1, { a : 3 });
fail();
}
catch (err) {
assertEqual(ERRORS.ERROR_ARANGO_CONFLICT.code, err.errorNum);
}
var doc2 = collection.document(a1._id);
assertEqual(a1._id, doc2._id);
assertEqual(a2._rev, doc2._rev);
assertEqual(2, doc2.a);
var a4 = collection.update(a1, { a : 4 }, {"overwrite": true});
assertEqual(a1._id, a4._id);
assertNotEqual(a1._rev, a4._rev);
assertNotEqual(a2._rev, a4._rev);
var doc4 = collection.document(a1._id);
assertEqual(a1._id, doc4._id);
assertEqual(a4._rev, doc4._rev);
assertEqual(4, doc4.a);
var a5 = collection.update(a4, { b : 1, c : 2, d : "foo", e : null });
assertEqual(a1._id, a5._id);
assertNotEqual(a4._rev, a5._rev);
var doc5 = collection.document(a1._id);
assertEqual(a1._id, doc5._id);
assertEqual(a5._rev, doc5._rev);
assertEqual(4, doc5.a);
assertEqual(1, doc5.b);
assertEqual(2, doc5.c);
assertEqual("foo", doc5.d);
assertEqual(null, doc5.e);
var a6 = collection.update(a5, { f : null, b : null, a : null, g : 2, c : 4 });
assertEqual(a1._id, a6._id);
assertNotEqual(a5._rev, a6._rev);
var doc6 = collection.document(a1._id);
assertEqual(a1._id, doc6._id);
assertEqual(a6._rev, doc6._rev);
assertEqual(null, doc6.a);
assertEqual(null, doc6.b);
assertEqual(4, doc6.c);
assertEqual("foo", doc6.d);
assertEqual(null, doc6.e);
assertEqual(null, doc6.f);
assertEqual(2, doc6.g);
var a7 = collection.update(a6, { a : null, b : null, c : null, g : null }, {"overwrite": true, "keepNull": false});
assertEqual(a1._id, a7._id);
assertNotEqual(a6._rev, a7._rev);
var doc7 = collection.document(a1._id);
assertEqual(a1._id, doc7._id);
assertEqual(a7._rev, doc7._rev);
assertEqual(undefined, doc7.a);
assertEqual(undefined, doc7.b);
assertEqual(undefined, doc7.c);
assertEqual("foo", doc7.d);
assertEqual(null, doc7.e);
assertEqual(null, doc7.f);
assertEqual(undefined, doc7.g);
var a8 = collection.update(a7, { d : { "one" : 1, "two" : 2, "three" : 3 }, e : { }, f : { "one" : 1 }} );
assertEqual(a1._id, a8._id);
assertNotEqual(a7._rev, a8._rev);
var doc8 = collection.document(a1._id);
assertEqual(a1._id, doc8._id);
assertEqual(a8._rev, doc8._rev);
assertEqual({"one": 1, "two": 2, "three": 3}, doc8.d);
assertEqual({}, doc8.e);
assertEqual({"one": 1}, doc8.f);
var a9 = collection.update(a8, { d : { "four" : 4 }, "e" : { "e1" : [ 1, 2 ], "e2" : 2 }, "f" : { "three" : 3 }} );
assertEqual(a1._id, a9._id);
assertNotEqual(a8._rev, a9._rev);
var doc9 = collection.document(a1._id);
assertEqual(a1._id, doc9._id);
assertEqual(a9._rev, doc9._rev);
assertEqual({"one": 1, "two": 2, "three": 3, "four": 4}, doc9.d);
assertEqual({"e2": 2, "e1": [ 1, 2 ]}, doc9.e);
assertEqual({"one": 1, "three": 3}, doc9.f);
var a10 = collection.update(a9, { d : { "one" : -1, "two": null, "four" : null, "five" : 5 }, "e" : { "e1" : 1, "e2" : null, "e3" : 3 }}, {"overwrite": true, "keepNull": false});
assertEqual(a1._id, a10._id);
assertNotEqual(a9._rev, a10._rev);
var doc10 = collection.document(a1._id);
assertEqual(a1._id, doc10._id);
assertEqual(a10._rev, doc10._rev);
@ -1405,6 +1522,123 @@ function DatabaseDocumentSuite () {
assertEqual(a1._id, a10._id);
assertNotEqual(a9._rev, a10._rev);
var doc10 = db._document(a1._id);
assertEqual(a1._id, doc10._id);
assertEqual(a10._rev, doc10._rev);
assertEqual({"one": -1, "three": 3, "five": 5}, doc10.d);
assertEqual({"e1": 1, "e3": 3}, doc10.e);
assertEqual({"one": 1, "three": 3}, doc10.f);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief tests update function with new signature
////////////////////////////////////////////////////////////////////////////////
testNewsignatureOf_UpdateDocument : function () {
var a1 = collection.save({ a : 1});
assertTypeOf("string", a1._id);
assertTypeOf("string", a1._rev);
var a2 = db._update(a1, { a : 2 });
assertEqual(a1._id, a2._id);
assertNotEqual(a1._rev, a2._rev);
try {
db._update(a1, { a : 3 });
fail();
}
catch (err) {
assertEqual(ERRORS.ERROR_ARANGO_CONFLICT.code, err.errorNum);
}
var doc2 = db._document(a1._id);
assertEqual(a1._id, doc2._id);
assertEqual(a2._rev, doc2._rev);
assertEqual(2, doc2.a);
var a4 = db._update(a1, { a : 4 }, {"overwrite": true});
assertEqual(a1._id, a4._id);
assertNotEqual(a1._rev, a4._rev);
assertNotEqual(a2._rev, a4._rev);
var doc4 = db._document(a1._id);
assertEqual(a1._id, doc4._id);
assertEqual(a4._rev, doc4._rev);
assertEqual(4, doc4.a);
var a5 = db._update(a4, { b : 1, c : 2, d : "foo", e : null });
assertEqual(a1._id, a5._id);
assertNotEqual(a4._rev, a5._rev);
var doc5 = db._document(a1._id);
assertEqual(a1._id, doc5._id);
assertEqual(a5._rev, doc5._rev);
assertEqual(4, doc5.a);
assertEqual(1, doc5.b);
assertEqual(2, doc5.c);
assertEqual("foo", doc5.d);
assertEqual(null, doc5.e);
var a6 = db._update(a5, { f : null, b : null, a : null, g : 2, c : 4 });
assertEqual(a1._id, a6._id);
assertNotEqual(a5._rev, a6._rev);
var doc6 = db._document(a1._id);
assertEqual(a1._id, doc6._id);
assertEqual(a6._rev, doc6._rev);
assertEqual(null, doc6.a);
assertEqual(null, doc6.b);
assertEqual(4, doc6.c);
assertEqual("foo", doc6.d);
assertEqual(null, doc6.e);
assertEqual(null, doc6.f);
assertEqual(2, doc6.g);
var a7 = db._update(a6, { a : null, b : null, c : null, g : null }, {"overwrite": true, "keepNull": false});
assertEqual(a1._id, a7._id);
assertNotEqual(a6._rev, a7._rev);
var doc7 = db._document(a1._id);
assertEqual(a1._id, doc7._id);
assertEqual(a7._rev, doc7._rev);
assertEqual(undefined, doc7.a);
assertEqual(undefined, doc7.b);
assertEqual(undefined, doc7.c);
assertEqual("foo", doc7.d);
assertEqual(null, doc7.e);
assertEqual(null, doc7.f);
assertEqual(undefined, doc7.g);
var a8 = db._update(a7, { d : { "one" : 1, "two" : 2, "three" : 3 }, e : { }, f : { "one" : 1 }} );
assertEqual(a1._id, a8._id);
assertNotEqual(a7._rev, a8._rev);
var doc8 = db._document(a1._id);
assertEqual(a1._id, doc8._id);
assertEqual(a8._rev, doc8._rev);
assertEqual({"one": 1, "two": 2, "three": 3}, doc8.d);
assertEqual({}, doc8.e);
assertEqual({"one": 1}, doc8.f);
var a9 = db._update(a8, { d : { "four" : 4 }, "e" : { "e1" : [ 1, 2 ], "e2" : 2 }, "f" : { "three" : 3 }} );
assertEqual(a1._id, a9._id);
assertNotEqual(a8._rev, a9._rev);
var doc9 = db._document(a1._id);
assertEqual(a1._id, doc9._id);
assertEqual(a9._rev, doc9._rev);
assertEqual({"one": 1, "two": 2, "three": 3, "four": 4}, doc9.d);
assertEqual({"e2": 2, "e1": [ 1, 2 ]}, doc9.e);
assertEqual({"one": 1, "three": 3}, doc9.f);
var a10 = db._update(a9, { d : { "one" : -1, "two": null, "four" : null, "five" : 5 }, "e" : { "e1" : 1, "e2" : null, "e3" : 3 }}, {"overwrite": true, "keepNull": false});
assertEqual(a1._id, a10._id);
assertNotEqual(a9._rev, a10._rev);
var doc10 = db._document(a1._id);
assertEqual(a1._id, doc10._id);
assertEqual(a10._rev, doc10._rev);

View File

@ -1,4 +1,4 @@
/*jslint indent: 2, nomen: true, maxlen: 80, sloppy: true */
/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true */
/*global require, assertEqual, assertTrue, assertFalse, fail */
////////////////////////////////////////////////////////////////////////////////
@ -46,6 +46,20 @@ var _ = require("underscore");
function GeneralGraphCreationSuite() {
var rn = "UnitTestRelationName";
var rn1 = "UnitTestRelationName1";
var vn1 = "UnitTestVerticies1";
var vn2 = "UnitTestVerticies2";
var vn3 = "UnitTestVerticies3";
var vn4 = "UnitTestVerticies4";
var gn = "UnitTestGraph";
var edgeDef = graph._edgeDefinitions(
graph._undirectedRelationDefinition(rn, vn1),
graph._directedRelationDefinition(rn1,
[vn1, vn2], [vn3, vn4]
)
);
return {
////////////////////////////////////////////////////////////////////////////////
@ -53,215 +67,178 @@ function GeneralGraphCreationSuite() {
////////////////////////////////////////////////////////////////////////////////
test_undirectedRelationDefinition : function () {
var r;
try {
r = graph._undirectedRelationDefinition("relationName", ["vertexC1", "vertexC2"]);
}
catch (err) {
}
var r = graph._undirectedRelationDefinition(rn, [vn1, vn2]);
assertEqual(r, {
collection: "relationName",
from: ["vertexC1", "vertexC2"],
to: ["vertexC1", "vertexC2"]
collection: rn,
from: [vn1, vn2],
to: [vn1, vn2]
});
},
test_undirectedRelationDefinitionWithSingleCollection : function () {
var r;
try {
r = graph._undirectedRelationDefinition("relationName", "vertexC1");
}
catch (err) {
}
var r = graph._undirectedRelationDefinition(rn, vn1);
assertEqual(r, {
collection: "relationName",
from: ["vertexC1"],
to: ["vertexC1"]
collection: rn,
from: [vn1],
to: [vn1]
});
},
test_undirectedRelationDefinitionWithMissingName : function () {
var r, exception;
try {
r = graph._undirectedRelationDefinition("", ["vertexC1", "vertexC2"]);
graph._undirectedRelationDefinition("", [vn1, vn2]);
fail();
}
catch (err) {
exception = err;
assertEqual(err, "<relationName> must be a not empty string");
}
assertEqual(exception, "<relationName> must be a not empty string");
},
test_undirectedRelationDefinitionWithTooFewArgs : function () {
var r, exception;
try {
r = graph._undirectedRelationDefinition(["vertexC1", "vertexC2"]);
graph._undirectedRelationDefinition([vn1, vn2]);
fail();
}
catch (err) {
exception = err;
assertEqual(err, "method _undirectedRelationDefinition expects 2 arguments");
}
assertEqual(exception, "method _undirectedRelationDefinition expects 2 arguments");
},
test_undirectedRelationDefinitionWithInvalidSecondArg : function () {
var r, exception;
try {
r = graph._undirectedRelationDefinition("name", {"vertexC1" : "vertexC2"});
var param = {};
param[vn1] = vn2;
graph._undirectedRelationDefinition(rn, param);
fail();
}
catch (err) {
exception = err;
assertEqual(err, "<vertexCollections> must be a not empty string or array");
}
assertEqual(exception, "<vertexCollections> must be a not empty string or array");
},
test_directedRelationDefinition : function () {
var r;
try {
r = graph._directedRelationDefinition("relationName",
["vertexC1", "vertexC2"], ["vertexC3", "vertexC4"]);
}
catch (err) {
}
var r = graph._directedRelationDefinition(rn,
[vn1, vn2], [vn3, vn4]);
assertEqual(r, {
collection: "relationName",
from: ["vertexC1", "vertexC2"],
to: ["vertexC3", "vertexC4"]
collection: rn,
from: [vn1, vn2],
to: [vn3, vn4]
});
},
test_directedRelationDefinitionWithMissingName : function () {
var r, exception;
try {
r = graph._directedRelationDefinition("",
["vertexC1", "vertexC2"], ["vertexC3", "vertexC4"]);
graph._directedRelationDefinition("",
[vn1, vn2], [vn3, vn4]);
fail();
}
catch (err) {
exception = err;
assertEqual(err, "<relationName> must be a not empty string");
}
assertEqual(exception, "<relationName> must be a not empty string");
},
test_directedRelationDefinitionWithTooFewArgs : function () {
var r, exception;
try {
r = graph._directedRelationDefinition(["vertexC1", "vertexC2"], ["vertexC3", "vertexC4"]);
graph._directedRelationDefinition([vn1, vn2], [vn3, vn4]);
fail();
}
catch (err) {
exception = err;
assertEqual(err, "method _directedRelationDefinition expects 3 arguments");
}
assertEqual(exception, "method _directedRelationDefinition expects 3 arguments");
},
test_directedRelationDefinitionWithInvalidSecondArg : function () {
var r, exception;
try {
r = graph._directedRelationDefinition("name", {"vertexC1" : "vertexC2"}, "");
var param = {};
param[vn1] = vn2;
graph._directedRelationDefinition(rn, param, vn3);
fail();
}
catch (err) {
exception = err;
assertEqual(err, "<fromVertexCollections> must be a not empty string or array");
}
assertEqual(exception, "<fromVertexCollections> must be a not empty string or array");
},
test_directedRelationDefinitionWithInvalidThirdArg : function () {
var r, exception;
try {
r = graph._directedRelationDefinition("name", ["vertexC1", "vertexC2"], []);
var param = {};
param[vn1] = vn2;
graph._directedRelationDefinition(rn, vn3, param);
fail();
}
catch (err) {
exception = err;
assertEqual(err, "<toVertexCollections> must be a not empty string or array");
}
assertEqual(exception, "<toVertexCollections> must be a not empty string or array");
},
testEdgeDefinitions : function () {
//with empty args
assertEqual(graph.edgeDefinitions(), []);
assertEqual(graph._edgeDefinitions(), []);
//with args
assertEqual(graph.edgeDefinitions(
graph._undirectedRelationDefinition("relationName", "vertexC1"),
graph._directedRelationDefinition("relationName",
["vertexC1", "vertexC2"], ["vertexC3", "vertexC4"])
assertEqual(graph._edgeDefinitions(
graph._undirectedRelationDefinition(rn, vn1),
graph._directedRelationDefinition(rn1,
[vn1, vn2], [vn3, vn4])
), [
{
collection: "relationName",
from: ["vertexC1"],
to: ["vertexC1"]
collection: rn,
from: [vn1],
to: [vn1]
},
{
collection: "relationName",
from: ["vertexC1", "vertexC2"],
to: ["vertexC3", "vertexC4"]
collection: rn1,
from: [vn1, vn2],
to: [vn3, vn4]
}
]);
},
test_create : function () {
try {
arangodb.db._collection("_graphs").remove("_graphs/bla3")
} catch (err) {
if (db._collection("_graphs").exists(gn)) {
db._collection("_graphs").remove(gn);
}
var a = graph._create(
"bla3",
graph.edgeDefinitions(
graph._undirectedRelationDefinition("relationName", "vertexC1"),
graph._directedRelationDefinition("relationName2",
["vertexC1", "vertexC2"], ["vertexC3", "vertexC4"]
)
gn,
graph._edgeDefinitions(
graph._undirectedRelationDefinition(rn, vn1),
graph._directedRelationDefinition(rn1, [vn1, vn2], [vn3, vn4])
)
);
assertTrue(a.__vertexCollections.hasOwnProperty('vertexC1'));
assertTrue(a.__vertexCollections.hasOwnProperty('vertexC2'));
assertTrue(a.__vertexCollections.hasOwnProperty('vertexC3'));
assertTrue(a.__vertexCollections.hasOwnProperty('vertexC4'));
assertTrue(a.__edgeCollections.hasOwnProperty('relationName'));
assertTrue(a.__edgeCollections.hasOwnProperty('relationName2'));
assertTrue(a.__vertexCollections.hasOwnProperty(vn1));
assertTrue(a.__vertexCollections.hasOwnProperty(vn2));
assertTrue(a.__vertexCollections.hasOwnProperty(vn3));
assertTrue(a.__vertexCollections.hasOwnProperty(vn4));
assertTrue(a.__edgeCollections.hasOwnProperty(rn));
assertTrue(a.__edgeCollections.hasOwnProperty(rn1));
assertEqual(a.__edgeDefinitions, [
{
"collection" : "relationName",
"collection" : rn,
"from" : [
"vertexC1"
vn1
],
"to" : [
"vertexC1"
vn1
]
},
{
"collection" : "relationName2",
"collection" : rn1,
"from" : [
"vertexC1",
"vertexC2"
vn1,
vn2
],
"to" : [
"vertexC3",
"vertexC4"
vn3,
vn4
]
}
]
@ -269,126 +246,79 @@ function GeneralGraphCreationSuite() {
},
test_create_WithOut_EdgeDefiniton : function () {
var msg;
try {
arangodb.db._collection("_graphs").remove("_graphs/bla3")
} catch (err) {
if (db._collection("_graphs").exists(gn)) {
db._collection("_graphs").remove(gn);
}
try {
var a = graph._create(
"bla3",
graph._create(
gn,
[]
);
fail();
} catch (err) {
msg = err;
assertEqual(err, "at least one edge definition is required to create a graph.");
}
assertEqual(msg, "at least one edge definition is required to create a graph.");
},
test_create_WithOut_Name : function () {
var msg;
try {
arangodb.db._collection("_graphs").remove("_graphs/bla3")
} catch (err) {
if (db._collection("_graphs").exists(gn)) {
db._collection("_graphs").remove(gn);
}
try {
var a = graph._create(
graph._create(
"",
graph.edgeDefinitions(
graph._undirectedRelationDefinition("relationName", "vertexC1"),
graph._directedRelationDefinition("relationName2",
["vertexC1", "vertexC2"], ["vertexC3", "vertexC4"]
)
)
edgeDef
);
fail();
} catch (err) {
msg = err;
assertEqual(err, "a graph name is required to create a graph.");
}
assertEqual(msg, "a graph name is required to create a graph.");
},
test_create_With_Already_Existing_Graph : function () {
try {
arangodb.db._collection("_graphs").remove("_graphs/bla3")
} catch (err) {
if (db._collection("_graphs").exists(gn)) {
db._collection("_graphs").remove(gn);
}
graph._create(
"bla3",
graph.edgeDefinitions(
graph._undirectedRelationDefinition("relationName", "vertexC1"),
graph._directedRelationDefinition("relationName2",
["vertexC1", "vertexC2"], ["vertexC3", "vertexC4"]
)
)
);
var msg;
graph._create(gn, edgeDef);
try {
var a = graph._create(
"bla3",
graph.edgeDefinitions(
graph._undirectedRelationDefinition("relationName", "vertexC1"),
graph._directedRelationDefinition("relationName2",
["vertexC1", "vertexC2"], ["vertexC3", "vertexC4"]
)
)
);
graph._create(gn, edgeDef);
} catch (err) {
msg = err;
assertEqual(err, "graph " + gn + " already exists.");
}
assertEqual(msg, "graph bla3 already exists.");
},
test_get_graph : function () {
try {
arangodb.db._collection("_graphs").remove("_graphs/bla3")
} catch (err) {
if (db._collection("_graphs").exists(gn)) {
db._collection("_graphs").remove(gn);
}
graph._create(
"bla3",
graph.edgeDefinitions(
graph._undirectedRelationDefinition("relationName", "vertexC1"),
graph._directedRelationDefinition("relationName2",
["vertexC1", "vertexC2"], ["vertexC3", "vertexC4"]
)
)
);
graph._create(gn, edgeDef);
var a = graph._graph(gn);
var a = graph._graph("bla3");
assertTrue(a.__vertexCollections.hasOwnProperty('vertexC1'));
assertTrue(a.__vertexCollections.hasOwnProperty('vertexC2'));
assertTrue(a.__vertexCollections.hasOwnProperty('vertexC3'));
assertTrue(a.__vertexCollections.hasOwnProperty('vertexC4'));
assertTrue(a.__edgeCollections.hasOwnProperty('relationName'));
assertTrue(a.__edgeCollections.hasOwnProperty('relationName2'));
assertTrue(a.__vertexCollections.hasOwnProperty(vn1));
assertTrue(a.__vertexCollections.hasOwnProperty(vn2));
assertTrue(a.__vertexCollections.hasOwnProperty(vn3));
assertTrue(a.__vertexCollections.hasOwnProperty(vn4));
assertTrue(a.__edgeCollections.hasOwnProperty(rn));
assertTrue(a.__edgeCollections.hasOwnProperty(rn1));
assertEqual(a.__edgeDefinitions, [
{
"collection" : "relationName",
"collection" : rn,
"from" : [
"vertexC1"
vn1
],
"to" : [
"vertexC1"
vn1
]
},
{
"collection" : "relationName2",
"collection" : rn1,
"from" : [
"vertexC1",
"vertexC2"
vn1,
vn2
],
"to" : [
"vertexC3",
"vertexC4"
vn3,
vn4
]
}
]
@ -396,13 +326,52 @@ function GeneralGraphCreationSuite() {
},
test_get_graph_without_hit : function () {
var msg;
try {
var a = graph._graph("bla4");
graph._graph(gn + "UnknownExtension");
fail();
} catch (e) {
msg = e;
assertEqual(e, "graph " + gn + "UnknownExtension" + " does not exists.");
}
assertEqual(msg, "graph bla4 does not exists.");
},
test_creationOfGraphShouldNotAffectCollections: function() {
if(graph._exists(gn)) {
graph._drop(gn);
}
var edgeDef2 = [graph._directedRelationDefinition(rn, vn1, vn2)];
var g = graph._create(gn, edgeDef2);
var v1 = g[vn1].save({_key: "1"})._id;
var v2 = g[vn2].save({_key: "2"})._id;
var v3 = g[vn1].save({_key: "3"})._id;
g[rn].save(v1, v2, {});
assertEqual(g[vn1].count(), 2);
assertEqual(g[vn2].count(), 1);
assertEqual(g[rn].count(), 1);
try {
g[rn].save(v2, v3, {});
fail();
} catch (e) {
// This should create an error
assertEqual(g[rn].count(), 1);
}
try {
db[rn].save(v2, v3, {});
} catch (e) {
// This should not create an error
fail();
}
assertEqual(g[rn].count(), 2);
db[vn2].remove(v2);
// This should not remove edges
assertEqual(g[rn].count(), 2);
g[vn1].remove(v1);
// This should remove edges
assertEqual(g[rn].count(), 1);
graph._drop(gn, true);
}
};
@ -679,7 +648,6 @@ function GeneralGraphAQLQueriesSuite() {
test_filterOnOutEdges: function() {
var query = g._outEdges(v1 + "/1").filter({val: true});
// var query = g._outEdges("v1/1").filter("e.val = true");
assertEqual(query.printQuery(), "FOR edges_0 IN GRAPH_EDGES("
+ '@graphName,@startVertex_0,"outbound") '
+ 'FILTER MATCHES(edges_0,[{"val":true}])');
@ -691,7 +659,96 @@ function GeneralGraphAQLQueriesSuite() {
assertTrue(findIdInResult(result, e1), "Did not include e1");
assertFalse(findIdInResult(result, e2), "e2 is not excluded");
assertFalse(findIdInResult(result, e3), "e3 is not excluded");
}
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test: counting of query results
////////////////////////////////////////////////////////////////////////////////
test_queryCount: function() {
var query = g._edges(v1 + "/1");
assertEqual(query.count(), 3);
query = g._inEdges(v1 + "/1").filter({val: true});
assertEqual(query.count(), 0);
query = g._outEdges(v1 + "/1").filter({val: true});
assertEqual(query.count(), 1);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test: Cursor iteration
////////////////////////////////////////////////////////////////////////////////
test_cursorIteration: function() {
var query = g._edges(v1 + "/1");
var list = [e1, e2, e3];
var next;
assertTrue(query.hasNext());
next = query.next();
list = _.without(list, next._id);
assertEqual(list.length, 2);
assertTrue(query.hasNext());
next = query.next();
list = _.without(list, next._id);
assertEqual(list.length, 1);
assertTrue(query.hasNext());
next = query.next();
list = _.without(list, next._id);
assertEqual(list.length, 0);
assertFalse(query.hasNext());
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test: Cursor recreation after iteration
////////////////////////////////////////////////////////////////////////////////
test_cursorIterationAndRecreation: function() {
var query = g._edges(v1 + "/1");
var list = [e1, e2, e3];
var next;
assertTrue(query.hasNext());
next = query.next();
list = _.without(list, next._id);
assertEqual(list.length, 2);
assertTrue(query.hasNext());
next = query.next();
list = _.without(list, next._id);
assertEqual(list.length, 1);
assertTrue(query.hasNext());
next = query.next();
list = _.without(list, next._id);
assertEqual(list.length, 0);
assertFalse(query.hasNext());
query = query.filter({val: true});
list = [e1];
assertTrue(query.hasNext());
next = query.next();
list = _.without(list, next._id);
assertEqual(list.length, 0);
assertFalse(query.hasNext());
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test: Is cursor recreated after counting of query results and appending filter
////////////////////////////////////////////////////////////////////////////////
test_cursorRecreationAfterCount: function() {
var query = g._edges(v1 + "/1");
assertEqual(query.count(), 3);
query = query.filter({val: true});
assertEqual(query.count(), 1);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test: Is cursor recreated after to array of query results and appending filter
////////////////////////////////////////////////////////////////////////////////
test_cursorRecreationAfterToArray: function() {
var query = g._edges(v1 + "/1");
var result = query.toArray();
assertTrue(findIdInResult(result, e1), "Did not include e1");
assertTrue(findIdInResult(result, e2), "Did not include e2");
assertTrue(findIdInResult(result, e3), "Did not include e3");
query = query.filter({val: true});
result = query.toArray();
assertTrue(findIdInResult(result, e1), "Did not include e1");
assertFalse(findIdInResult(result, e2), "e2 is not excluded");
assertFalse(findIdInResult(result, e3), "e3 is not excluded");
}
////////////////////////////////////////////////////////////////////////////////
/// @brief test: let construct on edges
@ -727,6 +784,7 @@ function EdgesAndVerticesSuite() {
var vertexIds = [];
var vertexId1, vertexId2;
var edgeId1, edgeId2;
var unitTestGraphName = "unitTestGraph";
fillCollections = function() {
var ids = {};
@ -784,12 +842,12 @@ function EdgesAndVerticesSuite() {
setUp : function() {
try {
arangodb.db._collection("_graphs").remove("_graphs/unitTestGraph")
arangodb.db._collection("_graphs").remove("_graphs/" + unitTestGraphName)
} catch (err) {
}
g = graph._create(
"unitTestGraph",
graph.edgeDefinitions(
unitTestGraphName,
graph._edgeDefinitions(
graph._undirectedRelationDefinition("unitTestEdgeCollection1", "unitTestVertexCollection1"),
graph._directedRelationDefinition("unitTestEdgeCollection2",
["unitTestVertexCollection1", "unitTestVertexCollection2"], ["unitTestVertexCollection3", "unitTestVertexCollection4"]
@ -799,12 +857,23 @@ function EdgesAndVerticesSuite() {
},
tearDown : function() {
db.unitTestVertexCollection1.drop();
db.unitTestVertexCollection2.drop();
db.unitTestVertexCollection3.drop();
db.unitTestVertexCollection4.drop();
db.unitTestEdgeCollection1.drop();
db.unitTestEdgeCollection2.drop();
graph._drop(unitTestGraphName);
},
test_dropGraph : function () {
var myGraphName = unitTestGraphName + "2";
var myEdgeColName = "unitTestEdgeCollection1";
var myVertexColName = "unitTestVertexCollection4711";
graph._create(
myGraphName,
graph._edgeDefinitions(
graph._undirectedRelationDefinition(myEdgeColName, myVertexColName)
)
);
graph._drop(myGraphName);
assertFalse(graph._exists(myGraphName));
assertTrue(db._collection(myVertexColName) === null);
assertTrue(db._collection(myEdgeColName) !== null);
},
test_edgeCollections : function () {
@ -853,8 +922,8 @@ function EdgesAndVerticesSuite() {
test_vC_remove : function () {
var vertex = g.unitTestVertexCollection1.save({first_name: "Tim"});
var vertexId = vertex._id;
var vertex = g.unitTestVertexCollection1.remove(vertexId);
assertTrue(vertex);
var result = g.unitTestVertexCollection1.remove(vertexId);
assertTrue(result);
},
test_vC_removeWithEdge : function () {

View File

@ -3971,13 +3971,11 @@ function DATE_MILLISECOND (value) {
// --SECTION-- graph functions
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief find all paths through a graph, INTERNAL part called recursively
////////////////////////////////////////////////////////////////////////////////
function GET_SUB_EDGES (edgeCollections, direction, vertexId) {
if (!Array.isArray(edgeCollections)) {
edgeCollections = [edgeCollections];
}
@ -3994,11 +3992,10 @@ function GET_SUB_EDGES (edgeCollections, direction, vertexId) {
result = result.concat(edgeCollection.edges(vertexId));
}
});
return result;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief find all paths through a graph, INTERNAL part called recursively
////////////////////////////////////////////////////////////////////////////////
@ -4136,7 +4133,6 @@ function GRAPH_PATHS (vertices, edgeCollection, direction, followCycles, minLeng
return result;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief find all paths through a graph
////////////////////////////////////////////////////////////////////////////////
@ -4150,7 +4146,6 @@ function GENERAL_GRAPH_PATHS (graphname, direction, followCycles, minLength, max
minLength = minLength || 0;
maxLength = maxLength !== undefined ? maxLength : 10;
// check graph exists and load edgeDefintions
var graph = DOCUMENT_HANDLE("_graphs/" + graphname);
if (!graph) {
@ -4232,8 +4227,6 @@ function GENERAL_GRAPH_PATHS (graphname, direction, followCycles, minLength, max
return result;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief visitor callback function for traversal
////////////////////////////////////////////////////////////////////////////////
@ -4329,7 +4322,6 @@ function TRAVERSAL_CHECK_EXAMPLES_TYPEWEIGHTS (examples, func) {
});
}
////////////////////////////////////////////////////////////////////////////////
/// @brief tranform key to id
////////////////////////////////////////////////////////////////////////////////
@ -4337,17 +4329,17 @@ function TRAVERSAL_CHECK_EXAMPLES_TYPEWEIGHTS (examples, func) {
function TO_ID (vertex, collection) {
"use strict";
if (vertex === 'object' && vertex.hasOwnProperty('_id')) {
return vertex._id;
if (typeof vertex === 'object' && vertex.hasOwnProperty('_id')) {
return vertex._id;
}
if (vertex.indexOf('/') === -1 && collection) {
return collection + '/' + vertex;
if (typeof vertex === 'string' && vertex.indexOf('/') === -1 && collection) {
return collection + '/' + vertex;
}
return vertex;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief traverse a graph
////////////////////////////////////////////////////////////////////////////////
@ -4456,19 +4448,15 @@ function TRAVERSAL_FUNC (func,
return result;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief shortest path algorithm
////////////////////////////////////////////////////////////////////////////////
function GRAPH_SHORTEST_PATH (vertexCollection,
edgeCollection,
startVertex,
endVertex,
direction,
params) {
"use strict";
////////////////////////////////////////////////////////////////////////////////
/// @brief helper function to determine parameters for SHORTEST_PATH and
/// GRAPH_SHORTEST_PATH
////////////////////////////////////////////////////////////////////////////////
function SHORTEST_PATH_PARAMS (params) {
"use strict";
if (params === undefined) {
params = { };
}
@ -4488,6 +4476,23 @@ function GRAPH_SHORTEST_PATH (vertexCollection,
params.distance = undefined;
}
return params;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief shortest path algorithm
////////////////////////////////////////////////////////////////////////////////
function GRAPH_SHORTEST_PATH (vertexCollection,
edgeCollection,
startVertex,
endVertex,
direction,
params) {
"use strict";
params = SHORTEST_PATH_PARAMS(params);
return TRAVERSAL_FUNC("SHORTEST_PATH",
TRAVERSAL.collectionDatasourceFactory(COLLECTION(edgeCollection)),
TO_ID(startVertex, vertexCollection),
@ -4501,32 +4506,15 @@ function GRAPH_SHORTEST_PATH (vertexCollection,
////////////////////////////////////////////////////////////////////////////////
function GENERAL_GRAPH_SHORTEST_PATH (graphName,
startVertex,
endVertex,
direction,
params) {
startVertex,
endVertex,
direction,
params) {
"use strict";
if (params === undefined) {
params = { };
}
params = SHORTEST_PATH_PARAMS(params);
params.strategy = "dijkstra";
params.itemorder = "forward";
params.visitor = TRAVERSAL_VISITOR;
if (typeof params.distance === "string") {
var name = params.distance.toUpperCase();
params.distance = function (config, vertex1, vertex2, edge) {
return FCALL_USER(name, [ config, vertex1, vertex2, edge ]);
};
}
else {
params.distance = undefined;
}
return TRAVERSAL_FUNC("SHORTEST_PATH",
return TRAVERSAL_FUNC("GRAPH_SHORTEST_PATH",
TRAVERSAL.generalGraphDatasourceFactory(graphName),
TO_ID(startVertex),
TO_ID(endVertex),
@ -4534,6 +4522,21 @@ function GENERAL_GRAPH_SHORTEST_PATH (graphName,
params);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief helper function to determine parameters for TRAVERSAL and
/// GRAPH_TRAVERSAL
////////////////////////////////////////////////////////////////////////////////
function TRAVERSAL_PARAMS (params) {
"use strict";
if (params === undefined) {
params = { };
}
params.visitor = TRAVERSAL_VISITOR;
return params;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief traverse a graph
@ -4545,12 +4548,8 @@ function GRAPH_TRAVERSAL (vertexCollection,
direction,
params) {
"use strict";
if (params === undefined) {
params = { };
}
params.visitor = TRAVERSAL_VISITOR;
params = TRAVERSAL_PARAMS(params);
return TRAVERSAL_FUNC("TRAVERSAL",
TRAVERSAL.collectionDatasourceFactory(COLLECTION(edgeCollection)),
@ -4560,7 +4559,6 @@ function GRAPH_TRAVERSAL (vertexCollection,
params);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief traverse a graph
////////////////////////////////////////////////////////////////////////////////
@ -4571,13 +4569,9 @@ function GENERAL_GRAPH_TRAVERSAL (graphName,
params) {
"use strict";
if (params === undefined) {
params = { };
}
params = TRAVERSAL_PARAMS(params);
params.visitor = TRAVERSAL_VISITOR;
return TRAVERSAL_FUNC("TRAVERSAL",
return TRAVERSAL_FUNC("GRAPH_TRAVERSAL",
TRAVERSAL.generalGraphDatasourceFactory(graphName),
TO_ID(startVertex),
undefined,
@ -4585,6 +4579,27 @@ function GENERAL_GRAPH_TRAVERSAL (graphName,
params);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief helper function to determine parameters for TRAVERSAL_TREE and
/// GRAPH_TRAVERSAL_TREE
////////////////////////////////////////////////////////////////////////////////
function TRAVERSAL_TREE_PARAMS (params, connectName, funcName) {
"use strict";
if (params === undefined) {
params = { };
}
params.visitor = TRAVERSAL_TREE_VISITOR;
params.connect = connectName;
if (params.connect === "") {
THROW(INTERNAL.errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, funcName);
}
return params;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief traverse a graph and create a hierarchical result
@ -4600,16 +4615,7 @@ function GRAPH_TRAVERSAL_TREE (vertexCollection,
params) {
"use strict";
if (connectName === "") {
THROW(INTERNAL.errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "TRAVERSAL_TREE");
}
if (params === undefined) {
params = { };
}
params.visitor = TRAVERSAL_TREE_VISITOR;
params.connect = connectName;
params = TRAVERSAL_TREE_PARAMS(params, connectName, "TRAVERSAL_TREE");
var result = TRAVERSAL_FUNC("TRAVERSAL_TREE",
TRAVERSAL.collectionDatasourceFactory(COLLECTION(edgeCollection)),
@ -4631,24 +4637,15 @@ function GRAPH_TRAVERSAL_TREE (vertexCollection,
////////////////////////////////////////////////////////////////////////////////
function GENERAL_GRAPH_TRAVERSAL_TREE (graphName,
startVertex,
direction,
connectName,
params) {
startVertex,
direction,
connectName,
params) {
"use strict";
if (connectName === "") {
THROW(INTERNAL.errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "TRAVERSAL_TREE");
}
params = TRAVERSAL_TREE_PARAMS(params, connectName, "GRAPH_TRAVERSAL_TREE");
if (params === undefined) {
params = { };
}
params.visitor = TRAVERSAL_TREE_VISITOR;
params.connect = connectName;
var result = TRAVERSAL_FUNC("TRAVERSAL_TREE",
var result = TRAVERSAL_FUNC("GRAPH_TRAVERSAL_TREE",
TRAVERSAL.generalGraphDatasourceFactory(graphName),
TO_ID(startVertex),
undefined,
@ -4661,7 +4658,6 @@ function GENERAL_GRAPH_TRAVERSAL_TREE (graphName,
return [ result[0][params.connect] ];
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return connected edges
////////////////////////////////////////////////////////////////////////////////
@ -4772,73 +4768,12 @@ function GENERAL_GRAPH_EDGES (
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return connected neighbors
/// @brief helper function to filter edges based on examples
////////////////////////////////////////////////////////////////////////////////
function GRAPH_NEIGHBORS (vertexCollection,
edgeCollection,
vertex,
direction,
examples) {
function FILTERED_EDGES (edges, vertex, direction, examples) {
"use strict";
var c = COLLECTION(vertexCollection);
if (typeof vertex === 'object' && vertex.hasOwnProperty('_id')) {
vertex = vertex._id;
}
if (vertex.indexOf('/') === -1) {
vertex = vertexCollection + '/' + vertex;
}
var edges = GRAPH_EDGES(edgeCollection, vertex, direction);
var result = [ ];
FILTER(edges, examples).forEach (function (e) {
var key;
if (direction === "inbound") {
key = e._from;
}
else if (direction === "outbound") {
key = e._to;
}
else if (direction === "any") {
key = e._from;
if (key === vertex) {
key = e._to;
}
}
if (key === vertex) {
// do not return the start vertex itself
return;
}
try {
result.push({ edge: CLONE(e), vertex: c.document(key) });
}
catch (err) {
}
});
return result;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return connected neighbors
////////////////////////////////////////////////////////////////////////////////
function GENERAL_GRAPH_NEIGHBORS (graphName,
vertex,
direction,
examples) {
"use strict";
var edges = GENERAL_GRAPH_EDGES(graphName, TO_ID(vertex), direction);
var result = [ ];
FILTER(edges, examples).forEach (function (e) {
@ -4872,6 +4807,36 @@ function GENERAL_GRAPH_NEIGHBORS (graphName,
return result;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return connected neighbors
////////////////////////////////////////////////////////////////////////////////
function GRAPH_NEIGHBORS (vertexCollection,
edgeCollection,
vertex,
direction,
examples) {
"use strict";
vertex = TO_ID(vertex, vertexCollection);
var edges = GRAPH_EDGES(edgeCollection, vertex, direction);
return FILTERED_EDGES(edges, vertex, direction, examples);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return connected neighbors
////////////////////////////////////////////////////////////////////////////////
function GENERAL_GRAPH_NEIGHBORS (graphName,
vertex,
direction,
examples) {
"use strict";
vertex = TO_ID(vertex);
var edges = GENERAL_GRAPH_EDGES(graphName, vertex, direction);
return FILTERED_EDGES(edges, vertex, direction, examples);
}
// -----------------------------------------------------------------------------
// --SECTION-- MODULE EXPORTS