1
0
Fork 0

fixed merge conflicts

This commit is contained in:
gschwab 2014-06-16 14:27:47 +02:00
commit 229834f5a4
16 changed files with 1053 additions and 250 deletions

10
DEPRECATED.md Normal file
View File

@ -0,0 +1,10 @@
Deprecated Features
-------------------
This file lists all features that have been deprecated in ArangoDB
or are known to become deprecated in a future version of ArangoDB.
Deprecated features will likely be removed in upcoming versions of
ArangoDB and shouldn't be used if possible.
Scheduled removal dates or releases will be listed here. Possible
migrations will also be detailed here.

View File

@ -0,0 +1,103 @@
!CHAPTER Handling Edges
!SECTION Create an edge
`POST /system/gharial/graph-name/edge/collection-name`*(create an edge)*
!SUBSECTION URL parameters
`graph-name (string, required)`
The name of the graph.
`collection-name (string, required)`
The name of the edge collection the edge belongs to.
!SUBSECTION Description
<!-- @startDocuBlock JSF_general_graph_edge_create_info -->
<!-- @startDocuBlock JSF_general_graph_edge_create_http_examples -->
!SECTION Get an edge
`GET /system/gharial/graph-name/edge/collection-name/edge-key`*(get an edge)*
!SUBSECTION URL parameters
`graph-name (string, required)`
The name of the graph.
`collection-name (string, required)`
The name of the edge collection the edge belongs to.
`edge-key (string, required)`
The `_key` attribute of the edge.
!SUBSECTION Description
<!-- @startDocuBlock JSF_general_graph_edge_get_info -->
<!-- @startDocuBlock JSF_general_graph_edge_get_http_examples -->
!SECTION Modify an edge
`PATCH /system/gharial/graph-name/edge/collection-name/edge-key`*(modify an edge)*
!SUBSECTION URL parameters
`graph-name (string, required)`
The name of the graph.
`collection-name (string, required)`
The name of the edge collection the edge belongs to.
`edge-key (string, required)`
The `_key` attribute of the edge.
!SUBSECTION Description
<!-- @startDocuBlock JSF_general_graph_edge_modify_info -->
<!-- @startDocuBlock JSF_general_graph_edge_modify_http_examples -->
!SECTION Replace an edge
`PATCH /system/gharial/graph-name/edge/collection-name/edge-key`*(replace an edge)*
!SUBSECTION URL parameters
`graph-name (string, required)`
The name of the graph.
`collection-name (string, required)`
The name of the edge collection the edge belongs to.
`edge-key (string, required)`
The `_key` attribute of the edge.
!SUBSECTION Description
<!-- @startDocuBlock JSF_general_graph_edge_replace_info -->
<!-- @startDocuBlock JSF_general_graph_edge_replace_http_examples -->
!SECTION Remove an edge
`DELETE /system/gharial/graph-name/edge/collection-name/edge-key`*(remove an edge)*
!SUBSECTION URL parameters
`graph-name (string, required)`
The name of the graph.
`collection-name (string, required)`
The name of the edge collection the edge belongs to.
`edge-key (string, required)`
The `_key` attribute of the edge.
!SUBSECTION Description
<!-- @startDocuBlock JSF_general_graph_edge_delete_info -->
<!-- @startDocuBlock JSF_general_graph_edge_delete_http_examples -->

View File

@ -0,0 +1,150 @@
!CHAPTER Manage your graphs
!SECTION List all graphs
`GET /system/gharial/`*(lists all graphs)*
!SUBSECTION Description
<!-- @startDocuBlock JSF_general_graph_list_info -->
<!-- @startDocuBlock JSF_general_graph_list_http_examples -->
!SECTION Create a graph
`POST /system/gharial/`*(create a graph)*
!SUBSECTION Description
<!-- @startDocuBlock JSF_general_graph_create_info -->
<!-- @startDocuBlock JSF_general_graph_create_http_examples -->
!SECTION Drop a graph
`DELETE /system/gharial/graph-name`*(drop a graph)*
!SUBSECTION URL parameters
`graph-name (string, required)`
The name of the graph.
!SUBSECTION Description
<!-- @startDocuBlock JSF_general_graph_create_info -->
<!-- @startDocuBlock JSF_general_graph_create_http_examples -->
!SECTION List all vertex collections in the graph
`GET /system/gharial/graph-name/vertex`*(lists all vertex collections)*
!SUBSECTION URL parameters
`graph-name (string, required)`
!SUBSECTION Description
<!-- @startDocuBlock JSF_general_graph_list_vertex_info -->
<!-- @startDocuBlock JSF_general_graph_list_vertex_http_examples -->
!SECTION Add a new vertex collection to the graph
`POST /system/gharial/graph-name/vertex`*(add a new vertex collection)*
!SUBSECTION URL parameters
`graph-name (string, required)`
!SUBSECTION Description
<!-- @startDocuBlock JSF_general_graph_vertex_collection_add_info -->
<!-- @startDocuBlock JSF_general_graph_vertex_collection_add_http_examples -->
!SECTION Remove a vertex collection form the graph
`DELETE /system/gharial/graph-name/vertex/collection-name`*(remove a vertex collection)*
!SUBSECTION URL parameters
`graph-name (string, required)`
The name of the graph.
`collection-name (string, required)`
The name of the vertex collection.
!SUBSECTION Description
<!-- @startDocuBlock JSF_general_graph_vertex_collection_remove_info -->
<!-- @startDocuBlock JSF_general_graph_vertex_collection_remove_http_examples -->
!SECTION List all edge definitions in the graph
`GET /system/gharial/graph-name/edge`*(lists all edge definitions)*
!SUBSECTION URL parameters
`graph-name (string, required)`
!SUBSECTION Description
<!-- @startDocuBlock JSF_general_graph_list_edge_info -->
<!-- @startDocuBlock JSF_general_graph_list_edge_http_examples -->
!SECTION Add a new edge definition to the graph
`POST /system/gharial/graph-name/edge`*(add a new edge definition)*
!SUBSECTION URL parameters
`graph-name (string, required)`
!SUBSECTION Description
<!-- @startDocuBlock JSF_general_graph_edge_definition_add_info -->
<!-- @startDocuBlock JSF_general_graph_edge_definition_add_http_examples -->
!SECTION Modify an edge definition
`DELETE /system/gharial/graph-name/edge/definition-name`*(remove a vertex collection)*
!SUBSECTION URL parameters
`graph-name (string, required)`
The name of the graph.
`definition-name (string, required)`
The name of the edge collection used in the definition.
!SUBSECTION Description
<!-- @startDocuBlock JSF_general_graph_edge_definition_modify_info -->
<!-- @startDocuBlock JSF_general_graph_edge_definition_modify_http_examples -->
!SECTION Remove an edge definition form the graph
`DELETE /system/gharial/graph-name/edge/definition-name`*(remove a vertex collection)*
!SUBSECTION URL parameters
`graph-name (string, required)`
The name of the graph.
`definition-name (string, required)`
The name of the edge collection used in the definition.
!SUBSECTION Description
<!-- @startDocuBlock JSF_general_graph_edge_definition_remove_info -->
<!-- @startDocuBlock JSF_general_graph_edge_definition_remove_http_examples -->

View File

@ -0,0 +1,6 @@
!CHAPTER General Graphs
This chapter describes the http interface for the multi-collection graph module.
It allows you to define a graph that is spread across several edge and document collections.
This allows you to structure your models in line with your domain and group them logically in collections and giving you the power to query them in the same graph queries.
There is no need to include the referenced collections within the query, this module will handle it for you.

View File

@ -0,0 +1,103 @@
!CHAPTER Handling Vertices
!SECTION Create a vertex
`POST /system/gharial/graph-name/vertex/collection-name`*(create a vertex)*
!SUBSECTION URL parameters
`graph-name (string, required)`
The name of the graph.
`collection-name (string, required)`
The name of the vertex collection the edge belongs to.
!SUBSECTION Description
<!-- @startDocuBlock JSF_general_graph_vertex_create_info -->
<!-- @startDocuBlock JSF_general_graph_vertex_create_http_examples -->
!SECTION Get a vertex
`GET /system/gharial/graph-name/vertex/collection-name/vertex-key`*(get a vertex)*
!SUBSECTION URL parameters
`graph-name (string, required)`
The name of the graph.
`collection-name (string, required)`
The name of the vertex collection the vertex belongs to.
`vertex-key (string, required)`
The `_key` attribute of the vertex.
!SUBSECTION Description
<!-- @startDocuBlock JSF_general_graph_vertex_get_info -->
<!-- @startDocuBlock JSF_general_graph_vertex_get_http_examples -->
!SECTION Modify an vertex
`PATCH /system/gharial/graph-name/vertex/collection-name/vertex-key`*(modify a vertex)*
!SUBSECTION URL parameters
`graph-name (string, required)`
The name of the graph.
`collection-name (string, required)`
The name of the vertex collection the vertex belongs to.
`vertex-key (string, required)`
The `_key` attribute of the vertex.
!SUBSECTION Description
<!-- @startDocuBlock JSF_general_graph_vertex_modify_info -->
<!-- @startDocuBlock JSF_general_graph_vertex_modify_http_examples -->
!SECTION Replace an vertex
`PATCH /system/gharial/graph-name/vertex/collection-name/vertex-key`*(replace a vertex)*
!SUBSECTION URL parameters
`graph-name (string, required)`
The name of the graph.
`collection-name (string, required)`
The name of the vertex collection the vertex belongs to.
`vertex-key (string, required)`
The `_key` attribute of the vertex.
!SUBSECTION Description
<!-- @startDocuBlock JSF_general_graph_vertex_replace_info -->
<!-- @startDocuBlock JSF_general_graph_vertex_replace_http_examples -->
!SECTION Remove a vertex
`DELETE /system/gharial/graph-name/vertex/collection-name/vertex-key`*(remove a vertex)*
!SUBSECTION URL parameters
`graph-name (string, required)`
The name of the graph.
`collection-name (string, required)`
The name of the vertex collection the vertex belongs to.
`vertex-key (string, required)`
The `_key` attribute of the vertex.
!SUBSECTION Description
<!-- @startDocuBlock JSF_general_graph_vertex_delete_info -->
<!-- @startDocuBlock JSF_general_graph_vertex_delete_http_examples -->

View File

@ -167,6 +167,10 @@
* [Graphs](HttpGraphs/README.md)
* [Vertex](HttpGraphs/Vertex.md)
* [Edges](HttpGraphs/Edge.md)
* [General Graph](HttpGharial/README.md)
* [Management](HttpGharial/Management.md)
* [Vertices](HttpGharial/Vertices.md)
* [Edges](HttpGharial/Edges.md)
* [Traversals](HttpTraversal/README.md)
* [Replication](HttpReplications/README.md)
* [Replication Dump](HttpReplications/ReplicationDump.md)

View File

@ -28,6 +28,11 @@ def edge_endpoint(graph_name, collection)
return URLPREFIX + "/" + graph_name + "/edge/" + collection
end
def list_edge_collections (graph_name)
cmd = URLPREFIX + "/" + graph_name + "/edge"
doc = ArangoDB.get(cmd)
return doc
end
def additional_edge_definition (graph_name, edge_definitions)
cmd = URLPREFIX + "/" + graph_name + "/edge"
@ -47,6 +52,25 @@ def delete_edge_definition (graph_name, definition_name)
return doc
end
def list_vertex_collections (graph_name)
cmd = URLPREFIX + "/" + graph_name + "/vertex"
doc = ArangoDB.get(cmd)
return doc
end
def additional_vertex_collection (graph_name, collection_name)
cmd = URLPREFIX + "/" + graph_name + "/vertex"
body = { :collection => collection_name }
doc = ArangoDB.post(cmd, :body => JSON.dump(body))
return doc
end
def delete_vertex_collection (graph_name, collection_name)
cmd = vertex_endpoint(graph_name, collection_name)
doc = ArangoDB.delete(cmd)
return doc
end
def create_vertex (graph_name, collection, body)
cmd = vertex_endpoint(graph_name, collection)
doc = ArangoDB.post(cmd, :body => JSON.dump(body))
@ -153,7 +177,7 @@ describe ArangoDB do
doc.parsed_response['error'].should eq(false)
doc.parsed_response['code'].should eq(201)
doc.parsed_response['graph']['name'].should eq(graph_name)
# doc.parsed_response['graph']['_rev'].should eq(doc.headers['etag'])
doc.parsed_response['graph']['_rev'].should eq(doc.headers['etag'])
doc.parsed_response['graph']['edgeDefinitions'].should eq(edge_definition)
end
@ -166,7 +190,7 @@ describe ArangoDB do
doc.parsed_response['error'].should eq(false)
doc.parsed_response['code'].should eq(201)
doc.parsed_response['graph']['name'].should eq(graph_name)
# doc.parsed_response['graph']['_rev'].should eq(doc.headers['etag'])
doc.parsed_response['graph']['_rev'].should eq(doc.headers['etag'])
doc.parsed_response['graph']['edgeDefinitions'].should eq(edge_definition)
end
@ -181,7 +205,7 @@ describe ArangoDB do
doc.code.should eq(200)
doc.parsed_response['error'].should eq(false)
doc.parsed_response['code'].should eq(200)
doc.parsed_response['graph']['name'].should eq("#{graph_name}")
doc.parsed_response['graph']['name'].should eq(graph_name)
doc.parsed_response['graph']['_rev'].should eq(doc.headers['etag'])
doc.parsed_response['graph']['edgeDefinitions'].should eq(edge_definition)
end
@ -196,10 +220,54 @@ describe ArangoDB do
doc.code.should eq(200)
doc.parsed_response['error'].should eq(false)
doc.parsed_response['code'].should eq(200)
doc.parsed_response['graph']['name'].should eq("#{graph_name}")
doc.parsed_response['graph']['name'].should eq(graph_name)
doc.parsed_response['graph']['_rev'].should eq(doc.headers['etag'])
doc.parsed_response['graph']['edgeDefinitions'].should eq(edge_definition)
end
it "can delete an edge definition" do
first_def = { "collection" => friend_collection, "from" => [user_collection], "to" => [user_collection] }
edge_definition = [first_def]
create_graph( graph_name, edge_definition )
doc = delete_edge_definition( graph_name, friend_collection )
doc.code.should eq(200)
doc.parsed_response['error'].should eq(false)
doc.parsed_response['code'].should eq(200)
doc.parsed_response['graph']['name'].should eq(graph_name)
doc.parsed_response['graph']['_rev'].should eq(doc.headers['etag'])
doc.parsed_response['graph']['edgeDefinitions'].should eq([])
end
it "can add an additional orphan collection" do
first_def = { "collection" => friend_collection, "from" => [user_collection], "to" => [user_collection] }
edge_definition = [first_def]
create_graph( graph_name, edge_definition )
doc = additional_vertex_collection( graph_name, product_collection )
doc.code.should eq(200)
doc.parsed_response['error'].should eq(false)
doc.parsed_response['code'].should eq(200)
doc.parsed_response['graph']['name'].should eq(graph_name)
doc.parsed_response['graph']['_rev'].should eq(doc.headers['etag'])
doc.parsed_response['graph']['edgeDefinitions'].should eq(edge_definition)
doc.parsed_response['graph']['orphanCollections'].should eq([product_collection])
end
it "can delete an orphan collection" do
first_def = { "collection" => friend_collection, "from" => [user_collection], "to" => [user_collection] }
edge_definition = [first_def]
create_graph( graph_name, edge_definition )
additional_vertex_collection( graph_name, product_collection )
doc = delete_vertex_collection( graph_name, product_collection )
doc.code.should eq(200)
doc.parsed_response['error'].should eq(false)
doc.parsed_response['code'].should eq(200)
doc.parsed_response['graph']['name'].should eq(graph_name)
doc.parsed_response['graph']['_rev'].should eq(doc.headers['etag'])
doc.parsed_response['graph']['edgeDefinitions'].should eq(edge_definition)
doc.parsed_response['graph']['orphanCollections'].should eq([])
end
it "can delete a graph again" do
@ -229,6 +297,30 @@ describe ArangoDB do
doc.parsed_response['error'].should eq("graph already exists")
doc.parsed_response['code'].should eq(409)
end
it "can get a list of vertex collections" do
definition = { "collection" => friend_collection, "from" => [user_collection], "to" => [user_collection] }
create_graph(graph_name, [definition])
additional_vertex_collection(graph_name, product_collection)
doc = list_vertex_collections(graph_name)
doc.code.should eq(200)
doc.parsed_response['error'].should eq(false)
doc.parsed_response['code'].should eq(200)
doc.parsed_response['collections'].should eq([product_collection, user_collection])
end
it "can get a list of edge collections" do
definition1 = { "collection" => friend_collection, "from" => [user_collection], "to" => [user_collection] }
definition2 = { "collection" => bought_collection, "from" => [user_collection], "to" => [product_collection] }
create_graph(graph_name, [definition1, definition2])
doc = list_edge_collections(graph_name)
doc.code.should eq(200)
doc.parsed_response['error'].should eq(false)
doc.parsed_response['code'].should eq(200)
doc.parsed_response['collections'].should eq([bought_collection, friend_collection])
end
end
context "check vertex operations" do

View File

@ -307,6 +307,7 @@ void ArangoClient::parse (ProgramOptions& options,
int argc,
char* argv[],
string const& initFilename) {
// if options are invalid, exit directly
if (! options.parse(description, argc, argv)) {
LOG_FATAL_AND_EXIT("%s", options.lastError().c_str());

View File

@ -1976,7 +1976,7 @@ actions.defineHttp({
/// db._drop(cn);
/// @END_EXAMPLE_ARANGOSH_RUN
/// Using new Signature for attributes WaitForSync and limit
/// @EXAMPLE_ARANGOSH_RUN{RestSimpleReplaceByExample}
/// @EXAMPLE_ARANGOSH_RUN{RestSimpleReplaceByExampleWaitForSync}
/// var cn = "products";
/// db._drop(cn);
/// var products = db._create(cn, { waitForSync: true });

View File

@ -121,17 +121,11 @@ function EventDispatcherControls(list, nodeShaper, edgeShaper, start, dispatcher
},
getCursorPositionInSVG = function (ev) {
var pos = getCursorPosition(ev),
off = $('svg').offset();
// Hack for Firefox
/*
var off = {
left: 166,
top: 171
off = $('svg#graphViewerSVG').offset();
return {
x: pos.x - off.left,
y: pos.y - off.top
};
*/
pos.x -= off.left;
pos.y -= off.top;
return pos;
},
callbacks = {
nodes: {},
@ -214,7 +208,7 @@ function EventDispatcherControls(list, nodeShaper, edgeShaper, start, dispatcher
idprefix = prefix + "_",
nodesDown = dispatcher.events.STARTCREATEEDGE(function(startNode, ev) {
var pos = getCursorPositionInSVG(ev),
moveCB = edgeShaper.addAnEdgeFollowingTheCursor(pos.x, pos.y);
moveCB = edgeShaper.addAnEdgeFollowingTheCursor(pos.x, pos.y);
dispatcher.bind("svg", "mousemove", function(ev) {
var pos = getCursorPositionInSVG(ev);
moveCB(pos.x, pos.y);

View File

@ -1010,7 +1010,7 @@ AQLGenerator.prototype._getLastRestrictableStatementInfo = function() {
///
/// Restriction of a query is only valid for collections known to the graph:
//
/// @EXAMPLE_ARANGOSH_OUTPUT{generalGraphFluentAQLRestricted}
/// @EXAMPLE_ARANGOSH_OUTPUT{generalGraphFluentAQLRestrictedUnknown}
/// var examples = require("org/arangodb/graph-examples/example-graph.js");
/// var g = examples.loadGraph("social");
/// var query = g._vertices({name: "Alice"});
@ -1403,6 +1403,31 @@ var _directedRelationDefinition = function (
};
};
////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSF_general_graph_list_call
/// `general-graph._list()`
/// *List all graphs.*
/// @endDocuBlock
///
/// @startDocuBlock JSF_general_graph_list_info
/// Lists all graph names stored in this database.
///
/// @EXAMPLES
/// @endDocuBlock
/// @startDocuBlock JSF_general_graph_list_examples
///
/// @EXAMPLE_ARANGOSH_OUTPUT{generalGraphList}
/// var graph = require("org/arangodb/general-graph");
/// graph._list();
/// @END_EXAMPLE_ARANGOSH_OUTPUT
/// @endDocuBlock
////////////////////////////////////////////////////////////////////////////////
var _list = function() {
var gdb = getGraphCollection();
return _.pluck(gdb.toArray(), "_key");
};
////////////////////////////////////////////////////////////////////////////////
/// @brief create a list of edge definitions
////////////////////////////////////////////////////////////////////////////////
@ -2079,7 +2104,11 @@ Graph.prototype._edgeCollections = function() {
////////////////////////////////////////////////////////////////////////////////
Graph.prototype._vertexCollections = function() {
return _.values(this.__vertexCollections);
var orphans = [];
_.each(this.__orphanCollections, function(o) {
orphans.push(db[o]);
});
return _.union(_.values(this.__vertexCollections), orphans);
};
////////////////////////////////////////////////////////////////////////////////
@ -2556,21 +2585,23 @@ Graph.prototype._extendEdgeDefinitions = function(edgeDefinition) {
};
////////////////////////////////////////////////////////////////////////////////
/// @brief internal function for editing edge definitions
////////////////////////////////////////////////////////////////////////////////
var changeEdgeDefinitionsForGraph = function(graph, edgeDefinition, newCollections, possibleOrphans, self) {
require("internal").print(graph._key);
//Alte ED austauschen gegen neue
//nicht mehr benutzte Cols ins Waisenhaus
//neu benutzte Cols aus dem Waisenhaus
var currentEdgeDefinition = {};
var oldCollections = [];
var graphCollections = [];
var graphObj = _graph(graph._key);
var eDs = graph.edgeDefinitions;
//replace edgeDefintion
eDs.forEach(
function(eD, id) {
if(eD.collection === edgeDefinition.collection) {
oldCollections = _.union(oldCollections, eD.from);
oldCollections = _.union(oldCollections, eD.to);
eDs[id].from = edgeDefinition.from;
eDs[id].to = edgeDefinition.to;
db._graphs.update(graph._key, {edgeDefinitions: eDs});
@ -2580,62 +2611,52 @@ require("internal").print(graph._key);
}
} else {
//collect all used collections
require("internal").print(eD.collection);
require("internal").print(edgeDefinition.collection);
require("internal").print("1????????????????");
require("internal").print(graphCollections);
graphCollections = _.union(graphCollections, eD.from);
require("internal").print("2????????????????");
require("internal").print(graphCollections);
graphCollections = _.union(graphCollections, eD.to);
}
}
);
require("internal").print("3????????????????");
require("internal").print(graphCollections);
//move unused collections to orphanage
possibleOrphans.forEach(
function(po) {
if (graphCollections.indexOf(po) === -1) {
if (graph.__name = self.__name) {
delete graph.__vertexCollections[po];
}
graph._addOrphanCollection(po);
}
}
);
//remove used collection from orphanage
newCollections.forEach(
function(nc) {
if (graph.__name = self.__name) {
if (graph._key = self.__name) {
if (self.__vertexCollections[nc] === undefined) {
self.__vertexCollections[nc] = db[nc];
}
try {
graph._removeOrphanCollection(nc);
graphObj._removeOrphanCollection(nc);
} catch (e) {
}
}
}
);
//move unused collections to orphanage
possibleOrphans.forEach(
function(po) {
if (graphCollections.indexOf(po) === -1) {
delete graphObj.__vertexCollections[po];
graphObj._addOrphanCollection(po);
}
}
);
};
////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSF_general_graph__editEdgeDefinition
/// Edits the edge definitions of a graph. The edge definition used as argument will
/// replace the existing edge definition of the graph.
/// replace the existing edge definition of the graph which has the same collection.
/// Vertex Collections of the replaced edge definition, that are not used in the new
/// definition will transform to an orphan. Other graphs with the same edge
/// definition will transform to an orphan. Orphans that are used in this new edge
/// definition will be deleted from the list of orphans. Other graphs with the same edge
/// definition will be modified, too.
///
/// `general-graph._editEdgeDefinition(edgeDefinition)`
///
/// *edgeDefinition* - [string] : the edge definition to replace the existing edge
/// definition with the same attribut *collection*.
/// definition with the same attribute *collection*.
///
/// @EXAMPLES
///
@ -2651,13 +2672,8 @@ require("internal").print(graph._key);
///
////////////////////////////////////////////////////////////////////////////////
Graph.prototype._editEdgeDefinitions = function(edgeDefinition) {
require("internal").print("+ + + S T A R T + + +");
var self = this;
var dropCandidates;
// var currentEdgeDefinition = {};
var exOrphanCandidates = [];
var effectedGraphs = [];
//check, if in graphs edge definition
if (this.__edgeCollections[edgeDefinition.collection] === undefined) {
@ -2670,109 +2686,33 @@ Graph.prototype._editEdgeDefinitions = function(edgeDefinition) {
findOrCreateCollectionsByEdgeDefinitions([edgeDefinition]);
//evaluate collections to add to orphanage
var addToOrphanage = [];
var currentEdgeDefinition = this.__edgeCollections[edgeDefinition.collection];
var possibleOrphans = [];
var currentEdgeDefinition;
this.__edgeDefinitions.forEach(
function(ed) {
if (edgeDefinition.collection === ed.collection) {
currentEdgeDefinition = ed;
}
}
);
var currentCollections = _.union(currentEdgeDefinition.from, currentEdgeDefinition.to);
var newCollections = _.union(edgeDefinition.from, edgeDefinition.to);
currentCollections.forEach(
function(colName) {
if (newCollections.indexOf(colName) === -1) {
addToOrphanage.push[colName];
possibleOrphans.push(colName);
}
}
);
//change definition for ALL graphs
var graphs = getGraphCollection().toArray();
graphs.forEach(
function(graph) {
changeEdgeDefinitionsForGraph(graph, edgeDefinition, newCollections, addToOrphanage, self);
changeEdgeDefinitionsForGraph(graph, edgeDefinition, newCollections, possibleOrphans, self);
}
);
require("internal").print("+ + + E N D E + + +");
/* findOrCreateCollectionsByEdgeDefinitions([edgeDefinition]);
//move unused collections to orphanage
graphs = getGraphCollection().toArray();
//eval collection to be dropped
dropCandidates = currentEdgeDefinition.from;
currentEdgeDefinition.to.forEach(
function (col) {
if (dropCandidates.indexOf(col) === -1) {
dropCandidates.push(col);
}
}
);
dropCandidates.forEach(
function(dc) {
if (checkIfMayBeDropped(dc, null, graphs)) {
db._drop(dc);
}
}
);
//push "new" collections into vertexCollections
edgeDefinition.from.forEach(
function(vc) {
if (self.__vertexCollections[vc] === undefined) {
exOrphanCandidates.push(vc);
self.__vertexCollections[vc] = db[vc];
}
}
);
edgeDefinition.to.forEach(
function(vc) {
if (self.__vertexCollections[vc] === undefined) {
exOrphanCandidates.push(vc);
self.__vertexCollections[vc] = db[vc];
}
}
);
//remove "old" collections from vertexCollections
dropCandidates.forEach(
function(dropCanditate) {
var drop = true;
self.__edgeDefinitions.forEach(
function(eD) {
eD.from.forEach(
function(vC) {
if (vC === dropCanditate) {
drop = false;
}
}
);
}
);
if (drop) {
delete self.__vertexCollections[dropCanditate];
}
}
);
//orphans treatment
effectedGraphs.forEach(
function(gN) {
var g;
if (gN === self.__name) {
g = self;
} else {
g = _graph(gN);
}
var orphans = g._getOrphanCollections();
exOrphanCandidates.forEach(
function(eOC) {
if (orphans.indexOf(eOC) !== -1) {
g._removeOrphanCollection(eOC);
}
}
);
}
);*/
};
@ -2914,7 +2854,7 @@ Graph.prototype._addOrphanCollection = function(orphanCollectionName, createColl
/// var examples = require("org/arangodb/graph-examples/example-graph.js");
/// var ed1 = examples._directedRelationDefinition("myEC1", ["myVC1"], ["myVC2"]);
/// var g = examples._create("myGraph", [ed1]);
/// g._addOrphanCollection("myVC3, true);
/// g._addOrphanCollection("myVC3", true);
/// g._getOrphanCollections();
/// @END_EXAMPLE_ARANGOSH_OUTPUT
///
@ -2939,12 +2879,12 @@ Graph.prototype._getOrphanCollections = function() {
///
/// @EXAMPLES
///
/// @EXAMPLE_ARANGOSH_OUTPUT{general_graph__getOrphanCollections}
/// @EXAMPLE_ARANGOSH_OUTPUT{general_graph__removeOrphanCollections}
/// var examples = require("org/arangodb/graph-examples/example-graph.js");
/// var ed1 = examples._directedRelationDefinition("myEC1", ["myVC1"], ["myVC2"]);
/// var g = examples._create("myGraph", [ed1]);
/// g._addOrphanCollection("myVC3, true);
/// g._addOrphanCollection("myVC4, true);
/// g._addOrphanCollection("myVC3", true);
/// g._addOrphanCollection("myVC4", true);
/// g._getOrphanCollections();
/// g._removeOrphanCollection("myVC3");
/// g._getOrphanCollections();
@ -3009,6 +2949,7 @@ exports._extendEdgeDefinitions = _extendEdgeDefinitions;
exports._create = _create;
exports._drop = _drop;
exports._exists = _exists;
exports._list = _list;
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE

View File

@ -36,11 +36,11 @@
actions = require("org/arangodb/actions"),
Model = require("org/arangodb/foxx").Model,
Graph = require("org/arangodb/general-graph"),
_ = require("underscore"),
errors = require("internal").errors,
toId = function(c, k) {
return c + "/" + k;
},
_ = require("underscore"),
setResponse = function (res, name, body, code) {
var obj = {};
obj.error = false;
@ -60,10 +60,331 @@
code = code || actions.HTTP_OK;
setResponse(res, "graph", {
name: g.__name,
edgeDefinitions: g.__edgeDefinitions
edgeDefinitions: g.__edgeDefinitions,
orphanCollections: g._getOrphanCollections()
}, code);
};
////////////////////// Graph Creation /////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSF_general_graph_list_http_examples
/// @EXAMPLE_ARANGOSH_RUN{HttpGharialList}
/// var examples = require("org/arangodb/graph-examples/example-graph.js");
/// examples.loadGraph("social");
/// examples.loadGraph("routeplanner");
/// var url = "/system/gharial";
/// var response = logCurlRequest('GET', url);
///
/// assert(response.code === 200);
///
/// logJsonResponse(response);
/// @END_EXAMPLE_ARANGOSH_RUN
/// @endDocuBlock
////////////////////////////////////////////////////////////////////////////////
/** List graphs
*
* Creates a list of all available graphs.
*/
controller.get("/", function(req, res) {
setResponse(res, "graphs", Graph._list());
});
////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSF_general_graph_create_http_examples
/// @EXAMPLE_ARANGOSH_RUN{HttpGharialList}
/// var url = "/system/gharial";
/// body = {
/// name: "myGraph",
/// edgeDefinitions: [{
/// collection: "edges",
/// from: [ "startVertices" ],
/// to: [ "endVertices" ]
/// }]
/// };
///
/// var response = logCurlRequest('POST', url, JSON.stringify(body));
///
/// assert(response.code === 200);
///
/// logJsonResponse(response);
///
/// var graph = require("org/arangodb/general-graph");
/// graph._drop("myGraph");
///
/// @END_EXAMPLE_ARANGOSH_RUN
/// @endDocuBlock
////////////////////////////////////////////////////////////////////////////////
/** Creates a new graph
*
* Creates a new graph object
*/
controller.post("/", function(req, res) {
var infos = req.params("graph");
var g = Graph._create(infos.get("name"), infos.get("edgeDefinitions"));
setGraphResponse(res, g, actions.HTTP_CREATED);
}).errorResponse(
ArangoError, actions.HTTP_CONFLICT, "Graph creation error.", function(e) {
return {
code: actions.HTTP_CONFLICT,
error: e.errorMessage
};
}
).bodyParam("graph", "The required information for a graph", Model);
////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSF_general_graph_drop_http_examples
/// @EXAMPLE_ARANGOSH_RUN{HttpGharialList}
/// var examples = require("org/arangodb/graph-examples/example-graph.js");
/// examples.loadGraph("social");
/// var url = "/system/gharial/social";
/// var response = logCurlRequest('DELETE', url);
///
/// assert(response.code === 200);
///
/// logJsonResponse(response);
/// @END_EXAMPLE_ARANGOSH_RUN
/// @endDocuBlock
////////////////////////////////////////////////////////////////////////////////
/** Drops an existing graph
*
* Drops an existing graph object by name.
* By default all collections not used by other graphs will be dropped as
* well. It can be optionally configured to not drop the collections.
*/
controller.del("/:graph", function(req, res) {
var name = req.params("graph");
Graph._drop(name);
setResponse(res);
})
.pathParam("graph", {
type: "string",
description: "Name of the graph."
})
.errorResponse(
ArangoError, actions.HTTP_NOT_FOUND, "The graph does not exist.", function(e) {
return {
code: actions.HTTP_NOT_FOUND,
error: e.errorMessage
};
}
);
/////////////////////// Definitions ////////////////////////////////////
/** List all vertex collections.
*
* Gets the list of all vertex collections.
*/
controller.get("/:graph/vertex", function(req, res) {
var name = req.params("graph");
var g = Graph._graph(name);
setResponse(res, "collections", _.map(g._vertexCollections(), function(c) {
return c.name();
}).sort());
})
.pathParam("graph", {
type: "string",
description: "Name of the graph."
})
.errorResponse(
ArangoError, actions.HTTP_NOT_FOUND, "The graph could not be found.", function(e) {
return {
code: actions.HTTP_NOT_FOUND,
error: e.errorMessage
};
}
);
/** Create a new vertex collection.
*
* Stores a new vertex collection.
* This has to contain the vertex-collection name.
*/
controller.post("/:graph/vertex", function(req, res) {
var name = req.params("graph");
var body = req.params("collection");
var g = Graph._graph(name);
g._addOrphanCollection(body.get("collection"));
setGraphResponse(res, g);
})
.pathParam("graph", {
type: "string",
description: "Name of the graph."
})
.bodyParam(
"collection", "The vertex collection to be stored.", Model
)
.errorResponse(
ArangoError, actions.HTTP_BAD, "The vertex collection is invalid.", function(e) {
return {
code: actions.HTTP_BAD,
error: e.errorMessage
};
}
);
/** Delete a vertex collection.
*
* Removes a vertex collection from this graph.
* If this collection is used in one or more edge definitions
* All data stored in the collection is dropped as well as long
* as it is not used in other graphs.
*/
controller.del("/:graph/vertex/:collection", function(req, res) {
var name = req.params("graph");
var def_name = req.params("collection");
var g = Graph._graph(name);
g._removeOrphanCollection(def_name);
setGraphResponse(res, g);
})
.pathParam("graph", {
type: "string",
description: "Name of the graph."
})
.pathParam("collection", {
type: "string",
description: "Name of the vertex collection."
})
.errorResponse(
ArangoError, actions.HTTP_NOT_FOUND,
"The collection is not found or part of an edge definition."
);
/** List all edge collections.
*
* Get the list of all edge collection.
*/
controller.get("/:graph/edge", function(req, res) {
var name = req.params("graph");
var g = Graph._graph(name);
setResponse(res, "collections", _.map(g._edgeCollections(), function(c) {
return c.name();
}).sort());
})
.pathParam("graph", {
type: "string",
description: "Name of the graph."
})
.errorResponse(
ArangoError, actions.HTTP_NOT_FOUND, "The graph could not be found.", function(e) {
return {
code: actions.HTTP_NOT_FOUND,
error: e.errorMessage
};
}
);
/** Create a new edge definition.
*
* Stores a new edge definition with the information contained
* within the body.
* This has to contain the edge-collection name, as well as set of from and to
* collections-names respectively.
*/
controller.post("/:graph/edge", function(req, res) {
var name = req.params("graph");
var body = req.params("edgeDefinition");
var g = Graph._graph(name);
g._extendEdgeDefinitions(body.forDB());
setGraphResponse(res, g);
})
.pathParam("graph", {
type: "string",
description: "Name of the graph."
})
.bodyParam(
"edgeDefinition", "The edge definition to be stored.", Model
)
.errorResponse(
ArangoError, actions.HTTP_BAD, "The edge definition is invalid.", function(e) {
return {
code: actions.HTTP_BAD,
error: e.errorMessage
};
}
);
/** Replace an edge definition.
*
* Replaces an existing edge definition with the information contained
* within the body.
* This has to contain the edge-collection name, as well as set of from and to
* collections-names respectively.
* This will also change the edge definitions of all other graphs using this
* definition as well.
*/
controller.put("/:graph/edge/:definition", function(req, res) {
var name = req.params("graph");
var def_name = req.params("definition");
var body = req.params("edgeDefinition");
var g = Graph._graph(name);
if (def_name !== body.get("collection")) {
var err = new ArangoError();
err.errorNum = errors.ERROR_GRAPH_EDGE_COLLECTION_NOT_USED.code;
err.errorMessage = errors.ERROR_GRAPH_EDGE_COLLECTION_NOT_USED.message;
throw err;
}
g._editEdgeDefinitions(body.forDB());
setGraphResponse(res, g);
})
.pathParam("graph", {
type: "string",
description: "Name of the graph."
})
.pathParam("definition", {
type: "string",
description: "Name of the edge collection in the definition."
})
.bodyParam(
"edgeDefinition", "The edge definition to be stored.", Model
)
.errorResponse(
ArangoError, actions.HTTP_BAD, "The edge definition is invalid.", function(e) {
return {
code: actions.HTTP_BAD,
error: e.errorMessage
};
}
);
/** Delete an edge definition.
*
* Removes an existing edge definition from this graph.
* All data stored in the collections is dropped as well as long
* as it is not used in other graphs.
*/
controller.del("/:graph/edge/:definition", function(req, res) {
var name = req.params("graph");
var def_name = req.params("definition");
var g = Graph._graph(name);
g._deleteEdgeDefinition(def_name);
setGraphResponse(res, g);
})
.pathParam("graph", {
type: "string",
description: "Name of the graph."
})
.pathParam("definition", {
type: "string",
description: "Name of the edge collection in the definition."
})
.errorResponse(
ArangoError, actions.HTTP_NOT_FOUND, "The edge definition is invalid.", function(e) {
return {
code: actions.HTTP_NOT_FOUND,
error: e.errorMessage
};
}
);
////////////////////// Vertex Operations /////////////////////////////////
/** Create a new vertex.
*
* Stores a new vertex with the information contained
@ -229,37 +550,7 @@
}
);
///////////////////////////////////////////////// Edges //////////
/** Create a new edge definition.
*
* Stores a new edge definition with the information contained
* within the body.
* This has to contain the edge-collection name, as well as set of from and to
* collections-names respectively.
*/
controller.post("/:graph/edge", function(req, res) {
var name = req.params("graph");
var body = req.params("edgeDefinition");
var g = Graph._graph(name);
g._extendEdgeDefinitions(body.forDB());
setGraphResponse(res, g);
})
.pathParam("graph", {
type: "string",
description: "Name of the graph."
})
.bodyParam(
"edgeDefinition", "The edge definition to be stored.", Model
)
.errorResponse(
ArangoError, actions.HTTP_BAD, "The edge definition is invalid.", function(e) {
return {
code: actions.HTTP_BAD,
error: e.errorMessage
};
}
);
//////////////////////////// Edge Operations //////////////////////////
/** Create a new edge.
*
@ -446,49 +737,6 @@
}
);
///////////////// GRAPH /////////////////////////////////
/** Creates a new graph
*
* Creates a new graph object
*/
controller.post("/", function(req, res) {
var infos = req.params("graph");
var g = Graph._create(infos.get("name"), infos.get("edgeDefinitions"));
setGraphResponse(res, g, actions.HTTP_CREATED);
}).errorResponse(
ArangoError, actions.HTTP_CONFLICT, "Graph creation error.", function(e) {
return {
code: actions.HTTP_CONFLICT,
error: e.errorMessage
};
}
).bodyParam("graph", "The required information for a graph", Model);
/** Drops an existing graph
*
* Drops an existing graph object by name.
* By default all collections not used by other graphs will be dropped as
* well. It can be optionally configured to not drop the collections.
*/
controller.del("/:graph", function(req, res) {
var name = req.params("graph");
Graph._drop(name);
setResponse(res);
})
.pathParam("graph", {
type: "string",
description: "Name of the graph."
})
.errorResponse(
ArangoError, actions.HTTP_NOT_FOUND, "The graph does not exist.", function(e) {
return {
code: actions.HTTP_NOT_FOUND,
error: e.errorMessage
};
}
);

View File

@ -378,7 +378,7 @@ function cmdUsage () {
var fm = "foxx-manager";
printf("Example usage:\n");
printf(" %s install <foxx> <mount-point>\n", fm);
printf(" %s install <foxx> <mount-point> option1=value1\n", fm);
printf(" %s uninstall <mount-point>\n\n", fm);
printf("Further help:\n");
@ -460,6 +460,43 @@ function fetchDirectoryForInstall (name) {
return exports.fetch("directory", name).app;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief extracts command-line options
////////////////////////////////////////////////////////////////////////////////
function extractCommandLineOptions (args) {
'use strict';
var options = {};
var nargs = [];
var i;
var re1 = /^([-_a-zA-Z0-9]*)=(.*)$/;
var re2 = /^(0|.0|([0-9]*(\.[0-9]*)?))$/;
for (i = 0; i < args.length; ++i) {
var a = args[i];
var m = re1.exec(a);
if (m !== null) {
var k = m[1];
var v = m[2];
if (re2.test(v)) {
options[k] = parseFloat(v);
}
else {
options[k] = v;
}
}
else {
nargs.push(args[i]);
}
}
return { 'options': options, 'args': nargs };
}
// -----------------------------------------------------------------------------
// --SECTION-- public functions
// -----------------------------------------------------------------------------
@ -481,17 +518,37 @@ exports.run = function (args) {
var printf = arangodb.printf;
var res;
function extractOptions () {
var co = extractCommandLineOptions(args);
if (3 < co.args.length) {
var options = JSON.parse(co.args[3]);
if (options.hasOwnProperty("configuration")) {
var k;
for (k in co.options) {
if (co.options.hasOwnProperty(k)) {
options.configuration[k] = co.options[k];
}
}
}
else {
options.configuration = co.options;
}
return options;
}
return { configuration: co.options };
}
try {
if (type === 'fetch') {
exports.fetch(args[1], args[2], args[3]);
}
else if (type === 'mount') {
if (3 < args.length) {
exports.mount(args[1], args[2], JSON.parse(args[3]));
}
else {
exports.mount(args[1], args[2]);
}
exports.mount(args[1], args[2], extractOptions());
}
else if (type === 'rescan') {
exports.rescan();
@ -506,16 +563,13 @@ exports.run = function (args) {
exports.unmount(args[1]);
}
else if (type === 'install') {
if (3 < args.length) {
res = exports.install(args[1], args[2], JSON.parse(args[3]));
}
else {
res = exports.install(args[1], args[2]);
}
var options = extractOptions();
res = exports.install(args[1], args[2], options);
printf("Application %s installed successfully at mount point %s\n",
res.appId,
res.mount);
printf("options used: %s", JSON.stringify(options));
}
else if (type === 'replace') {
if (3 < args.length) {

View File

@ -1009,7 +1009,7 @@ AQLGenerator.prototype._getLastRestrictableStatementInfo = function() {
///
/// Restriction of a query is only valid for collections known to the graph:
//
/// @EXAMPLE_ARANGOSH_OUTPUT{generalGraphFluentAQLRestricted}
/// @EXAMPLE_ARANGOSH_OUTPUT{generalGraphFluentAQLRestrictedUnknown}
/// var examples = require("org/arangodb/graph-examples/example-graph.js");
/// var g = examples.loadGraph("social");
/// var query = g._vertices({name: "Alice"});
@ -1402,6 +1402,31 @@ var _directedRelationDefinition = function (
};
};
////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSF_general_graph_list_call
/// `general-graph._list()`
/// *List all graphs.*
/// @endDocuBlock
///
/// @startDocuBlock JSF_general_graph_list_info
/// Lists all graph names stored in this database.
///
/// @EXAMPLES
/// @endDocuBlock
/// @startDocuBlock JSF_general_graph_list_examples
///
/// @EXAMPLE_ARANGOSH_OUTPUT{generalGraphList}
/// var graph = require("org/arangodb/general-graph");
/// graph._list();
/// @END_EXAMPLE_ARANGOSH_OUTPUT
/// @endDocuBlock
////////////////////////////////////////////////////////////////////////////////
var _list = function() {
var gdb = getGraphCollection();
return _.pluck(gdb.toArray(), "_key");
};
////////////////////////////////////////////////////////////////////////////////
/// @brief create a list of edge definitions
////////////////////////////////////////////////////////////////////////////////
@ -2078,7 +2103,11 @@ Graph.prototype._edgeCollections = function() {
////////////////////////////////////////////////////////////////////////////////
Graph.prototype._vertexCollections = function() {
return _.values(this.__vertexCollections);
var orphans = [];
_.each(this.__orphanCollections, function(o) {
orphans.push(db[o]);
});
return _.union(_.values(this.__vertexCollections), orphans);
};
////////////////////////////////////////////////////////////////////////////////
@ -2816,7 +2845,7 @@ Graph.prototype._addOrphanCollection = function(orphanCollectionName, createColl
/// var examples = require("org/arangodb/graph-examples/example-graph.js");
/// var ed1 = examples._directedRelationDefinition("myEC1", ["myVC1"], ["myVC2"]);
/// var g = examples._create("myGraph", [ed1]);
/// g._addOrphanCollection("myVC3, true);
/// g._addOrphanCollection("myVC3", true);
/// g._getOrphanCollections();
/// @END_EXAMPLE_ARANGOSH_OUTPUT
///
@ -2841,12 +2870,12 @@ Graph.prototype._getOrphanCollections = function() {
///
/// @EXAMPLES
///
/// @EXAMPLE_ARANGOSH_OUTPUT{general_graph__getOrphanCollections}
/// @EXAMPLE_ARANGOSH_OUTPUT{general_graph__removeOrphanCollections}
/// var examples = require("org/arangodb/graph-examples/example-graph.js");
/// var ed1 = examples._directedRelationDefinition("myEC1", ["myVC1"], ["myVC2"]);
/// var g = examples._create("myGraph", [ed1]);
/// g._addOrphanCollection("myVC3, true);
/// g._addOrphanCollection("myVC4, true);
/// g._addOrphanCollection("myVC3", true);
/// g._addOrphanCollection("myVC4", true);
/// g._getOrphanCollections();
/// g._removeOrphanCollection("myVC3");
/// g._getOrphanCollections();
@ -2911,6 +2940,7 @@ exports._extendEdgeDefinitions = _extendEdgeDefinitions;
exports._create = _create;
exports._drop = _drop;
exports._exists = _exists;
exports._list = _list;
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE

View File

@ -88,6 +88,7 @@ function getStorage () {
////////////////////////////////////////////////////////////////////////////////
/// @brief check a manifest for completeness
///
/// this implements issue #590: Manifest Lint
////////////////////////////////////////////////////////////////////////////////
@ -120,14 +121,15 @@ function checkManifest (filename, mf) {
var expected = {
"assets": [ false, "object" ],
"author": [ false, "string" ],
"configuration": [ false, "object" ],
"contributors": [ false, "array" ],
"controllers": [ false, "object" ],
"defaultDocument": [ false, "string" ],
"description": [ true, "string" ],
"engines": [ false, "object" ],
"files": [ false, "object" ],
"keywords": [ false, "array" ],
"isSystem": [ false, "boolean" ],
"keywords": [ false, "array" ],
"lib": [ false, "string" ],
"license": [ false, "string" ],
"name": [ true, "string" ],
@ -363,9 +365,9 @@ function buildFileAsset (app, path, basePath, asset) {
var content = buildAssetContent(app, asset.files, basePath);
var type;
// -----------------------------------------------------------------------------
// .............................................................................
// content-type detection
// -----------------------------------------------------------------------------
// .............................................................................
// contentType explicitly specified for asset
if (asset.hasOwnProperty("contentType") && asset.contentType !== '') {
@ -388,9 +390,9 @@ function buildFileAsset (app, path, basePath, asset) {
type = arangodb.guessContentType("");
}
// -----------------------------------------------------------------------------
// .............................................................................
// return content
// -----------------------------------------------------------------------------
// .............................................................................
return { contentType: type, body: content };
}
@ -528,6 +530,7 @@ function executeAppScript (app, name, mount, prefix) {
appContext.mount = mount;
appContext.collectionPrefix = prefix;
appContext.options = app._options;
appContext.configuration = app._options.configuration;
appContext.basePath = fs.join(root, app._path);
appContext.isDevelopment = devel;
@ -747,6 +750,7 @@ function routingAalApp (app, mount, options) {
appContextTempl.mount = mount; // global mount
appContextTempl.options = options;
appContext.configuration = app._options.configuration;
appContextTempl.collectionPrefix = prefix; // collection prefix
appContextTempl.basePath = fs.join(root, app._path);
@ -908,6 +912,68 @@ function scanDirectory (path) {
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief create configuration
////////////////////////////////////////////////////////////////////////////////
function checkConfiguration (app, options) {
'use strict';
if (options === undefined || options === null) {
options = {};
}
if (! options.hasOwnProperty("configuration")) {
options.configuration = {};
}
if (! app._manifest.hasOwnProperty("configuration")) {
return options;
}
var configuration = options.configuration;
var expected = app._manifest.configuration;
var att;
for (att in expected) {
if (expected.hasOwnProperty(att)) {
if (configuration.hasOwnProperty(att)) {
var value = configuration[att];
var expectedType = expected[att].type;
var actualType = Array.isArray(value) ? "array" : typeof(value);
if (actualType !== expectedType) {
throw new Error(
"configuration for '" + app._manifest.name + "' uses "
+ "an invalid data type (" + actualType + ") "
+ "for " + expectedType + " attribute '" + att + "'");
}
}
else if (expected[att].hasOwnProperty("default")) {
configuration[att] = expected[att]["default"];
}
else {
throw new Error(
"configuration for '" + app._manifest.name + "' is "
+ "missing a value for attribute '" + att + "'");
}
}
}
// additionally check if there are superfluous attributes in the manifest
for (att in configuration) {
if (configuration.hasOwnProperty(att)) {
if (! expected.hasOwnProperty(att)) {
console.warn("configuration for '%s' contains an unknown attribute '%s'",
app._manifest.name,
att);
}
}
}
return options;
}
// -----------------------------------------------------------------------------
// --SECTION-- public functions
// -----------------------------------------------------------------------------
@ -950,6 +1016,7 @@ exports.rescan = function () {
/// * options:
/// collectionPrefix: overwrites the default prefix
/// reload: reload the routing info (default: true)
/// configuration: configuration options
///
/// Output:
/// * appId: the application identifier (must be mounted)
@ -983,7 +1050,7 @@ exports.mount = function (appId, mount, options) {
// install the application
// .............................................................................
options = options || { };
options = checkConfiguration(app, options);
var doc;

View File

@ -370,7 +370,7 @@ Graph.prototype.initialize = function (name, vertices, edges, waitForSync) {
if (from.length !== 1 || to.length !== 1 || from[0] !== to[0]) {
throw newGraphError;
}
}
}
vertices = db._collection(edgeDefinitions[0].from[0]);