1
0
Fork 0

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

This commit is contained in:
Max Neunhoeffer 2014-05-20 13:25:10 +02:00
commit 464b6720ca
17 changed files with 866 additions and 244 deletions

View File

@ -36,7 +36,17 @@ Please use the
@EXTREF_S{https://github.com/mgiken/portage-overlay/tree/master/dev-db/ArangoDB,portage}
provided by @@mgiken.
### Linux-Mint {#InstallingDebian}
### Debian sid {#InstallingDebian}
To use ArangoDB on Debian sid (the development version of Debian), a different version
of ICU is required. User basir provided the following instructions for getting ArangoDB 2.0.7
to work on an x86_64:
@EXTREF_S{https://github.com/triAGENS/ArangoDB/issues/865,link to Github issue}
Other versions of ArangoDB or other architectures should work similarly.
### Linux-Mint {#InstallingLinuxMint}
Download and import GPG-PublicKey:

View File

@ -5,6 +5,7 @@ TOC {#InstallingTOC}
- @ref InstallingLinux
- @ref InstallingLinuxPackageManager
- @ref InstallingDebian
- @ref InstallingLinuxMint
- @ref InstallingMacOSX
- @ref InstallingMacOSXHomebrew
- @ref InstallingMacOSXAppStore

View File

@ -121,32 +121,6 @@ BOOST_AUTO_TEST_CASE (tst_df_footer_marker) {
BOOST_CHECK_EQUAL(28, offsetof(struct TRI_df_footer_marker_s, _totalSize));
}
////////////////////////////////////////////////////////////////////////////////
/// @brief test sizeof TRI_df_document_marker_t
////////////////////////////////////////////////////////////////////////////////
BOOST_AUTO_TEST_CASE (tst_df_document_marker) {
size_t s = sizeof(TRI_df_document_marker_t);
BOOST_CHECK_EQUAL(24, s); // base + own size
BOOST_CHECK_EQUAL(true, s % 8 == 0);
BOOST_CHECK_EQUAL( 0, offsetof(struct TRI_df_document_marker_s, base));
}
////////////////////////////////////////////////////////////////////////////////
/// @brief test sizeof TRI_df_skip_marker_t
////////////////////////////////////////////////////////////////////////////////
BOOST_AUTO_TEST_CASE (tst_df_skip_marker) {
size_t s = sizeof(TRI_df_skip_marker_t);
BOOST_CHECK_EQUAL(24, s); // base + own size
BOOST_CHECK_EQUAL(true, s % 8 == 0);
BOOST_CHECK_EQUAL( 0, offsetof(struct TRI_df_skip_marker_s, base));
}
////////////////////////////////////////////////////////////////////////////////
/// @brief test sizeof TRI_col_header_marker_t
////////////////////////////////////////////////////////////////////////////////

View File

@ -415,15 +415,6 @@ typedef struct TRI_df_document_marker_s {
}
TRI_df_document_marker_t;
////////////////////////////////////////////////////////////////////////////////
/// @brief datafile skip marker
////////////////////////////////////////////////////////////////////////////////
typedef struct TRI_df_skip_marker_s {
TRI_df_marker_t base; // 24 bytes
}
TRI_df_skip_marker_t;
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

View File

@ -30,6 +30,7 @@ module.define("org/arangodb/graph/traversal", function(exports, module) {
////////////////////////////////////////////////////////////////////////////////
var graph = require("org/arangodb/graph-blueprint");
var generalGraph = require("org/arangodb/general-graph");
var arangodb = require("org/arangodb");
var BinaryHeap = require("org/arangodb/heap").BinaryHeap;
var ArangoError = arangodb.ArangoError;
@ -159,6 +160,72 @@ function collectionDatasourceFactory (edgeCollection) {
};
}
////////////////////////////////////////////////////////////////////////////////
/// @brief general graph datasource
///
/// This is a factory function that creates a datasource that operates on the
/// specified general graph. The vertices and edges are delivered by the
/// the general-graph module.
////////////////////////////////////////////////////////////////////////////////
function generalGraphDatasourceFactory (graph) {
var g = graph;
if (typeof g === 'string') {
g = generalGraph._graph(g);
}
return {
graph: g,
getVertexId: function (vertex) {
return vertex._id;
},
getPeerVertex: function (edge, vertex) {
if (edge._from === vertex._id) {
return db._document(edge._to);
}
if (edge._to === vertex._id) {
return db._document(edge._from);
}
return null;
},
getInVertex: function (edge) {
return db._document(edge._to);
},
getOutVertex: function (edge) {
return db._document(edge._from);
},
getEdgeId: function (edge) {
return edge._id;
},
getLabel: function (edge) {
return edge.$label;
},
getAllEdges: function (vertex) {
return this.graph._EDGES(vertex._id);
},
getInEdges: function (vertex) {
return this.graph._INEDGES(vertex._id);
},
getOutEdges: function (vertex) {
return this.graph._OUTEDGES(vertex._id);
}
};
}
////////////////////////////////////////////////////////////////////////////////
/// @brief default Graph datasource
///
@ -1487,6 +1554,7 @@ ArangoTraverser.EXCLUDE = 'exclude';
////////////////////////////////////////////////////////////////////////////////
exports.collectionDatasourceFactory = collectionDatasourceFactory;
exports.generalGraphDatasourceFactory = generalGraphDatasourceFactory;
exports.graphDatasourceFactory = graphDatasourceFactory;
exports.outboundExpander = outboundExpander;

View File

@ -70,54 +70,4 @@
</div>
</div>
<div id="new-aql-query" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" style="display:none">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<a class="arangoHeader">Save new query</a>
</div>
<div id="new-aql-body" class="modal-body">
<table>
<tr>
<th class="queryTH">Name:</th>
<th class="queryTH2"><input type="text" id="new-query-name" name="name" value=""/></th>
</tr>
</table>
</div>
<div id="colFooter" class="modal-footer">
<button class="button-close" data-dismiss="modal" aria-hidden="true">Close</button>
<button id="save-query" class="button-success pull-right">Save</button>
</div>
</div>
</script>
<!--
<div id="queryDropdown" class="headerDropdown query-dropdown">
<div class="dropdownInner query-dropdown-in" id="queryDropdownIn">
<a class="arangoHeader">Edit custom queries</a>
<div id="queryDropdownLeft" class="query-dropdown-left">
Name
<select id="queryModalSelect" class="query-modal-select"/>
</div>
<div id="queryDropdownRight">
Query
<textarea id="edit-aql-textarea"/>
</div>
<div class="buttonContainer">
<button id="delete-edit-query" class="button-danger">Delete</button>
<button id="save-edit-query" class="button-success">Save</button>
</div>
</div>
<div class="alert alert-error" style="display:none" id="reallyDeleteQueryDiv">
<strong>Really delete query?</strong>
<button id="confirmDeleteQuery" class="button-danger pull-right"
style="margin-top: -4px; margin-right: -18px !important;">Yes
</button>
<button id="abortDeleteQuery" class="button-neutral pull-right"
style="margin-top: -4px; margin-right:10px;">No
</button>
</div>
</div>
-->

View File

@ -168,7 +168,7 @@
this.buildCollectionLink(
this.collectionContext.prev
),
{
{
trigger: true
}
);
@ -281,7 +281,7 @@
var num = ++this.filterId;
$('#filterHeader').append(' <div class="queryline querylineAdd">'+
'<input id="attribute_name' + num +
'<input id="attribute_name' + num +
'" type="text" placeholder="Attribute name">'+
'<select name="operator" id="operator' +
num + '" class="filterSelect">'+
@ -292,8 +292,8 @@
' <option value="&gt;=">&gt;=</option>'+
' <option value="&gt;">&gt;</option>'+
'</select>'+
'<input id="attribute_value' + num +
'" type="text" placeholder="Attribute value" ' +
'<input id="attribute_value' + num +
'" type="text" placeholder="Attribute value" ' +
'class="filterValue">'+
' <a class="removeFilterItem" id="removeFilter' + num + '">' +
'<i class="icon icon-minus arangoicon"></i></a></div>');
@ -432,6 +432,7 @@
this.collection.getDocuments(this.collection.collectionID, page);
$('#docDeleteModal').modal('hide');
this.drawTable();
this.renderPaginationElements();
}
},
@ -554,7 +555,7 @@
$('.modalImportTooltips').tooltip({
placement: "left"
});
arangoHelper.fixTooltips(".icon_arangodb, .arangoicon", "top");
this.drawTable();
this.renderPaginationElements();

View File

@ -13,7 +13,7 @@
};
};
var createTextStub = function(type, label, value, info, placeholder, mandatory) {
var createTextStub = function(type, label, value, info, placeholder, mandatory, regexp) {
var obj = {
type: type,
label: label
@ -30,6 +30,12 @@
if (mandatory) {
obj.mandatory = mandatory;
}
if (regexp){
// returns true if the string contains the match
obj.validateInput = function(el){
return regexp.test(el.val());
};
}
return obj;
};
@ -161,8 +167,9 @@
return obj;
},
createTextEntry: function(id, label, value, info, placeholder, mandatory) {
var obj = createTextStub(this.tables.TEXT, label, value, info, placeholder, mandatory);
createTextEntry: function(id, label, value, info, placeholder, mandatory, regexp) {
var obj = createTextStub(this.tables.TEXT, label, value, info, placeholder, mandatory,
regexp);
obj.id = id;
return obj;
},
@ -270,6 +277,20 @@
});
}
});//handle select2
self.testInput = (function(){
_.each(tableContent,function(r){
if(r.validateInput){
$('#' + r.id).on('keyup', function(){
if(r.validateInput($('#' + r.id))){
$('#' + r.id).addClass('invalid-input');
} else {
$('#' + r.id).removeClass('invalid-input');
}
});
}
});
}());
if (events) {
this.events = events;
this.delegateEvents();

View File

@ -17,26 +17,6 @@
this.tableDescription.rows = this.customQueries;
},
updateTable: function () {
this.tableDescription.rows = this.customQueries;
_.each(this.tableDescription.rows, function(k,v) {
k.thirdRow = '<a class="deleteButton"><span class="icon_arangodb_roundminus"' +
' title="Delete query"></span></a>';
});
this.$(this.id).html(this.table.render({content: this.tableDescription}));
},
editCustomQuery: function(e) {
var queryName = $(e.target).parent().children().first().text();
var inputEditor = ace.edit("aqlEditor");
inputEditor.setValue(this.getCustomQueryValueByName(queryName));
this.deselect(inputEditor);
$('#querySelect').val(queryName);
this.switchTab("query-switch");
},
events: {
"click #result-switch": "switchTab",
"click #query-switch": "switchTab",
@ -57,10 +37,8 @@
'click #clearQueryButton': 'clearInput',
'click #addAQL': 'addAQL',
'click #editAQL': 'editAQL',
'click #save-query': 'saveAQL',
'click #delete-edit-query': 'showDeleteField',
'click #delete-edit-query': 'showDeleteFie/ld',
'click #abortDeleteQuery': 'hideDeleteField',
'keyup #new-query-name': 'listenKey',
'change #queryModalSelect': 'updateEditSelect',
'change #querySelect': 'importSelected',
'change #querySize': 'changeSize',
@ -71,6 +49,46 @@
'click #queryDiv .showHotkeyHelp': 'shortcutModal'
},
createCustomQueryModal: function(){
var buttons = [], tableContent = [];
tableContent.push(
window.modalView.createTextEntry(
'new-query-name',
'Name',
'',
undefined,
undefined,
false,
/[<>&'"]/
)
);
buttons.push(
window.modalView.createSuccessButton('Save', this.saveAQL.bind(this))
);
window.modalView.show('modalTable.ejs', 'Save Query', buttons, tableContent, undefined,
{'keyup #new-query-name' : this.listenKey.bind(this)});
},
updateTable: function () {
this.tableDescription.rows = this.customQueries;
_.each(this.tableDescription.rows, function(k,v) {
k.thirdRow = '<a class="deleteButton"><span class="icon_arangodb_roundminus"' +
' title="Delete query"></span></a>';
});
this.$(this.id).html(this.table.render({content: this.tableDescription}));
},
editCustomQuery: function(e) {
var queryName = $(e.target).parent().children().first().text();
var inputEditor = ace.edit("aqlEditor");
inputEditor.setValue(this.getCustomQueryValueByName(queryName));
this.deselect(inputEditor);
$('#querySelect').val(queryName);
this.switchTab("query-switch");
},
initTabArray: function() {
var self = this;
$(".arango-tab").children().each( function(index) {
@ -92,42 +110,20 @@
return;
}
//check for invalid query names, if present change the box-shadoq to red
//check for invalid query names, if present change the box-shadow to red
// and disable the save functionality
var dangerCss = {
"webkit-box-shadow" : "inset 0 1px 1px rgba( 0,0,0, 0.075), 0 0 8px rgba(234, 23, 23, 0.6)",
"moz-box-shadow" : "inset 0 1px 1px rgba( 0,0,0, 0.075), 0 0 8px rgba(234, 23, 23, 0.6)",
"box-shadow" : "inset 0 1px 1px rgba( 0,0,0, 0.075), 0 0 8px rgba(234, 23, 23, 0.6)",
"border-color" : "rgba(234, 23, 23, 0.8)"
};
var normalCss = {
"webkit-box-shadow" : "inset 0 1px 1px rgba( 0,0,0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6)",
"moz-box-shadow" : "inset 0 1px 1px rgba( 0,0,0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6)",
"box-shadow" : "inset 0 1px 1px rgba( 0,0,0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6)",
"border-color" : "rgba(82, 168, 236, 0.8)"
};
if ( saveName.match(/[<>&'"]/g)){
$('#new-query-name').css(dangerCss);
$('#new-query-name').addClass('invalid');
} else {
$('#new-query-name').css(normalCss);
$('#new-query-name').removeClass('invalid');
}
//console.log(saveName.match(/[<>&'"]/));
var boolTemp = false;
this.customQueries.some(function(query){
if( query.name === saveName ){
$('#save-query').removeClass('button-success');
$('#save-query').addClass('button-warning');
$('#save-query').text('Update');
$('#modalButton1').removeClass('button-success');
$('#modalButton1').addClass('button-warning');
$('#modalButton1').text('Update');
boolTemp = true;
} else {
$('#save-query').removeClass('button-warning');
$('#save-query').addClass('button-success');
$('#save-query').text('Save');
$('#modalButton1').removeClass('button-warning');
$('#modalButton1').addClass('button-success');
$('#modalButton1').text('Save');
}
if (boolTemp) {
@ -309,8 +305,8 @@
addAQL: function () {
//render options
this.createCustomQueryModal();
$('#new-query-name').val($('#querySelect').val());
$('#new-aql-query').modal('show');
setTimeout(function () {
$('#new-query-name').focus();
}, 500);
@ -363,10 +359,11 @@
},
saveAQL: function (e) {
e.stopPropagation();
var inputEditor = ace.edit("aqlEditor");
var saveName = $('#new-query-name').val();
if ($('#new-query-name').hasClass('invalid')) {
if ($('#new-query-name').hasClass('invalid-input')) {
return;
}
@ -389,8 +386,7 @@
if (quit === true) {
//Heiko: Form-Validator - name already taken
$('#new-aql-query').modal('hide');
$('#edit-aql-query').modal('hide');
window.modalView.hide();
return;
}
@ -399,8 +395,7 @@
value: content
});
$('#new-aql-query').modal('hide');
$('#edit-aql-query').modal('hide');
window.modalView.hide();
localStorage.setItem("customQueries", JSON.stringify(this.customQueries));
this.renderSelectboxes();

View File

@ -219,6 +219,13 @@ pre.gv-object-view {
margin-bottom: 10px;
}
.modal-body input[type='text'].invalid-input{
webkit-box-shadow : inset 0 1px 1px rgba( 0,0,0, 0.075), 0 0 8px rgba(234, 23, 23, 0.6);
moz-box-shadow : inset 0 1px 1px rgba( 0,0,0, 0.075), 0 0 8px rgba(234, 23, 23, 0.6);
box-shadow : inset 0 1px 1px rgba( 0,0,0, 0.075), 0 0 8px rgba(234, 23, 23, 0.6);
border-color : rgba(234, 23, 23, 0.8)
}
.modal-delete-confirmation {
display: none;

View File

@ -21,31 +21,37 @@ textarea,
font-style: normal;
font-weight: 300;
src: local("Open Sans Light"), local("OpenSans-Light"), url("../fonts/opensans/OpenSansLight.woff") format("woff"); }
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 400;
src: local("Open Sans"), local("OpenSans"), url("../fonts/opensans/OpenSans.woff") format("woff"); }
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 700;
src: local("Open Sans Bold"), local("OpenSans-Bold"), url("../fonts/opensans/OpenSansBold.woff") format("woff"); }
@font-face {
font-family: 'Open Sans';
font-style: italic;
font-weight: 300;
src: local("Open Sans Light Italic"), local("OpenSansLight-Italic"), url("../fonts/opensans/OpenSansLightItalic.woff") format("woff"); }
@font-face {
font-family: 'Open Sans';
font-style: italic;
font-weight: 400;
src: local("Open Sans Italic"), local("OpenSans-Italic"), url("../fonts/opensans/OpenSansItalic.woff") format("woff"); }
@font-face {
font-family: 'Open Sans';
font-style: italic;
font-weight: 700;
src: local("Open Sans Bold Italic"), local("OpenSans-BoldItalic"), url("../fonts/opensans/OpenSansBoldItalic.woff") format("woff"); }
/*!
* Font Awesome 4.0.3 by @davegandy - http://fontawesome.io - @fontawesome
* License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
@ -58,6 +64,7 @@ textarea,
src: url("../fonts/fontawesome/fontawesome-webfont.eot?#iefix&v=4.0.3") format("embedded-opentype"), url("../fonts/fontawesome/fontawesome-webfont.woff?v=4.0.3") format("woff"), url("../fonts/fontawesome/fontawesome-webfont.ttf?v=4.0.3") format("truetype"), url("../fonts/fontawesome/fontawesome-webfont.svg?v=4.0.3#fontawesomeregular") format("svg");
font-weight: normal;
font-style: normal; }
.fa {
display: inline-block;
font-family: FontAwesome;
@ -133,30 +140,35 @@ textarea,
100% {
-moz-transform: rotate(359deg); } }
@-webkit-keyframes spin {
0% {
-webkit-transform: rotate(0deg); }
100% {
-webkit-transform: rotate(359deg); } }
@-o-keyframes spin {
0% {
-o-transform: rotate(0deg); }
100% {
-o-transform: rotate(359deg); } }
@-ms-keyframes spin {
0% {
-ms-transform: rotate(0deg); }
100% {
-ms-transform: rotate(359deg); } }
@keyframes spin {
0% {
transform: rotate(0deg); }
100% {
transform: rotate(359deg); } }
.fa-rotate-90 {
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=$rotation);
-webkit-transform: rotate(90deg);
@ -1444,7 +1456,7 @@ nav.navbar, footer.footer {
background-color: #f87c0f; }
.button-inactive {
background-color: lightgray; }
background-color: lightgrey; }
.button-inactive:hover, .button-inactive:focus {
background-color: gray; }
@ -3997,6 +4009,12 @@ pre.gv-object-view {
.modal-body input[type='checkbox'] {
margin-bottom: 10px; }
.modal-body input[type='text'].invalid-input {
webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(234, 23, 23, 0.6);
moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(234, 23, 23, 0.6);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(234, 23, 23, 0.6);
border-color: rgba(234, 23, 23, 0.8); }
.modal-delete-confirmation {
display: none; }
.modal-delete-confirmation button {
@ -4155,7 +4173,7 @@ pre.gv-object-view {
width: 5%; }
.user-menu-img {
background-color: lightgray;
background-color: lightgrey;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
border-radius: 3px;

View File

@ -1290,9 +1290,11 @@
spyOn(view, "drawTable");
view.collection = new window.arangoDocuments();
view.target = "#confirmDeleteBtn";
spyOn(view, "renderPaginationElements");
view.reallyDelete();
expect(view.renderPaginationElements).toHaveBeenCalled();
expect(window.$).toHaveBeenCalledWith("#confirmDeleteBtn");
expect(window.$).toHaveBeenCalledWith("#documentsTableID");
expect(window.$).toHaveBeenCalledWith("#docDeleteModal");
@ -1375,8 +1377,11 @@
view.collection = new window.arangoDocuments();
view.target = "#confirmDeleteBtn";
spyOn(view, "drawTable");
spyOn(view, "renderPaginationElements");
view.reallyDelete();
expect(view.renderPaginationElements).toHaveBeenCalled();
expect(window.$).toHaveBeenCalledWith("#confirmDeleteBtn");

View File

@ -53,7 +53,7 @@ var stringToArray = function (x) {
if (typeof x === "string") {
return [x];
}
return x;
return _.clone(x);
};
////////////////////////////////////////////////////////////////////////////////
@ -127,10 +127,6 @@ var findOrCreateCollectionsByEdgeDefinitions = function (edgeDefinitions, noCrea
// --SECTION-- Fluent AQL Interface
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// --SECTION-- Fluent AQL Interface
// -----------------------------------------------------------------------------
var AQLStatement = function(query, isEdgeQuery) {
this.query = query;
this.edgeQuery = isEdgeQuery || false;
@ -279,7 +275,7 @@ var _directedRelationDefinition = function (
relationName, fromVertexCollections, toVertexCollections) {
if (arguments.length < 3) {
throw "method _undirectedRelationDefinition expects 3 arguments";
throw "method _directedRelationDefinition expects 3 arguments";
}
if (typeof relationName !== "string" || relationName === "") {
@ -430,6 +426,51 @@ var _graph = function(graphName) {
return new Graph(graphName, g.edgeDefinitions, collections[0], collections[1]);
};
////////////////////////////////////////////////////////////////////////////////
/// @brief drop a graph.
////////////////////////////////////////////////////////////////////////////////
var _drop = function(graphId, dropCollections) {
var gdb = db._graphs;
if (gdb === null || gdb === undefined) {
throw "_graphs collection does not exist.";
}
if (!gdb.exists(graphId)) {
throw "Graph " + graphId + " does not exist.";
}
if (dropCollections !== false) {
var graph = gdb.document(graphId);
var edgeDefinitions = graph.edgeDefinitions;
require("internal").print(edgeDefinitions);
edgeDefinitions.forEach(
function(edgeDefinition) {
var from = edgeDefinition.from;
var to = edgeDefinition.to;
var edge = edgeDefinition.collection;
db._drop(edge);
from.forEach(
function(col) {
db._drop(col);
}
);
to.forEach(
function(col) {
db._drop(col);
}
);
}
);
}
gdb.remove(graphId);
return true;
};
////////////////////////////////////////////////////////////////////////////////
/// @brief return all edge collections of the graph.
////////////////////////////////////////////////////////////////////////////////
@ -487,7 +528,7 @@ Graph.prototype._INEDGES = function(vertexId) {
/// @brief outEdges(vertexId).
////////////////////////////////////////////////////////////////////////////////
Graph.prototype._outEdges = function(vertexId) {
Graph.prototype._OUTEDGES = function(vertexId) {
var edgeCollections = this._edgeCollections();
var result = [];
@ -587,6 +628,7 @@ exports._directedRelationDefinition = _directedRelationDefinition;
exports._graph = _graph;
exports.edgeDefinitions = edgeDefinitions;
exports._create = _create;
exports._drop = _drop;
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE

View File

@ -29,6 +29,7 @@
////////////////////////////////////////////////////////////////////////////////
var graph = require("org/arangodb/graph-blueprint");
var generalGraph = require("org/arangodb/general-graph");
var arangodb = require("org/arangodb");
var BinaryHeap = require("org/arangodb/heap").BinaryHeap;
var ArangoError = arangodb.ArangoError;
@ -158,6 +159,72 @@ function collectionDatasourceFactory (edgeCollection) {
};
}
////////////////////////////////////////////////////////////////////////////////
/// @brief general graph datasource
///
/// This is a factory function that creates a datasource that operates on the
/// specified general graph. The vertices and edges are delivered by the
/// the general-graph module.
////////////////////////////////////////////////////////////////////////////////
function generalGraphDatasourceFactory (graph) {
var g = graph;
if (typeof g === 'string') {
g = generalGraph._graph(g);
}
return {
graph: g,
getVertexId: function (vertex) {
return vertex._id;
},
getPeerVertex: function (edge, vertex) {
if (edge._from === vertex._id) {
return db._document(edge._to);
}
if (edge._to === vertex._id) {
return db._document(edge._from);
}
return null;
},
getInVertex: function (edge) {
return db._document(edge._to);
},
getOutVertex: function (edge) {
return db._document(edge._from);
},
getEdgeId: function (edge) {
return edge._id;
},
getLabel: function (edge) {
return edge.$label;
},
getAllEdges: function (vertex) {
return this.graph._EDGES(vertex._id);
},
getInEdges: function (vertex) {
return this.graph._INEDGES(vertex._id);
},
getOutEdges: function (vertex) {
return this.graph._OUTEDGES(vertex._id);
}
};
}
////////////////////////////////////////////////////////////////////////////////
/// @brief default Graph datasource
///
@ -1486,6 +1553,7 @@ ArangoTraverser.EXCLUDE = 'exclude';
////////////////////////////////////////////////////////////////////////////////
exports.collectionDatasourceFactory = collectionDatasourceFactory;
exports.generalGraphDatasourceFactory = generalGraphDatasourceFactory;
exports.graphDatasourceFactory = graphDatasourceFactory;
exports.outboundExpander = outboundExpander;

View File

@ -478,14 +478,32 @@ function GeneralGraphAQLQueriesSuite() {
});
};
// The testee graph object
var g;
return {
////////////////////////////////////////////////////////////////////////////////
/// @brief setUp: query creation for edges
////////////////////////////////////////////////////////////////////////////////
setUp: function() {
g = createInclExcl();
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test: query creation for edges
////////////////////////////////////////////////////////////////////////////////
tearDown: function() {
dropInclExcl();
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test: query creation for edges
////////////////////////////////////////////////////////////////////////////////
test_edges: function() {
var g = createInclExcl();
var query = g._edges("v1/1");
assertEqual(query.printQuery(), 'FOR edges_0 IN GRAPH_EDGES('
+ '@graphName,@startVertex_0,"any")');
@ -497,7 +515,6 @@ function GeneralGraphAQLQueriesSuite() {
assertTrue(findIdInResult(result, e1), "Did not include e1");
assertTrue(findIdInResult(result, e2), "Did not include e2");
assertTrue(findIdInResult(result, e3), "Did not include e3");
dropInclExcl();
},
////////////////////////////////////////////////////////////////////////////////
@ -505,7 +522,6 @@ function GeneralGraphAQLQueriesSuite() {
////////////////////////////////////////////////////////////////////////////////
test_outEdges: function() {
var g = createInclExcl();
var query = g._outEdges("v1/1");
assertEqual(query.printQuery(), "FOR edges_0 IN GRAPH_EDGES("
+ '@graphName,@startVertex_0,"outbound")');
@ -517,7 +533,6 @@ function GeneralGraphAQLQueriesSuite() {
assertTrue(findIdInResult(result, e1), "Did not include e1");
assertTrue(findIdInResult(result, e3), "Did not include e3");
assertFalse(findIdInResult(result, e2), "e2 is not excluded");
dropInclExcl();
},
////////////////////////////////////////////////////////////////////////////////
@ -525,7 +540,6 @@ function GeneralGraphAQLQueriesSuite() {
////////////////////////////////////////////////////////////////////////////////
test_inEdges: function() {
var g = createInclExcl();
var query = g._inEdges("v1/1");
assertEqual(query.printQuery(), "FOR edges_0 IN GRAPH_EDGES("
+ '@graphName,@startVertex_0,"inbound")');
@ -537,11 +551,9 @@ function GeneralGraphAQLQueriesSuite() {
assertTrue(findIdInResult(result, e2), "Did not include e2");
assertFalse(findIdInResult(result, e1), "e1 is not excluded");
assertFalse(findIdInResult(result, e3), "e3 is not excluded");
dropInclExcl();
},
test_restrictOnEdges: function() {
var g = createInclExcl();
var query = g._edges("v1/1").restrict("included");
assertEqual(query.printQuery(), "FOR edges_0 IN GRAPH_EDGES("
+ '@graphName,@startVertex_0,"any",{},@restrictions_0)');
@ -555,7 +567,6 @@ function GeneralGraphAQLQueriesSuite() {
assertTrue(findIdInResult(result, e1), "Did not include e1");
assertTrue(findIdInResult(result, e2), "Did not include e2");
assertFalse(findIdInResult(result, e3), "e3 is not excluded");
dropInclExcl();
},
////////////////////////////////////////////////////////////////////////////////
@ -563,7 +574,6 @@ function GeneralGraphAQLQueriesSuite() {
////////////////////////////////////////////////////////////////////////////////
test_restrictOnInEdges: function() {
var g = createInclExcl();
var query = g._inEdges("v1/1").restrict("included");
assertEqual(query.printQuery(), "FOR edges_0 IN GRAPH_EDGES("
+ '@graphName,@startVertex_0,"inbound",{},@restrictions_0)');
@ -576,7 +586,6 @@ function GeneralGraphAQLQueriesSuite() {
assertTrue(findIdInResult(result, e2), "Did not include e2");
assertFalse(findIdInResult(result, e1), "e1 is not excluded");
assertFalse(findIdInResult(result, e3), "e3 is not excluded");
dropInclExcl();
},
////////////////////////////////////////////////////////////////////////////////
@ -584,7 +593,6 @@ function GeneralGraphAQLQueriesSuite() {
////////////////////////////////////////////////////////////////////////////////
test_restrictOnOutEdges: function() {
var g = createInclExcl();
var query = g._outEdges("v1/1").restrict("included");
assertEqual(query.printQuery(), "FOR edges_0 IN GRAPH_EDGES("
+ '@graphName,@startVertex_0,"outbound",{},@restrictions_0)');
@ -597,7 +605,6 @@ 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");
dropInclExcl();
},
////////////////////////////////////////////////////////////////////////////////
@ -605,7 +612,6 @@ function GeneralGraphAQLQueriesSuite() {
////////////////////////////////////////////////////////////////////////////////
test_filterOnEdges: function() {
var g = createInclExcl();
var query = g._edges("v1/1").filter({val: true});
// var query = g._edges("v1/1").filter("e.val = true");
assertEqual(query.printQuery(), "FOR edges_0 IN GRAPH_EDGES("
@ -619,8 +625,6 @@ 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");
dropInclExcl();
},
////////////////////////////////////////////////////////////////////////////////
@ -628,7 +632,6 @@ function GeneralGraphAQLQueriesSuite() {
////////////////////////////////////////////////////////////////////////////////
test_filterOnInEdges: function() {
var g = createInclExcl();
var query = g._inEdges("v1/1").filter({val: true});
assertEqual(query.printQuery(), "FOR edges_0 IN GRAPH_EDGES("
+ '@graphName,@startVertex_0,"inbound") '
@ -641,7 +644,6 @@ function GeneralGraphAQLQueriesSuite() {
assertFalse(findIdInResult(result, e1), "e1 is not excluded");
assertFalse(findIdInResult(result, e2), "e2 is not excluded");
assertFalse(findIdInResult(result, e3), "e3 is not excluded");
dropInclExcl();
},
////////////////////////////////////////////////////////////////////////////////
@ -649,7 +651,6 @@ function GeneralGraphAQLQueriesSuite() {
////////////////////////////////////////////////////////////////////////////////
test_filterOnOutEdges: function() {
var g = createInclExcl();
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("
@ -663,7 +664,6 @@ 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");
dropInclExcl();
}
////////////////////////////////////////////////////////////////////////////////
@ -672,7 +672,6 @@ function GeneralGraphAQLQueriesSuite() {
/* Broken string replacement
test_letOnEdges: function() {
var g = createInclExcl();
var query = g._edges("v1/1").let("myVal = e.val");
assertEqual(query.printQuery(), "FOR edges_0 IN GRAPH_EDGES("
+ "@graphName,@startVertex_0,any) LET myVal = edges_0.val");
@ -688,7 +687,6 @@ function GeneralGraphAQLQueriesSuite() {
assertFalse(findIdInResult(result, e2));
*/
/*
dropInclExcl();
}
*/
@ -698,141 +696,249 @@ function GeneralGraphAQLQueriesSuite() {
function EdgesAndVerticesSuite() {
try {
arangodb.db._collection("_graphs").remove("_graphs/blubGraph")
} catch (err) {
}
var g = graph._create(
"blubGraph",
graph.edgeDefinitions(
graph._undirectedRelationDefinition("edgeCollection1", "vertexCollection1"),
graph._directedRelationDefinition("edgeCollection2",
["vertexCollection1", "vertexCollection2"], ["vertexCollection3", "vertexCollection4"]
)
)
);
var g;
var vertexIds = [];
var vertexId1, vertexId2;
var edgeId1, edgeId2;
fillCollections = function() {
var ids = {};
var vertex = g.vertexCollection1.save({first_name: "Tam"});
ids["vId11"] = vertex._id;
vertex = g.vertexCollection1.save({first_name: "Tem"});
ids["vId12"] = vertex._id;
vertex = g.vertexCollection1.save({first_name: "Tim"});
ids["vId13"] = vertex._id;
vertex = g.vertexCollection1.save({first_name: "Tom"});
ids["vId14"] = vertex._id;
vertex = g.vertexCollection1.save({first_name: "Tum"});
ids["vId15"] = vertex._id;
vertex = g.unitTestVertexCollection3.save({first_name: "Tam"});
ids["vId31"] = vertex._id;
vertex = g.unitTestVertexCollection3.save({first_name: "Tem"});
ids["vId32"] = vertex._id;
vertex = g.unitTestVertexCollection3.save({first_name: "Tim"});
ids["vId33"] = vertex._id;
vertex = g.unitTestVertexCollection3.save({first_name: "Tom"});
ids["vId34"] = vertex._id;
vertex = g.unitTestVertexCollection3.save({first_name: "Tum"});
ids["vId35"] = vertex._id;
var edge = g.unitTestEdgeCollection1.save(ids.vId11, ids.vId12, {});
ids["eId11"] = edge._id;
edge = g.unitTestEdgeCollection1.save(ids.vId11, ids.vId13, {});
ids["eId12"] = edge._id;
edge = g.unitTestEdgeCollection1.save(ids.vId11, ids.vId14, {});
ids["eId13"] = edge._id;
edge = g.unitTestEdgeCollection1.save(ids.vId11, ids.vId15, {});
ids["eId14"] = edge._id;
edge = g.unitTestEdgeCollection1.save(ids.vId12, ids.vId11, {});
ids["eId15"] = edge._id;
edge = g.unitTestEdgeCollection1.save(ids.vId13, ids.vId11, {});
ids["eId16"] = edge._id;
edge = g.unitTestEdgeCollection1.save(ids.vId14, ids.vId11, {});
ids["eId17"] = edge._id;
edge = g.unitTestEdgeCollection1.save(ids.vId15, ids.vId11, {});
ids["eId18"] = edge._id;
edge = g.unitTestEdgeCollection2.save(ids.vId11, ids.vId31, {});
ids["eId21"] = edge._id;
edge = g.unitTestEdgeCollection2.save(ids.vId11, ids.vId32, {});
ids["eId22"] = edge._id;
edge = g.unitTestEdgeCollection2.save(ids.vId11, ids.vId33, {});
ids["eId23"] = edge._id;
edge = g.unitTestEdgeCollection2.save(ids.vId11, ids.vId34, {});
ids["eId24"] = edge._id;
edge = g.unitTestEdgeCollection2.save(ids.vId11, ids.vId35, {});
ids["eId25"] = edge._id;
return ids;
}
return {
setUp : function() {
try {
arangodb.db._collection("_graphs").remove("_graphs/unitTestGraph")
} catch (err) {
}
g = graph._create(
"unitTestGraph",
graph.edgeDefinitions(
graph._undirectedRelationDefinition("unitTestEdgeCollection1", "unitTestVertexCollection1"),
graph._directedRelationDefinition("unitTestEdgeCollection2",
["unitTestVertexCollection1", "unitTestVertexCollection2"], ["unitTestVertexCollection3", "unitTestVertexCollection4"]
)
)
);
},
tearDown : function() {
db.unitTestVertexCollection1.drop();
db.unitTestVertexCollection2.drop();
db.unitTestVertexCollection3.drop();
db.unitTestVertexCollection4.drop();
db.unitTestEdgeCollection1.drop();
db.unitTestEdgeCollection2.drop();
},
test_edgeCollections : function () {
var edgeCollections = g._edgeCollections();
assertEqual(edgeCollections[0].name(), 'edgeCollection1');
assertEqual(edgeCollections[1].name(), 'edgeCollection2');
assertEqual(edgeCollections[0].name(), 'unitTestEdgeCollection1');
assertEqual(edgeCollections[1].name(), 'unitTestEdgeCollection2');
},
test_vertexCollections : function () {
var vertexCollections = g._vertexCollections();
assertEqual(vertexCollections[0].name(), 'vertexCollection1');
assertEqual(vertexCollections[1].name(), 'vertexCollection2');
assertEqual(vertexCollections[2].name(), 'vertexCollection3');
assertEqual(vertexCollections[3].name(), 'vertexCollection4');
assertEqual(vertexCollections[0].name(), 'unitTestVertexCollection1');
assertEqual(vertexCollections[1].name(), 'unitTestVertexCollection2');
assertEqual(vertexCollections[2].name(), 'unitTestVertexCollection3');
assertEqual(vertexCollections[3].name(), 'unitTestVertexCollection4');
},
test_vC_save : function () {
var vertex = g.vertexCollection1.save({first_name: "Tom"});
var vertex = g.unitTestVertexCollection1.save({first_name: "Tom"});
assertFalse(vertex.error);
vertexId1 = vertex._id;
var vertexObj = g.vertexCollection1.document(vertexId1);
var vertexObj = g.unitTestVertexCollection1.document(vertexId1);
assertEqual(vertexObj.first_name, "Tom");
},
test_vC_replace : function () {
var vertex = g.vertexCollection1.replace(vertexId1, {first_name: "Tim"});
var vertex = g.unitTestVertexCollection1.save({first_name: "Tom"});
var vertexId = vertex._id;
vertex = g.unitTestVertexCollection1.replace(vertexId, {first_name: "Tim"});
assertFalse(vertex.error);
var vertexObj = g.vertexCollection1.document(vertexId1);
var vertexObj = g.unitTestVertexCollection1.document(vertexId);
assertEqual(vertexObj.first_name, "Tim");
},
test_vC_update : function () {
var vertex = g.vertexCollection1.update(vertexId1, {age: 42});
var vertex = g.unitTestVertexCollection1.save({first_name: "Tim"});
var vertexId = vertex._id;
vertex = g.unitTestVertexCollection1.update(vertexId, {age: 42});
assertFalse(vertex.error);
var vertexObj = g.vertexCollection1.document(vertexId1);
var vertexObj = g.unitTestVertexCollection1.document(vertexId);
assertEqual(vertexObj.first_name, "Tim");
assertEqual(vertexObj.age, 42);
},
test_vC_remove : function () {
var vertex = g.vertexCollection1.remove(vertexId1);
var vertex = g.unitTestVertexCollection1.save({first_name: "Tim"});
var vertexId = vertex._id;
var vertex = g.unitTestVertexCollection1.remove(vertexId);
assertTrue(vertex);
},
test_eC_save_undirected : function() {
var vertex1 = g.vertexCollection1.save({first_name: "Tom"});
vertexId1 = vertex1._id;
var vertex2 = g.vertexCollection1.save({first_name: "Tim"});
vertexId2 = vertex2._id;
var edge = g.edgeCollection1.save(vertexId1, vertexId2, {});
var vertex1 = g.unitTestVertexCollection1.save({first_name: "Tom"});
var vertexId1 = vertex1._id;
var vertex2 = g.unitTestVertexCollection1.save({first_name: "Tim"});
var vertexId2 = vertex2._id;
var edge = g.unitTestEdgeCollection1.save(vertexId1, vertexId2, {});
assertFalse(edge.error);
edgeId1 = edge._id;
g.vertexCollection1.remove(vertexId1);
g.vertexCollection1.remove(vertexId2);
g.unitTestVertexCollection1.remove(vertexId1);
g.unitTestVertexCollection1.remove(vertexId2);
},
test_eC_save_directed : function() {
var vertex1 = g.vertexCollection2.save({first_name: "Tom"});
var vertex1 = g.unitTestVertexCollection2.save({first_name: "Tom"});
vertexId1 = vertex1._id;
var vertex2 = g.vertexCollection4.save({first_name: "Tim"});
var vertex2 = g.unitTestVertexCollection4.save({first_name: "Tim"});
vertexId2 = vertex2._id;
var edge = g.edgeCollection2.save(vertexId1, vertexId2, {});
var edge = g.unitTestEdgeCollection2.save(vertexId1, vertexId2, {});
assertFalse(edge.error);
edgeId2 = edge._id;
g.vertexCollection2.remove(vertexId1);
g.vertexCollection4.remove(vertexId2);
g.unitTestVertexCollection2.remove(vertexId1);
g.unitTestVertexCollection4.remove(vertexId2);
},
test_eC_save_withError : function() {
var vertex1 = g.vertexCollection1.save({first_name: "Tom"});
var vertex1 = g.unitTestVertexCollection1.save({first_name: "Tom"});
vertexId1 = vertex1._id;
var vertex2 = g.vertexCollection2.save({first_name: "Tim"});
var vertex2 = g.unitTestVertexCollection2.save({first_name: "Tim"});
vertexId2 = vertex2._id;
try {
var edge = g.edgeCollection1.save(vertexId1, vertexId2, {});
var edge = g.unitTestEdgeCollection1.save(vertexId1, vertexId2, {});
} catch (e) {
assertEqual(e, "Edge is not allowed between " + vertexId1 + " and " + vertexId2 + ".")
}
g.vertexCollection1.remove(vertexId1);
g.vertexCollection2.remove(vertexId2);
g.unitTestVertexCollection1.remove(vertexId1);
g.unitTestVertexCollection2.remove(vertexId2);
},
test_eC_replace : function() {
var edge = g.edgeCollection1.replace(edgeId1, {label: "knows"});
var vertex1 = g.unitTestVertexCollection1.save({first_name: "Tom"});
var vertexId1 = vertex1._id;
var vertex2 = g.unitTestVertexCollection1.save({first_name: "Tim"});
var vertexId2 = vertex2._id;
var edge = g.unitTestEdgeCollection1.save(vertexId1, vertexId2, {});
var edgeId1 = edge._id;
edge = g.unitTestEdgeCollection1.replace(edgeId1, {label: "knows"});
assertFalse(edge.error);
var edgeObj = g.edgeCollection1.document(edgeId1);
var edgeObj = g.unitTestEdgeCollection1.document(edgeId1);
assertEqual(edgeObj.label, "knows");
assertEqual(edgeObj._id, edgeId1);
},
test_eC_update : function () {
var edge = g.edgeCollection1.update(edgeId1, {blub: "blub"});
var vertex1 = g.unitTestVertexCollection1.save({first_name: "Tom"});
var vertexId1 = vertex1._id;
var vertex2 = g.unitTestVertexCollection1.save({first_name: "Tim"});
var vertexId2 = vertex2._id;
var edge = g.unitTestEdgeCollection1.save(vertexId1, vertexId2, {});
var edgeId1 = edge._id;
edge = g.unitTestEdgeCollection1.replace(edgeId1, {label: "knows"});
edge = g.unitTestEdgeCollection1.update(edgeId1, {blub: "blub"});
assertFalse(edge.error);
var edgeObj = g.edgeCollection1.document(edgeId1);
var edgeObj = g.unitTestEdgeCollection1.document(edgeId1);
assertEqual(edgeObj.label, "knows");
assertEqual(edgeObj.blub, "blub");
assertEqual(edgeObj._id, edgeId1);
},
test_eC_remove : function () {
var edge = g.edgeCollection1.remove(edgeId1);
assertTrue(edge);
edge = g.edgeCollection2.remove(edgeId2);
var vertex1 = g.unitTestVertexCollection1.save({first_name: "Tom"});
var vertexId1 = vertex1._id;
var vertex2 = g.unitTestVertexCollection1.save({first_name: "Tim"});
var vertexId2 = vertex2._id;
var edge = g.unitTestEdgeCollection1.save(vertexId1, vertexId2, {});
var edgeId1 = edge._id;
edge = g.unitTestEdgeCollection1.remove(edgeId1);
assertTrue(edge);
},
test_edges : function() {
var ids = fillCollections();
var result = g._edges(ids.vId11).toArray();
assertEqual(result.length, 13)
},
test_inEdges : function() {
var ids = fillCollections();
var result = g._inEdges(ids.vId11).toArray();
assertEqual(result.length, 4)
},
dump : function() {
db.vertexCollection1.drop();
db.vertexCollection2.drop();
db.vertexCollection3.drop();
db.vertexCollection4.drop();
db.edgeCollection1.drop();
db.edgeCollection2.drop();
test_outEdges : function() {
var ids = fillCollections();
var result = g._outEdges(ids.vId11).toArray();
assertEqual(result.length, 9)
},
test_getInVertex : function() {
var ids = fillCollections();
var result = g._getInVertex(ids.eId11);
assertEqual(result._id, ids.vId11);
},
test_getOutVertex : function() {
var ids = fillCollections();
var result = g._getOutVertex(ids.eId11);
assertEqual(result._id, ids.vId12);
result = g._getOutVertex(ids.eId25);
assertEqual(result._id, ids.vId35);
}
};

View File

@ -33,6 +33,7 @@ var jsunity = require("jsunity");
var arangodb = require("org/arangodb");
var traversal = require("org/arangodb/graph/traversal");
var graph = require("org/arangodb/graph");
var generalGraph = require("org/arangodb/general-graph");
var db = arangodb.db;
var Traverser = traversal.Traverser;
@ -1856,6 +1857,370 @@ function CollectionTraversalSuite () {
};
}
// -----------------------------------------------------------------------------
// --SECTION-- general graph traversal
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief test: general-graph-based graph traversal
////////////////////////////////////////////////////////////////////////////////
function GeneralGraphTraversalSuite () {
// Definition of the edges: A -> BDEH <-> CFGI
var vnA = "UnitTestsVertices1";
var enDir = "UnitTestsEdges1";
var vnBDH = "UnitTestsVertices2";
var enUndir = "UnitTestsEdges2";
var vnCEFGI = "UnitTestsVertices3";
var gn = "UnitTestsGraph";
var g;
var getResult = function () {
return {
visited: {
vertices: [ ],
paths: [ ]
}
};
};
var getIds = function (data) {
var r = [ ];
data.forEach(function (item) {
r.push(item._id);
});
return r;
};
var saveVertex = function(colName, key) {
g[colName].save({ _key: key, name: key });
};
var saveEdge = function(edgeCol, fromCol, toCol, nodePair) {
var l = nodePair[0];
var r = nodePair[1];
g[edgeCol].save(fromCol + "/" + l, toCol + "/" + r, {_key: l + r, what: l + "->" + r });
};
var cleanUp = function() {
db._drop(vnA);
db._drop(vnBDH);
db._drop(vnCEFGI);
db._drop(enDir);
db._drop(enUndir);
if (db._graphs.exists(gn)) {
db._graphs.remove(gn);
}
};
return {
////////////////////////////////////////////////////////////////////////////////
/// @brief set up
////////////////////////////////////////////////////////////////////////////////
setUp : function () {
cleanUp();
var edgeDef = [];
edgeDef.push(generalGraph._directedRelationDefinition(enDir, vnA, vnBDH));
edgeDef.push(generalGraph._undirectedRelationDefinition(enUndir, [vnBDH, vnCEFGI]));
g = generalGraph._create(gn, edgeDef);
saveVertex(vnA, "A");
[ "B", "D", "H" ].forEach(function (item) {
saveVertex(vnBDH, item);
});
[ "C", "E", "F", "G", "I" ].forEach(function (item) {
saveVertex(vnCEFGI, item);
});
[ [ "A", "B" ], [ "A", "D" ] ].forEach(function (item) {
saveEdge(enDir, vnA, vnBDH, item);
});
[ [ "B", "C" ], [ "D", "E" ], [ "D", "F" ], [ "B", "G" ], [ "B", "I" ] ].forEach(function (item) {
saveEdge(enUndir, vnBDH, vnCEFGI, item);
});
[ [ "C", "D" ], [ "G", "H" ], [ "I", "H"] ].forEach(function (item) {
saveEdge(enUndir, vnCEFGI, vnBDH, item);
});
},
////////////////////////////////////////////////////////////////////////////////
/// @brief tear down
////////////////////////////////////////////////////////////////////////////////
tearDown : function () {
cleanUp();
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test outbound expander
////////////////////////////////////////////////////////////////////////////////
testOutboundExpander : function () {
var config = {
sort: function (l, r) { return l._key < r._key ? -1 : 1; },
datasource: traversal.generalGraphDatasourceFactory(gn)
};
var expander = traversal.outboundExpander;
var connected;
connected = [ ];
expander(config, g[vnA].document("A")).forEach(function(item) {
connected.push(item.vertex._key);
});
assertEqual([ "B", "D" ], connected);
connected = [ ];
expander(config, g[vnBDH].document("D")).forEach(function(item) {
connected.push(item.vertex._key);
});
assertEqual([ "E", "F" ], connected);
connected = [ ];
expander(config, g[vnBDH].document("H")).forEach(function(item) {
connected.push(item.vertex._key);
});
assertEqual([ ], connected);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test inbound expander
////////////////////////////////////////////////////////////////////////////////
testInboundExpander : function () {
var config = {
sort: function (l, r) { return l._key < r._key ? -1 : 1; },
datasource: traversal.generalGraphDatasourceFactory(gn)
};
var expander = traversal.inboundExpander;
var connected;
connected = [ ];
expander(config, g[vnBDH].document("D")).forEach(function(item) {
connected.push(item.vertex._key);
});
assertEqual([ "A", "C" ], connected);
connected = [ ];
expander(config, g[vnBDH].document("H")).forEach(function(item) {
connected.push(item.vertex._key);
});
assertEqual([ "G", "I" ], connected);
connected = [ ];
expander(config, g[vnA].document("A")).forEach(function(item) {
connected.push(item.vertex._key);
});
assertEqual([ ], connected);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test iteration
////////////////////////////////////////////////////////////////////////////////
testIterateFullOutbound : function () {
var config = {
datasource: traversal.generalGraphDatasourceFactory(gn),
strategy: Traverser.DEPTH_FIRST,
order: Traverser.PRE_ORDER,
itemOrder: Traverser.FORWARD,
filter: traversal.visitAllFilter,
expander: traversal.outboundExpander,
sort: function (l, r) { return l._key < r._key ? -1 : 1; }
};
var traverser = new Traverser(config);
var result = getResult();
traverser.traverse(result, g[vnA].document("A"));
var expectedVisits = [
vnA + "/A",
vnBDH + "/B",
vnCEFGI + "/C",
vnBDH + "/D",
vnCEFGI + "/E",
vnCEFGI + "/F",
vnCEFGI + "/G",
vnBDH + "/H",
vnCEFGI + "/I",
vnBDH + "/H",
vnBDH + "/D",
vnCEFGI + "/E",
vnCEFGI + "/F"
];
assertEqual(expectedVisits, getIds(result.visited.vertices));
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test iteration
////////////////////////////////////////////////////////////////////////////////
testIterateInbound : function () {
var config = {
datasource: traversal.generalGraphDatasourceFactory(gn),
strategy: Traverser.DEPTH_FIRST,
order: Traverser.PRE_ORDER,
itemOrder: Traverser.FORWARD,
filter: traversal.visitAllFilter,
expander: traversal.inboundExpander,
sort: function (l, r) { return l._key < r._key ? -1 : 1; }
};
var result = getResult();
var traverser = new Traverser(config);
traverser.traverse(result, g[vnCEFGI].document("F"));
var expectedVisits = [
vnCEFGI + "/F",
vnBDH + "/D",
vnA + "/A",
vnCEFGI + "/C",
vnBDH + "/B",
vnA + "/A"
];
assertEqual(expectedVisits, getIds(result.visited.vertices));
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test iteration
////////////////////////////////////////////////////////////////////////////////
testIterateUniqueGlobalVertices : function () {
var config = {
datasource: traversal.generalGraphDatasourceFactory(gn),
strategy: Traverser.DEPTH_FIRST,
order: Traverser.PRE_ORDER,
itemOrder: Traverser.FORWARD,
uniqueness: {
vertices: Traverser.UNIQUE_GLOBAL,
edges: Traverser.UNIQUE_NONE
},
filter: traversal.visitAllFilter,
expander: traversal.outboundExpander,
sort: function (l, r) { return l._key < r._key ? -1 : 1; }
};
var result = getResult();
var traverser = new Traverser(config);
traverser.traverse(result, g[vnA].document("A"));
var expectedVisits = [
vnA + "/A",
vnBDH + "/B",
vnCEFGI + "/C",
vnBDH + "/D",
vnCEFGI + "/E",
vnCEFGI + "/F",
vnCEFGI + "/G",
vnBDH + "/H",
vnCEFGI + "/I"
];
assertEqual(expectedVisits, getIds(result.visited.vertices));
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test iteration
////////////////////////////////////////////////////////////////////////////////
testIterateUniquePathVertices : function () {
var config = {
datasource: traversal.generalGraphDatasourceFactory(gn),
strategy: Traverser.DEPTH_FIRST,
order: Traverser.PRE_ORDER,
itemOrder: Traverser.FORWARD,
uniqueness: {
vertices: Traverser.UNIQUE_PATH,
edges: Traverser.UNIQUE_NONE
},
filter: traversal.visitAllFilter,
expander: traversal.outboundExpander,
sort: function (l, r) { return l._key < r._key ? -1 : 1; }
};
var result = getResult();
var traverser = new Traverser(config);
traverser.traverse(result, g[vnA].document("A"));
var expectedVisits = [
vnA + "/A",
vnBDH + "/B",
vnCEFGI + "/C",
vnBDH + "/D",
vnCEFGI + "/E",
vnCEFGI + "/F",
vnCEFGI + "/G",
vnBDH + "/H",
vnCEFGI + "/I",
vnBDH + "/H",
vnBDH + "/D",
vnCEFGI + "/E",
vnCEFGI + "/F"
];
assertEqual(expectedVisits, getIds(result.visited.vertices));
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test iteration
////////////////////////////////////////////////////////////////////////////////
testIterateUniqueEdges : function () {
var config = {
datasource: traversal.generalGraphDatasourceFactory(gn),
strategy: Traverser.DEPTH_FIRST,
order: Traverser.PRE_ORDER,
itemOrder: Traverser.FORWARD,
uniqueness: {
vertices: Traverser.UNIQUE_NONE,
edges: Traverser.UNIQUE_GLOBAL
},
filter: traversal.visitAllFilter,
expander: traversal.outboundExpander,
sort: function (l, r) { return l._key < r._key ? -1 : 1; }
};
var result = getResult();
var traverser = new Traverser(config);
traverser.traverse(result, g[vnA].document("A"));
var expectedVisits = [
vnA + "/A",
vnBDH + "/B",
vnCEFGI + "/C",
vnBDH + "/D",
vnCEFGI + "/E",
vnCEFGI + "/F",
vnCEFGI + "/G",
vnBDH + "/H",
vnCEFGI + "/I",
vnBDH + "/H",
vnBDH + "/D"
];
assertEqual(expectedVisits, getIds(result.visited.vertices));
}
};
}
// -----------------------------------------------------------------------------
// --SECTION-- main
// -----------------------------------------------------------------------------
@ -1867,6 +2232,7 @@ function CollectionTraversalSuite () {
jsunity.run(GraphTraversalSuite);
jsunity.run(MemoryTraversalSuite);
jsunity.run(CollectionTraversalSuite);
jsunity.run(GeneralGraphTraversalSuite);
return jsunity.done();

View File

@ -41,11 +41,10 @@
using namespace triagens;
using namespace std;
ShellImplementation * ShellImplFactory::buildShell(string const & history, Completer * completer) {
ShellImplementation * ShellImplFactory::buildShell (string const & history, Completer * completer) {
#ifdef _WIN32
//under windows the realine is not compilable
//under windows the readline is not compilable
return new LinenoiseShell(history, completer);
#elif defined TRI_HAVE_LINENOISE
return new LinenoiseShell(history, completer);