1
0
Fork 0

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

Conflicts:
	js/common/modules/org/arangodb/general-graph.js
This commit is contained in:
Michael Hackstein 2014-05-21 09:55:37 +02:00
commit 27474a7960
9 changed files with 181 additions and 127 deletions

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

@ -705,6 +705,7 @@ TRI_associative_pointer_t* TRI_CreateFunctionsAql (void) {
REGISTER_FUNCTION("PATHS", "GRAPH_PATHS", false, false, "c,h|s,b", &OptimisePaths);
REGISTER_FUNCTION("GRAPH_PATHS", "GENERAL_GRAPH_PATHS", false, false, "s|s,b,n,n", &OptimisePaths);
REGISTER_FUNCTION("SHORTEST_PATH", "GRAPH_SHORTEST_PATH", false, false, "h,h,s,s,s|a", NULL);
REGISTER_FUNCTION("GRAPH_SHORTEST_PATH", "GENERAL_GRAPH_SHORTEST_PATH", false, false, "s,s,s,s|a", NULL);
REGISTER_FUNCTION("TRAVERSAL", "GRAPH_TRAVERSAL", false, false, "h,h,s,s|a", NULL);
REGISTER_FUNCTION("GRAPH_TRAVERSAL", "GENERAL_GRAPH_TRAVERSAL", false, false, "s,s,s|a", NULL);
REGISTER_FUNCTION("TRAVERSAL_TREE", "GRAPH_TRAVERSAL_TREE", false, false, "h,h,s,s,s|a", NULL);
@ -712,6 +713,7 @@ TRI_associative_pointer_t* TRI_CreateFunctionsAql (void) {
REGISTER_FUNCTION("EDGES", "GRAPH_EDGES", false, false, "h,s,s|l", NULL);
REGISTER_FUNCTION("GRAPH_EDGES", "GENERAL_GRAPH_EDGES", false, false, "s,s,s|lza,ls", NULL);
REGISTER_FUNCTION("NEIGHBORS", "GRAPH_NEIGHBORS", false, false, "h,h,s,s|l", NULL);
REGISTER_FUNCTION("GRAPH_NEIGHBORS", "GENERAL_GRAPH_NEIGHBORS", false, false, "s,s,s|l", NULL);
// date functions
REGISTER_FUNCTION("DATE_NOW", "DATE_NOW", false, false, "", NULL); // NOW is non-deterministic

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

@ -424,6 +424,10 @@ var Graph = function(graphName, edgeDefinitions, vertexCollections, edgeCollecti
}
}
);
if (options === null || options === undefined) {
return old_remove(vertexId);
}
return old_remove(vertexId, options);
};
self[key] = wrap;

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),
@ -4495,7 +4500,44 @@ function GRAPH_SHORTEST_PATH (vertexCollection,
direction,
params);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief shortest path algorithm
////////////////////////////////////////////////////////////////////////////////
function GENERAL_GRAPH_SHORTEST_PATH (graphName,
startVertex,
endVertex,
direction,
params) {
"use strict";
params = SHORTEST_PATH_PARAMS(params);
return TRAVERSAL_FUNC("GRAPH_SHORTEST_PATH",
TRAVERSAL.generalGraphDatasourceFactory(graphName),
TO_ID(startVertex),
TO_ID(endVertex),
direction,
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
////////////////////////////////////////////////////////////////////////////////
@ -4506,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)),
@ -4521,7 +4559,6 @@ function GRAPH_TRAVERSAL (vertexCollection,
params);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief traverse a graph
////////////////////////////////////////////////////////////////////////////////
@ -4532,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,
@ -4546,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
@ -4561,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)),
@ -4592,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,
@ -4622,7 +4658,6 @@ function GENERAL_GRAPH_TRAVERSAL_TREE (graphName,
return [ result[0][params.connect] ];
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return connected edges
////////////////////////////////////////////////////////////////////////////////
@ -4733,29 +4768,14 @@ 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;
@ -4778,14 +4798,45 @@ function GRAPH_NEIGHBORS (vertexCollection,
}
try {
result.push({ edge: CLONE(e), vertex: c.document(key) });
result.push({ edge: CLONE(e), vertex: DOCUMENT_HANDLE(key) });
}
catch (err) {
}
});
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
@ -4892,6 +4943,7 @@ exports.GEO_WITHIN = GEO_WITHIN;
exports.FULLTEXT = FULLTEXT;
exports.GRAPH_PATHS = GRAPH_PATHS;
exports.GRAPH_SHORTEST_PATH = GRAPH_SHORTEST_PATH;
exports.GENERAL_GRAPH_SHORTEST_PATH = GENERAL_GRAPH_SHORTEST_PATH;
exports.GRAPH_TRAVERSAL = GRAPH_TRAVERSAL;
exports.GRAPH_TRAVERSAL_TREE = GRAPH_TRAVERSAL_TREE;
exports.GENERAL_GRAPH_TRAVERSAL = GENERAL_GRAPH_TRAVERSAL;
@ -4900,6 +4952,7 @@ exports.GRAPH_EDGES = GRAPH_EDGES;
exports.GENERAL_GRAPH_EDGES = GENERAL_GRAPH_EDGES;
exports.GENERAL_GRAPH_PATHS = GENERAL_GRAPH_PATHS;
exports.GRAPH_NEIGHBORS = GRAPH_NEIGHBORS;
exports.GENERAL_GRAPH_NEIGHBORS = GENERAL_GRAPH_NEIGHBORS;
exports.NOT_NULL = NOT_NULL;
exports.FIRST_LIST = FIRST_LIST;
exports.FIRST_DOCUMENT = FIRST_DOCUMENT;

View File

@ -113,7 +113,7 @@ function ahuacatlQueryGeneralEdgesTestSuite() {
},
////////////////////////////////////////////////////////////////////////////////
/// @brief checks EDGES()
/// @brief checks GRAPH_EDGES() and GRAPH_NEIGHBOURS()
////////////////////////////////////////////////////////////////////////////////
testEdgesAny: function () {
@ -128,6 +128,9 @@ function ahuacatlQueryGeneralEdgesTestSuite() {
actual = getQueryResults("FOR e IN GRAPH_EDGES('bla3', 'UnitTestsAhuacatlVertex1/v1', 'any' , [{'what' : 'v2->v1'}]) SORT e.what RETURN e.what");
assertEqual(actual, [ "v2->v1" ]);
actual = getQueryResults("FOR e IN GRAPH_NEIGHBORS('bla3', 'UnitTestsAhuacatlVertex1/v1', 'any' , [{'what' : 'v2->v1'}]) SORT e.what RETURN e");
assertEqual(actual[0].edge.what , "v2->v1");
assertEqual(actual[0].vertex._key , "v2");
},
////////////////////////////////////////////////////////////////////////////////
@ -145,6 +148,10 @@ function ahuacatlQueryGeneralEdgesTestSuite() {
actual = getQueryResults("FOR e IN GRAPH_EDGES('bla3', 'UnitTestsAhuacatlVertex3/v5', 'inbound' , [{'what' : 'v2->v5'}]) SORT e.what RETURN e.what");
assertEqual(actual, [ "v2->v5" ]);
actual = getQueryResults("FOR e IN GRAPH_NEIGHBORS('bla3', 'UnitTestsAhuacatlVertex3/v5', 'inbound' , [{'what' : 'v2->v5'}]) SORT e.what RETURN e");
assertEqual(actual[0].edge.what , "v2->v5");
assertEqual(actual[0].vertex._key , "v2");
},
@ -163,6 +170,12 @@ function ahuacatlQueryGeneralEdgesTestSuite() {
actual = getQueryResults("FOR e IN GRAPH_EDGES('bla3', 'UnitTestsAhuacatlVertex1/v1', 'outbound' , [{'what' : 'v2->v5'}]) SORT e.what RETURN e.what");
assertEqual(actual, []);
actual = getQueryResults("FOR e IN GRAPH_NEIGHBORS('bla3', 'UnitTestsAhuacatlVertex1/v1', 'outbound') SORT e.what RETURN e");
assertEqual(actual[0].edge.what , "v1->v2");
assertEqual(actual[0].vertex._key , "v2");
assertEqual(actual[1].edge.what , "v1->v5");
assertEqual(actual[1].vertex._key , "v5");
},
////////////////////////////////////////////////////////////////////////////////
@ -353,7 +366,7 @@ function ahuacatlQueryGeneralPathsTestSuite() {
////////////////////////////////////////////////////////////////////////////////
/// @brief test suite for GRAPH_TRAVERSAL() function
/// @brief test suite for GRAPH_TRAVERSAL() and GRAPH_SHORTEST_PATH function
////////////////////////////////////////////////////////////////////////////////
function ahuacatlQueryGeneralTraversalTestSuite() {
@ -494,6 +507,23 @@ function ahuacatlQueryGeneralTraversalTestSuite() {
assertTrue(middle.connected.length === 1);
assertEqual(middle.connected[0]._key, "Fritz");
},
testGRAPH_SHORTEST_PATH: function () {
var actual, result= [];
actual = getQueryResults("FOR e IN GRAPH_SHORTEST_PATH('werKenntWen', 'UnitTests_Hamburger/Caesar', 'UnitTests_Frankfurter/Emil', 'outbound') RETURN e");
actual.forEach(function (s) {
result.push(s.vertex._key);
});
assertEqual(result, [
"Caesar",
"Berta",
"Gerda",
"Dieter",
"Emil"
]);
}
}
}