mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'devel' of github.com:triAGENS/ArangoDB into devel
This commit is contained in:
commit
f0d65ce57b
|
@ -26,12 +26,8 @@ There are different types of edge defintions:
|
|||
|
||||
!SUBSECTION Edge Definitions
|
||||
|
||||
The edge definitions for a graph is an Array containing arbitrary many directed and/or undirected relations as defined below.
|
||||
The edge definitons array is initialised with the following call:
|
||||
<!-- @startDocuBlock @startDocuBlock JSF_general_graph_edgeDefinitions -->
|
||||
|
||||
```js
|
||||
> var edgeDefinitions = graph._edgeDefinitions(edgeDefinition1,......edgeDefinitionN);
|
||||
```
|
||||
|
||||
To add further edge definitions to the array one must call:
|
||||
|
||||
|
@ -42,11 +38,87 @@ To add further edge definitions to the array one must call:
|
|||
|
||||
!SUBSUBSECTION Undirected Relation
|
||||
|
||||
<!-- @startDocuBlock JSF_general_graph_undirectedRelationDefinition -->
|
||||
|
||||
<br />
|
||||
`general-graph._undirectedRelationDefinition(relationName, vertexCollections)`
|
||||
*Define an undirected relation.*
|
||||
<br />
|
||||
Defines an undirected relation with the name *relationName* using the
|
||||
list of *vertexCollections*. This relation allows the user to store
|
||||
edges in any direction between any pair of vertices within the
|
||||
*vertexCollections*.
|
||||
<br />
|
||||
@EXAMPLES
|
||||
<br />
|
||||
To define simple relation with only one vertex collection:
|
||||
<br />
|
||||
|
||||
```
|
||||
arangosh> var graph = require("org/arangodb/general-graph");
|
||||
arangosh> graph._undirectedRelationDefinition("friend", "user");
|
||||
{
|
||||
"collection" : "friend",
|
||||
"from" : [
|
||||
"user"
|
||||
],
|
||||
"to" : [
|
||||
"user"
|
||||
]
|
||||
}
|
||||
```
|
||||
<br />
|
||||
To define a relation between several vertex collections:
|
||||
<br />
|
||||
|
||||
```
|
||||
arangosh> var graph = require("org/arangodb/general-graph");
|
||||
arangosh> graph._undirectedRelationDefinition("marriage", ["female", "male"]);
|
||||
{
|
||||
"collection" : "marriage",
|
||||
"from" : [
|
||||
"female",
|
||||
"male"
|
||||
],
|
||||
"to" : [
|
||||
"female",
|
||||
"male"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
!SUBSUBSECTION Directed Relation
|
||||
|
||||
<!-- @startDocuBlock JSF_general_graph_undirectedRelationDefinition -->
|
||||
|
||||
<br />
|
||||
`general-graph._directedRelationDefinition(relationName, fromVertexCollections, toVertexCollections)`
|
||||
*Define a directed relation.*
|
||||
<br />
|
||||
The *relationName* defines the name of this relation and references to the underlying edge collection.
|
||||
The *fromVertexCollections* is an Array of document collections holding the start vertices.
|
||||
The *toVertexCollections* is an Array of document collections holding the target vertices.
|
||||
Relations are only allowed in the direction from any collection in *fromVertexCollections*
|
||||
to any collection in *toVertexCollections*.
|
||||
<br />
|
||||
@EXAMPLES
|
||||
<br />
|
||||
|
||||
```
|
||||
arangosh> var graph = require("org/arangodb/general-graph");
|
||||
arangosh> graph._directedRelationDefinition("has_bought", ["Customer", "Company"], ["Groceries", "Electronics"]);
|
||||
{
|
||||
"collection" : "has_bought",
|
||||
"from" : [
|
||||
"Customer",
|
||||
"Company"
|
||||
],
|
||||
"to" : [
|
||||
"Groceries",
|
||||
"Electronics"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
!SUBSUBSECTION Complete Example to create a graph
|
||||
|
@ -81,20 +153,74 @@ alternative call:
|
|||
!SUBSECTION Orphan Collections
|
||||
|
||||
Each graph has an orphan collection. It consists of arbitrary many vertex collection (type *document*), that are not
|
||||
used in an edge definition of the graph. If the graph is extended with an edge definition, which is part of the orphan
|
||||
collection, it will be removed from the orphan collection automatically.
|
||||
used in an edge definition of the graph. If the graph is extended with an edge definition using one of the orphans,
|
||||
it will be removed from the orphan collection automatically.
|
||||
|
||||
!SUBSUBSECTION Add
|
||||
|
||||
<!-- @startDocuBlock JSF_general_graph__addOrphanCollection -->
|
||||
|
||||
Adds a vertex collection to the set of orphan collections of the graph. If the
|
||||
collection does not exist, it will be created.
|
||||
<br />
|
||||
`general-graph._addOrphanCollection(orphanCollectionName, createCollection)`
|
||||
<br />
|
||||
*orphanCollectionName* - string : name of vertex collection.
|
||||
*createCollection* - bool : if true the collection will be created if it does not exist. Default: true.
|
||||
<br />
|
||||
@EXAMPLES
|
||||
<br />
|
||||
|
||||
```
|
||||
arangosh> var graph = require("org/arangodb/general-graph")
|
||||
arangosh> var ed1 = graph._directedRelationDefinition("myEC1", ["myVC1"], ["myVC2"]);
|
||||
arangosh> var g = graph._create("myGraph", [ed1, ed2]);
|
||||
ReferenceError: ed2 is not defined
|
||||
```
|
||||
<br />
|
||||
|
||||
|
||||
!SUBSUBSECTION Read
|
||||
|
||||
<!-- @startDocuBlock JSF_general_graph__getOrphanCollections -->
|
||||
|
||||
Returns all vertex collections of the graph, that are not used in an edge definition.
|
||||
<br />
|
||||
`general-graph._getOrphanCollections()`
|
||||
<br />
|
||||
@EXAMPLES
|
||||
<br />
|
||||
|
||||
```
|
||||
arangosh> var graph = require("org/arangodb/general-graph")
|
||||
arangosh> var ed1 = graph._directedRelationDefinition("myEC1", ["myVC1"], ["myVC2"]);
|
||||
arangosh> var g = graph._create("myGraph", [ed1]);
|
||||
[ArangoError 1925: graph already exists]
|
||||
```
|
||||
<br />
|
||||
|
||||
|
||||
!SUBSUBSECTION Remove
|
||||
|
||||
<!-- @startDocuBlock JSF_general_graph__removeOrphanCollection -->
|
||||
|
||||
Removes an orphan collection from the graph and deletes the collection, if it is not
|
||||
used in any graph.
|
||||
<br />
|
||||
`general-graph._removeOrphanCollection()`
|
||||
<br />
|
||||
*orphanCollectionName* - string : name of vertex collection.
|
||||
*dropCollection* - bool : if true the collection will be dropped if it is not used in any graph.
|
||||
Default: true.
|
||||
<br />
|
||||
@EXAMPLES
|
||||
<br />
|
||||
|
||||
```
|
||||
arangosh> var graph = require("org/arangodb/general-graph")
|
||||
arangosh> var ed1 = graph._directedRelationDefinition("myEC1", ["myVC1"], ["myVC2"]);
|
||||
arangosh> var g = graph._create("myGraph", [ed1]);
|
||||
[ArangoError 1925: graph already exists]
|
||||
```
|
||||
<br />
|
||||
|
||||
|
||||
!SUBSECTION Read a graph
|
||||
|
||||
|
@ -126,47 +252,324 @@ dropCollections: bool - optional. *true* all collections of the graph will be de
|
|||
|
||||
!SUBSECTION Save
|
||||
|
||||
<!-- @startDocuBlock JSF_general_graph_vertex_collection_save -->
|
||||
|
||||
Creates and saves a new vertex in collection *vertexCollectionName*
|
||||
<br />
|
||||
`general-graph.vertexCollectionName.save(data)`
|
||||
<br />
|
||||
*data*: json - data of vertex
|
||||
<br />
|
||||
@EXAMPLES
|
||||
<br />
|
||||
|
||||
```
|
||||
arangosh> var examples = require("org/arangodb/graph-examples/example-graph.js");
|
||||
arangosh> var g = examples.loadGraph("social");
|
||||
arangosh> g.male.save({name: "Floyd", _key: "floyd"});
|
||||
{
|
||||
"error" : false,
|
||||
"_id" : "male/floyd",
|
||||
"_rev" : "91260521",
|
||||
"_key" : "floyd"
|
||||
}
|
||||
```
|
||||
<br />
|
||||
|
||||
|
||||
!SUBSECTION Replace
|
||||
|
||||
<!-- @startDocuBlock JSF_general_graph_vertex_collection_replace -->
|
||||
|
||||
Replaces the data of a vertex in collection *vertexCollectionName*
|
||||
<br />
|
||||
`general-graph.vertexCollectionName.replace(vertexId, data, options)`
|
||||
<br />
|
||||
*vertexId*: string - id of the vertex
|
||||
*data*: json - data of vertex
|
||||
*options*: json - (optional) - see collection documentation
|
||||
<br />
|
||||
@EXAMPLES
|
||||
<br />
|
||||
|
||||
```
|
||||
arangosh> var examples = require("org/arangodb/graph-examples/example-graph.js");
|
||||
arangosh> var g = examples.loadGraph("social");
|
||||
arangosh> g.male.save({neym: "Jon", _key: "john"});
|
||||
{
|
||||
"error" : false,
|
||||
"_id" : "male/john",
|
||||
"_rev" : "31360617",
|
||||
"_key" : "john"
|
||||
}
|
||||
arangosh> g.male.replace("male/john", {name: "John"});
|
||||
{
|
||||
"error" : false,
|
||||
"_id" : "male/john",
|
||||
"_rev" : "31557225",
|
||||
"_key" : "john"
|
||||
}
|
||||
```
|
||||
<br />
|
||||
|
||||
|
||||
!SUBSECTION Update
|
||||
|
||||
<!-- @startDocuBlock JSF_general_graph_vertex_collection_update -->
|
||||
|
||||
Updates the data of a vertex in collection *vertexCollectionName*
|
||||
<br />
|
||||
`general-graph.vertexCollectionName.update(vertexId, data, options)`
|
||||
<br />
|
||||
*vertexId*: string - id of the vertex
|
||||
*data*: json - data of vertex
|
||||
*options*: json - (optional) - see collection documentation
|
||||
<br />
|
||||
@EXAMPLES
|
||||
<br />
|
||||
|
||||
```
|
||||
arangosh> var examples = require("org/arangodb/graph-examples/example-graph.js");
|
||||
arangosh> var g = examples.loadGraph("social");
|
||||
arangosh> g.female.save({name: "Lynda", _key: "linda"});
|
||||
{
|
||||
"error" : false,
|
||||
"_id" : "female/linda",
|
||||
"_rev" : "79201897",
|
||||
"_key" : "linda"
|
||||
}
|
||||
arangosh> g.female.update({name: "Linda", _key: "linda"});
|
||||
TypeError: Object #<Object> has no method 'split'
|
||||
```
|
||||
<br />
|
||||
|
||||
|
||||
!SUBSECTION Remove
|
||||
|
||||
<!-- @startDocuBlock JSF_general_graph_vertex_collection_remove -->
|
||||
|
||||
Removes a vertex in collection *vertexCollectionName*
|
||||
<br />
|
||||
`general-graph.vertexCollectionName.remove(vertexId, options)`
|
||||
<br />
|
||||
Additionally removes all ingoing and outgoing edges of the vertex recursively
|
||||
(see [edge remove](#edge.remove)).
|
||||
<br />
|
||||
@EXAMPLES
|
||||
<br />
|
||||
|
||||
```
|
||||
arangosh> var examples = require("org/arangodb/graph-examples/example-graph.js");
|
||||
arangosh> var g = examples.loadGraph("social");
|
||||
arangosh> g.male.save({name: "Kermit", _key: "kermit"});
|
||||
{
|
||||
"error" : false,
|
||||
"_id" : "male/kermit",
|
||||
"_rev" : "83068521",
|
||||
"_key" : "kermit"
|
||||
}
|
||||
arangosh> db._exists("male/kermit")
|
||||
true
|
||||
arangosh> g.male.remove("male/kermit")
|
||||
true
|
||||
arangosh> db._exists("male/kermit")
|
||||
false
|
||||
```
|
||||
<br />
|
||||
|
||||
|
||||
!SECTION Edge
|
||||
|
||||
!SUBSECTION Save
|
||||
|
||||
<!-- @startDocuBlock JSF_general_graph_edge_collection_save -->
|
||||
|
||||
Creates and saves a new edge from vertex *from* to vertex *to* in
|
||||
collection *edgeCollectionName*
|
||||
<br />
|
||||
`general-graph.edgeCollectionName.save(from, to, data)`
|
||||
<br />
|
||||
*from*: string - id of outgoing vertex
|
||||
*to*: string - of ingoing vertex
|
||||
*data*: json - data of edge
|
||||
<br />
|
||||
@EXAMPLES
|
||||
<br />
|
||||
|
||||
```
|
||||
arangosh> var examples = require("org/arangodb/graph-examples/example-graph.js");
|
||||
arangosh> var g = examples.loadGraph("social");
|
||||
arangosh> g.relation.save("male/bob", "female/alice", {type: "married", _key: "bobAndAlice"});
|
||||
{
|
||||
"error" : false,
|
||||
"_id" : "relation/bobAndAlice",
|
||||
"_rev" : "45909609",
|
||||
"_key" : "bobAndAlice"
|
||||
}
|
||||
```
|
||||
<br />
|
||||
If the collections of *from* and *to* are not defined in an edgeDefinition of the graph,
|
||||
the edge will not be stored.
|
||||
<br />
|
||||
<br />
|
||||
|
||||
```
|
||||
arangosh> var examples = require("org/arangodb/graph-examples/example-graph.js");
|
||||
arangosh> var g = examples.loadGraph("social");
|
||||
arangosh> g.relation.save("relation/aliceAndBob", "female/alice", {type: "married", _key: "bobAndAlice"});
|
||||
Edge is not allowed between relation/aliceAndBob and female/alice.
|
||||
```
|
||||
|
||||
|
||||
!SUBSECTION Replace
|
||||
|
||||
<!-- @startDocuBlock JSF_general_graph_edge_collection_replace -->
|
||||
|
||||
Replaces the data of an edge in collection *edgeCollectionName*
|
||||
<br />
|
||||
`general-graph.edgeCollectionName.replace(edgeId, data, options)`
|
||||
<br />
|
||||
*edgeId*: string - id of the edge
|
||||
*data*: json - data of edge
|
||||
*options*: json - (optional) - see collection documentation
|
||||
<br />
|
||||
@EXAMPLES
|
||||
<br />
|
||||
|
||||
```
|
||||
arangosh> var examples = require("org/arangodb/graph-examples/example-graph.js");
|
||||
arangosh> var g = examples.loadGraph("social");
|
||||
arangosh> g.relation.save("female/alice", "female/diana", {typo: "nose", _key: "aliceAndDiana"});
|
||||
{
|
||||
"error" : false,
|
||||
"_id" : "relation/aliceAndDiana",
|
||||
"_rev" : "27362921",
|
||||
"_key" : "aliceAndDiana"
|
||||
}
|
||||
arangosh> g.relation.replace("relation/aliceAndDiana", {type: "knows"});
|
||||
{
|
||||
"error" : false,
|
||||
"_id" : "relation/aliceAndDiana",
|
||||
"_rev" : "27559529",
|
||||
"_key" : "aliceAndDiana"
|
||||
}
|
||||
```
|
||||
<br />
|
||||
|
||||
|
||||
!SUBSECTION Update
|
||||
|
||||
<!-- @startDocuBlock JSF_general_graph_edge_collection_update -->
|
||||
|
||||
Updates the data of an edge in collection *edgeCollectionName*
|
||||
<br />
|
||||
`general-graph.edgeCollectionName.update(edgeId, data, options)`
|
||||
<br />
|
||||
*edgeId*: string - id of the edge
|
||||
*data*: json - data of edge
|
||||
*options*: json - (optional) - see collection documentation
|
||||
<br />
|
||||
@EXAMPLES
|
||||
<br />
|
||||
|
||||
```
|
||||
arangosh> var examples = require("org/arangodb/graph-examples/example-graph.js");
|
||||
arangosh> var g = examples.loadGraph("social");
|
||||
arangosh> g.relation.save("female/alice", "female/diana", {type: "knows", _key: "aliceAndDiana"});
|
||||
{
|
||||
"error" : false,
|
||||
"_id" : "relation/aliceAndDiana",
|
||||
"_rev" : "127108713",
|
||||
"_key" : "aliceAndDiana"
|
||||
}
|
||||
arangosh> g.relation.update("relation/aliceAndDiana", {type: "quarrelled", _key: "aliceAndDiana"});
|
||||
{
|
||||
"error" : false,
|
||||
"_id" : "relation/aliceAndDiana",
|
||||
"_rev" : "127305321",
|
||||
"_key" : "aliceAndDiana"
|
||||
}
|
||||
```
|
||||
<br />
|
||||
|
||||
|
||||
!SUBSECTION Remove
|
||||
|
||||
<!-- @startDocuBlock JSF_general_graph_edge_collection_remove -->
|
||||
|
||||
Removes an edge in collection *edgeCollectionName*
|
||||
<br />
|
||||
`general-graph.edgeCollectionName.remove(edgeId, options)`
|
||||
<br />
|
||||
If this edge is used as a vertex by another edge, the other edge will be removed (recursively).
|
||||
<br />
|
||||
@EXAMPLES
|
||||
<br />
|
||||
|
||||
```
|
||||
arangosh> var examples = require("org/arangodb/graph-examples/example-graph.js");
|
||||
arangosh> var g = examples.loadGraph("social");
|
||||
arangosh> g.relation.save("female/alice", "female/diana", {_key: "aliceAndDiana"});
|
||||
{
|
||||
"error" : false,
|
||||
"_id" : "relation/aliceAndDiana",
|
||||
"_rev" : "141657705",
|
||||
"_key" : "aliceAndDiana"
|
||||
}
|
||||
arangosh> db._exists("relation/aliceAndDiana")
|
||||
true
|
||||
arangosh> g.relation.remove("relation/aliceAndDiana")
|
||||
true
|
||||
arangosh> db._exists("relation/aliceAndDiana")
|
||||
false
|
||||
```
|
||||
<br />
|
||||
|
||||
|
||||
!SECTION Vertices
|
||||
|
||||
!SUBSECTION Get vertex *from* of an edge
|
||||
|
||||
<!-- @startDocuBlock JSF_general_graph_getFromVertex -->
|
||||
|
||||
Get the vertex of an edge defined as *_from*
|
||||
<br />
|
||||
`general-graph._getFromVertex(edgeId)`
|
||||
<br />
|
||||
Returns the vertex defined with the attribute *_from* of the edge with *edgeId* as its *_id*.
|
||||
<br />
|
||||
@EXAMPLES
|
||||
<br />
|
||||
|
||||
```
|
||||
arangosh> var examples = require("org/arangodb/graph-examples/example-graph.js");
|
||||
arangosh> var g = examples.loadGraph("social");
|
||||
arangosh> g._getFromVertex("relation/aliceAndBob")
|
||||
{
|
||||
"name" : "Alice",
|
||||
"_id" : "female/alice",
|
||||
"_rev" : "175670889",
|
||||
"_key" : "alice"
|
||||
}
|
||||
```
|
||||
<br />
|
||||
|
||||
|
||||
!SUBSECTION Get vertex *to* of an edge
|
||||
|
||||
<!-- @startDocuBlock JSF_general_graph_getToVertex -->
|
||||
|
||||
Get the vertex of an edge defined as *_to*
|
||||
<br />
|
||||
`general-graph._getToVertex(edgeId)`
|
||||
<br />
|
||||
Returns the vertex defined with the attribute *_to* of the edge with *edgeId* as its *_id*.
|
||||
<br />
|
||||
@EXAMPLES
|
||||
<br />
|
||||
|
||||
```
|
||||
arangosh> var examples = require("org/arangodb/graph-examples/example-graph.js");
|
||||
arangosh> var g = examples.loadGraph("social");
|
||||
arangosh> g._getToVertex("relation/aliceAndBob")
|
||||
{
|
||||
"name" : "Bob",
|
||||
"_id" : "male/bob",
|
||||
"_rev" : "40666729",
|
||||
"_key" : "bob"
|
||||
}
|
||||
```
|
||||
<br />
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -216,6 +216,8 @@
|
|||
"ERROR_GRAPH_VERTEX_COL_DOES_NOT_EXIST" : { "code" : 1926, "message" : "collection does not exist" },
|
||||
"ERROR_GRAPH_WRONG_COLLECTION_TYPE_VERTEX" : { "code" : 1927, "message" : "not a vertex collection" },
|
||||
"ERROR_GRAPH_NOT_IN_ORPHAN_COLLECTION" : { "code" : 1928, "message" : "not in orphan collection" },
|
||||
"ERROR_GRAPH_COLLECTION_USED_IN_EDGE_DEF" : { "code" : 1929, "message" : "collection used in edge def" },
|
||||
"ERROR_GRAPH_EDGE_COLLECTION_NOT_USED" : { "code" : 1930, "message" : "edge collection not used in graph" },
|
||||
"ERROR_SESSION_UNKNOWN" : { "code" : 1950, "message" : "unknown session" },
|
||||
"ERROR_SESSION_EXPIRED" : { "code" : 1951, "message" : "session expired" },
|
||||
"SIMPLE_CLIENT_UNKNOWN_ERROR" : { "code" : 2000, "message" : "unknown client error" },
|
||||
|
|
|
@ -2033,7 +2033,8 @@ var checkIfMayBeDropped = function(colName, graphName, graphs) {
|
|||
|
||||
var _drop = function(graphId, dropCollections) {
|
||||
|
||||
var gdb = getGraphCollection();
|
||||
var gdb = getGraphCollection(),
|
||||
graphs;
|
||||
|
||||
if (!gdb.exists(graphId)) {
|
||||
var err = new ArangoError();
|
||||
|
@ -2050,7 +2051,7 @@ var _drop = function(graphId, dropCollections) {
|
|||
var from = edgeDefinition.from;
|
||||
var to = edgeDefinition.to;
|
||||
var collection = edgeDefinition.collection;
|
||||
var graphs = getGraphCollection().toArray();
|
||||
graphs = getGraphCollection().toArray();
|
||||
if (checkIfMayBeDropped(collection, graph._key, graphs)) {
|
||||
db._drop(collection);
|
||||
}
|
||||
|
@ -2070,6 +2071,20 @@ var _drop = function(graphId, dropCollections) {
|
|||
);
|
||||
}
|
||||
);
|
||||
//drop orphans
|
||||
graphs = getGraphCollection().toArray();
|
||||
if (!graph.orphanCollections) {
|
||||
graph.orphanCollections = [];
|
||||
}
|
||||
graph.orphanCollections.forEach(
|
||||
function(oC) {
|
||||
if (checkIfMayBeDropped(oC, graph._key, graphs)) {
|
||||
try {
|
||||
db._drop(oC);
|
||||
} catch (e) {}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
gdb.remove(graphId);
|
||||
|
@ -2482,9 +2497,10 @@ Graph.prototype._amountCommonProperties = function(vertex1Example, vertex2Exampl
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @startDocuBlock JSF_general_graph__extendEdgeDefinitions
|
||||
/// Extends the edge definitions of a graph. If the edge collection of the edge definition
|
||||
/// to add is already used in the graph or used in a different graph with different from
|
||||
/// an to collections an error is thrown.
|
||||
/// Extends the edge definitions of a graph. If an orphan collection is used in this
|
||||
/// edge definitino, it will be removed from the orphenage. If the edge collection of
|
||||
/// the edge definition to add is already used in the graph or used in a different
|
||||
/// graph with different from an to collections an error is thrown.
|
||||
///
|
||||
/// `general-graph._extendEdgeDefinitions(edgeDefinition)`
|
||||
///
|
||||
|
@ -2570,19 +2586,78 @@ Graph.prototype._extendEdgeDefinitions = function(edgeDefinition) {
|
|||
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief internal function for editing edge definitions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var changeEdgeDefinitionsForGraph = function(graph, edgeDefinition, newCollections, possibleOrphans, self) {
|
||||
|
||||
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});
|
||||
if (graph._key === self.__name) {
|
||||
self.__edgeDefinitions[id].from = edgeDefinition.from;
|
||||
self.__edgeDefinitions[id].to = edgeDefinition.to;
|
||||
}
|
||||
} else {
|
||||
//collect all used collections
|
||||
graphCollections = _.union(graphCollections, eD.from);
|
||||
graphCollections = _.union(graphCollections, eD.to);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
//remove used collection from orphanage
|
||||
newCollections.forEach(
|
||||
function(nc) {
|
||||
if (graph._key === self.__name) {
|
||||
if (self.__vertexCollections[nc] === undefined) {
|
||||
self.__vertexCollections[nc] = db[nc];
|
||||
}
|
||||
try {
|
||||
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 the corresponding edge definition in graphs
|
||||
/// edge definitions. Other graphs with the same edge definition will be modified, too.
|
||||
/// 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. 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, dropCollections)`
|
||||
/// `general-graph._editEdgeDefinition(edgeDefinition)`
|
||||
///
|
||||
/// *edgeDefinition* - [string] : the edge definition to replace the existing edge
|
||||
/// definition with the same attribut *collection*.
|
||||
/// *dropCollections* - bool : True, all collections that are not used anymore in any
|
||||
/// graph will be removed. Default: true.
|
||||
/// definition with the same attribute *collection*.
|
||||
///
|
||||
/// @EXAMPLES
|
||||
///
|
||||
|
@ -2597,13 +2672,9 @@ Graph.prototype._extendEdgeDefinitions = function(edgeDefinition) {
|
|||
/// @endDocuBlock
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Graph.prototype._editEdgeDefinitions = function(edgeDefinition, dropCollections) {
|
||||
var self = this;
|
||||
var dropCandidates;
|
||||
var currentEdgeDefinition = {};
|
||||
var exOrphanCandidates = [];
|
||||
var effectedGraphs = [];
|
||||
Graph.prototype._editEdgeDefinitions = function(edgeDefinition) {
|
||||
|
||||
var self = this;
|
||||
|
||||
//check, if in graphs edge definition
|
||||
if (this.__edgeCollections[edgeDefinition.collection] === undefined) {
|
||||
|
@ -2613,108 +2684,33 @@ Graph.prototype._editEdgeDefinitions = function(edgeDefinition, dropCollections)
|
|||
throw err;
|
||||
}
|
||||
|
||||
findOrCreateCollectionsByEdgeDefinitions([edgeDefinition]);
|
||||
|
||||
//evaluate collections to add to orphanage
|
||||
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) {
|
||||
possibleOrphans.push(colName);
|
||||
}
|
||||
}
|
||||
);
|
||||
//change definition for ALL graphs
|
||||
var graphs = getGraphCollection().toArray();
|
||||
graphs.forEach(
|
||||
function(graph) {
|
||||
var eDs = graph.edgeDefinitions;
|
||||
eDs.forEach(
|
||||
function(eD, id) {
|
||||
if(eD.collection === edgeDefinition.collection) {
|
||||
currentEdgeDefinition.from = eD.from;
|
||||
currentEdgeDefinition.to = eD.to;
|
||||
eDs[id].from = edgeDefinition.from;
|
||||
eDs[id].to = edgeDefinition.to;
|
||||
db._graphs.update(graph._key, {edgeDefinitions: eDs});
|
||||
effectedGraphs.push(graph._key);
|
||||
if (graph._key === self.__name) {
|
||||
self.__edgeDefinitions[id].from = edgeDefinition.from;
|
||||
self.__edgeDefinitions[id].to = edgeDefinition.to;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
findOrCreateCollectionsByEdgeDefinitions([edgeDefinition]);
|
||||
|
||||
if (dropCollections !== false) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
);
|
||||
changeEdgeDefinitionsForGraph(graph, edgeDefinition, newCollections, possibleOrphans, self);
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -2725,14 +2721,12 @@ Graph.prototype._editEdgeDefinitions = function(edgeDefinition, dropCollections)
|
|||
/// @startDocuBlock JSF_general_graph__deleteEdgeDefinition
|
||||
/// Deletes an edge definition defined by the edge collection of a graph. If the
|
||||
/// collections defined in the edge definition (collection, from, to) are not used
|
||||
/// in another graph, they will be removed.
|
||||
/// in another edge definition of the graph, they will be moved to the orphanage.
|
||||
///
|
||||
/// `general-graph._deleteEdgeDefinition(edgeCollectionName, dropCollections)`
|
||||
/// `general-graph._deleteEdgeDefinition(edgeCollectionName)`
|
||||
///
|
||||
/// *edgeCollectionName* - string : name of edge collection defined in *collection* of the edge
|
||||
/// definition.
|
||||
/// *dropCollections* - bool : True, all collections are removed, if not used in another edge
|
||||
/// definition (including other graphs). Default: true.
|
||||
///
|
||||
/// @EXAMPLES
|
||||
///
|
||||
|
@ -2741,56 +2735,49 @@ Graph.prototype._editEdgeDefinitions = function(edgeDefinition, dropCollections)
|
|||
/// var ed1 = examples._directedRelationDefinition("myEC1", ["myVC1"], ["myVC2"]);
|
||||
/// var ed2 = examples._directedRelationDefinition("myEC2", ["myVC1"], ["myVC3"]);
|
||||
/// var g = examples._create("myGraph", [ed1, ed2]);
|
||||
/// g._deleteEdgeDefinition("myEC1", true);
|
||||
/// g._deleteEdgeDefinition("myEC1");
|
||||
/// @END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
///
|
||||
/// @endDocuBlock
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Graph.prototype._deleteEdgeDefinition = function(edgeCollection, dropCollections) {
|
||||
Graph.prototype._deleteEdgeDefinition = function(edgeCollection) {
|
||||
|
||||
//check, if in graphs edge definition
|
||||
if (this.__edgeCollections[edgeCollection] === undefined) {
|
||||
var err = new ArangoError();
|
||||
err.errorNum = arangodb.errors.ERROR_GRAPH_EDGE_COLLECTION_NOT_USED.code;
|
||||
err.errorMessage = arangodb.errors.ERROR_GRAPH_EDGE_COLLECTION_NOT_USED.message;
|
||||
throw err;
|
||||
}
|
||||
|
||||
var edgeDefinitions = this.__edgeDefinitions,
|
||||
vertexCollections = [],
|
||||
definitionFound = false,
|
||||
self = this,
|
||||
usedVertexCollections = [],
|
||||
possibleOrphans = [],
|
||||
index;
|
||||
|
||||
edgeDefinitions.forEach(
|
||||
function(edgeDefinition, idx) {
|
||||
if (edgeDefinition.collection === edgeCollection) {
|
||||
definitionFound = true;
|
||||
if (dropCollections !== false) {
|
||||
//get all vertex collections
|
||||
var vertexCols = edgeDefinition.from.concat(edgeDefinition.to);
|
||||
vertexCols.forEach(
|
||||
function(vertexCol) {
|
||||
if (vertexCollections.indexOf(vertexCol) === -1) {
|
||||
vertexCollections.push(vertexCol);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
index = idx;
|
||||
possibleOrphans = edgeDefinition.from;
|
||||
possibleOrphans = _.union(possibleOrphans, edgeDefinition.to);
|
||||
} else {
|
||||
usedVertexCollections = _.union(usedVertexCollections, edgeDefinition.from);
|
||||
usedVertexCollections = _.union(usedVertexCollections, edgeDefinition.to);
|
||||
}
|
||||
}
|
||||
);
|
||||
if (definitionFound) {
|
||||
edgeDefinitions.splice(index, 1);
|
||||
this.__edgeDefinitions = edgeDefinitions;
|
||||
db._graphs.update(this.__name, {edgeDefinitions: this.__edgeDefinitions});
|
||||
}
|
||||
if (dropCollections !== false) {
|
||||
if (checkIfMayBeDropped(edgeCollection, this.__name, getGraphCollection().toArray())) {
|
||||
db._drop(edgeCollection);
|
||||
}
|
||||
vertexCollections.forEach(
|
||||
function(vC) {
|
||||
if (checkIfMayBeDropped(vC, this.__name, getGraphCollection().toArray())) {
|
||||
db._drop(vC);
|
||||
}
|
||||
this.__edgeDefinitions.splice(index, 1);
|
||||
possibleOrphans.forEach(
|
||||
function(po) {
|
||||
if (usedVertexCollections.indexOf(po) === -1) {
|
||||
self.__orphanCollections.push(po);
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -2816,17 +2803,17 @@ Graph.prototype._deleteEdgeDefinition = function(edgeCollection, dropCollections
|
|||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Graph.prototype._addOrphanCollection = function(vertexCollection, createCollection) {
|
||||
Graph.prototype._addOrphanCollection = function(orphanCollectionName, createCollection) {
|
||||
//check edgeCollection
|
||||
var ec = db._collection(vertexCollection);
|
||||
var ec = db._collection(orphanCollectionName);
|
||||
var err;
|
||||
if (ec === null) {
|
||||
if (createCollection !== false) {
|
||||
db._create(vertexCollection);
|
||||
db._create(orphanCollectionName);
|
||||
} else {
|
||||
err = new ArangoError();
|
||||
err.errorNum = arangodb.errors.ERROR_GRAPH_VERTEX_COL_DOES_NOT_EXIST.code;
|
||||
err.errorMessage = vertexCollection + arangodb.errors.ERROR_GRAPH_VERTEX_COL_DOES_NOT_EXIST.message;
|
||||
err.errorMessage = orphanCollectionName + arangodb.errors.ERROR_GRAPH_VERTEX_COL_DOES_NOT_EXIST.message;
|
||||
throw err;
|
||||
}
|
||||
} else if (ec.type() !== 2) {
|
||||
|
@ -2835,8 +2822,14 @@ Graph.prototype._addOrphanCollection = function(vertexCollection, createCollecti
|
|||
err.errorMessage = arangodb.errors.ERROR_GRAPH_WRONG_COLLECTION_TYPE_VERTEX.message;
|
||||
throw err;
|
||||
}
|
||||
if (this.__vertexCollections[orphanCollectionName] !== undefined) {
|
||||
err = new ArangoError();
|
||||
err.errorNum = arangodb.errors.ERROR_GRAPH_COLLECTION_USED_IN_EDGE_DEF.code;
|
||||
err.errorMessage = arangodb.errors.ERROR_GRAPH_COLLECTION_USED_IN_EDGE_DEF.message;
|
||||
throw err;
|
||||
}
|
||||
|
||||
this.__orphanCollections.push(vertexCollection);
|
||||
this.__orphanCollections.push(orphanCollectionName);
|
||||
db._graphs.update(this.__name, {orphanCollections: this.__orphanCollections});
|
||||
|
||||
};
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -216,6 +216,8 @@
|
|||
"ERROR_GRAPH_VERTEX_COL_DOES_NOT_EXIST" : { "code" : 1926, "message" : "collection does not exist" },
|
||||
"ERROR_GRAPH_WRONG_COLLECTION_TYPE_VERTEX" : { "code" : 1927, "message" : "not a vertex collection" },
|
||||
"ERROR_GRAPH_NOT_IN_ORPHAN_COLLECTION" : { "code" : 1928, "message" : "not in orphan collection" },
|
||||
"ERROR_GRAPH_COLLECTION_USED_IN_EDGE_DEF" : { "code" : 1929, "message" : "collection used in edge def" },
|
||||
"ERROR_GRAPH_EDGE_COLLECTION_NOT_USED" : { "code" : 1930, "message" : "edge collection not used in graph" },
|
||||
"ERROR_SESSION_UNKNOWN" : { "code" : 1950, "message" : "unknown session" },
|
||||
"ERROR_SESSION_EXPIRED" : { "code" : 1951, "message" : "session expired" },
|
||||
"SIMPLE_CLIENT_UNKNOWN_ERROR" : { "code" : 2000, "message" : "unknown client error" },
|
||||
|
|
|
@ -2032,7 +2032,8 @@ var checkIfMayBeDropped = function(colName, graphName, graphs) {
|
|||
|
||||
var _drop = function(graphId, dropCollections) {
|
||||
|
||||
var gdb = getGraphCollection();
|
||||
var gdb = getGraphCollection(),
|
||||
graphs;
|
||||
|
||||
if (!gdb.exists(graphId)) {
|
||||
var err = new ArangoError();
|
||||
|
@ -2049,7 +2050,7 @@ var _drop = function(graphId, dropCollections) {
|
|||
var from = edgeDefinition.from;
|
||||
var to = edgeDefinition.to;
|
||||
var collection = edgeDefinition.collection;
|
||||
var graphs = getGraphCollection().toArray();
|
||||
graphs = getGraphCollection().toArray();
|
||||
if (checkIfMayBeDropped(collection, graph._key, graphs)) {
|
||||
db._drop(collection);
|
||||
}
|
||||
|
@ -2069,6 +2070,20 @@ var _drop = function(graphId, dropCollections) {
|
|||
);
|
||||
}
|
||||
);
|
||||
//drop orphans
|
||||
graphs = getGraphCollection().toArray();
|
||||
if (!graph.orphanCollections) {
|
||||
graph.orphanCollections = [];
|
||||
}
|
||||
graph.orphanCollections.forEach(
|
||||
function(oC) {
|
||||
if (checkIfMayBeDropped(oC, graph._key, graphs)) {
|
||||
try {
|
||||
db._drop(oC);
|
||||
} catch (e) {}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
gdb.remove(graphId);
|
||||
|
@ -2481,9 +2496,10 @@ Graph.prototype._amountCommonProperties = function(vertex1Example, vertex2Exampl
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @startDocuBlock JSF_general_graph__extendEdgeDefinitions
|
||||
/// Extends the edge definitions of a graph. If the edge collection of the edge definition
|
||||
/// to add is already used in the graph or used in a different graph with different from
|
||||
/// an to collections an error is thrown.
|
||||
/// Extends the edge definitions of a graph. If an orphan collection is used in this
|
||||
/// edge definitino, it will be removed from the orphenage. If the edge collection of
|
||||
/// the edge definition to add is already used in the graph or used in a different
|
||||
/// graph with different from an to collections an error is thrown.
|
||||
///
|
||||
/// `general-graph._extendEdgeDefinitions(edgeDefinition)`
|
||||
///
|
||||
|
@ -2492,10 +2508,10 @@ Graph.prototype._amountCommonProperties = function(vertex1Example, vertex2Exampl
|
|||
/// @EXAMPLES
|
||||
///
|
||||
/// @EXAMPLE_ARANGOSH_OUTPUT{general_graph__extendEdgeDefinitions}
|
||||
/// var examples = require("org/arangodb/graph-examples/example-graph.js");
|
||||
/// var ed1 = examples._directedRelationDefinition("myEC1", ["myVC1"], ["myVC2"]);
|
||||
/// var ed2 = examples._directedRelationDefinition("myEC2", ["myVC1"], ["myVC3"]);
|
||||
/// var g = examples._create("myGraph", [ed1]);
|
||||
/// var graph = require("org/arangodb/general-graph")
|
||||
/// var ed1 = graph._directedRelationDefinition("myEC1", ["myVC1"], ["myVC2"]);
|
||||
/// var ed2 = graph._directedRelationDefinition("myEC2", ["myVC1"], ["myVC3"]);
|
||||
/// var g = graph._create("myGraph", [ed1]);
|
||||
/// g._extendEdgeDefinitions(ed2);
|
||||
/// @END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
///
|
||||
|
@ -2569,40 +2585,95 @@ Graph.prototype._extendEdgeDefinitions = function(edgeDefinition) {
|
|||
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief internal function for editing edge definitions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var changeEdgeDefinitionsForGraph = function(graph, edgeDefinition, newCollections, possibleOrphans, self) {
|
||||
|
||||
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});
|
||||
if (graph._key === self.__name) {
|
||||
self.__edgeDefinitions[id].from = edgeDefinition.from;
|
||||
self.__edgeDefinitions[id].to = edgeDefinition.to;
|
||||
}
|
||||
} else {
|
||||
//collect all used collections
|
||||
graphCollections = _.union(graphCollections, eD.from);
|
||||
graphCollections = _.union(graphCollections, eD.to);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
//remove used collection from orphanage
|
||||
newCollections.forEach(
|
||||
function(nc) {
|
||||
if (graph._key === self.__name) {
|
||||
if (self.__vertexCollections[nc] === undefined) {
|
||||
self.__vertexCollections[nc] = db[nc];
|
||||
}
|
||||
try {
|
||||
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 the corresponding edge definition in graphs
|
||||
/// edge definitions. Other graphs with the same edge definition will be modified, too.
|
||||
/// 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. 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, dropCollections)`
|
||||
/// `general-graph._editEdgeDefinition(edgeDefinition)`
|
||||
///
|
||||
/// *edgeDefinition* - [string] : the edge definition to replace the existing edge
|
||||
/// definition with the same attribut *collection*.
|
||||
/// *dropCollections* - bool : True, all collections that are not used anymore in any
|
||||
/// graph will be removed. Default: true.
|
||||
/// definition with the same attribute *collection*.
|
||||
///
|
||||
/// @EXAMPLES
|
||||
///
|
||||
/// @EXAMPLE_ARANGOSH_OUTPUT{general_graph__editEdgeDefinition}
|
||||
/// var examples = require("org/arangodb/graph-examples/example-graph.js");
|
||||
/// var ed1 = examples._directedRelationDefinition("myEC1", ["myVC1"], ["myVC2"]);
|
||||
/// var ed2 = examples._directedRelationDefinition("myEC1", ["myVC2"], ["myVC3"]);
|
||||
/// var g = examples._create("myGraph", [ed1, ed2]);
|
||||
/// var graph = require("org/arangodb/general-graph")
|
||||
/// var ed1 = graph._directedRelationDefinition("myEC1", ["myVC1"], ["myVC2"]);
|
||||
/// var ed2 = graph._directedRelationDefinition("myEC1", ["myVC2"], ["myVC3"]);
|
||||
/// var g = graph._create("myGraph", [ed1, ed2]);
|
||||
/// g._editEdgeDefinition(ed2, true);
|
||||
/// @END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
///
|
||||
/// @endDocuBlock
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Graph.prototype._editEdgeDefinitions = function(edgeDefinition, dropCollections) {
|
||||
var self = this;
|
||||
var dropCandidates;
|
||||
var currentEdgeDefinition = {};
|
||||
var exOrphanCandidates = [];
|
||||
var effectedGraphs = [];
|
||||
Graph.prototype._editEdgeDefinitions = function(edgeDefinition) {
|
||||
|
||||
var self = this;
|
||||
|
||||
//check, if in graphs edge definition
|
||||
if (this.__edgeCollections[edgeDefinition.collection] === undefined) {
|
||||
|
@ -2612,108 +2683,33 @@ Graph.prototype._editEdgeDefinitions = function(edgeDefinition, dropCollections)
|
|||
throw err;
|
||||
}
|
||||
|
||||
findOrCreateCollectionsByEdgeDefinitions([edgeDefinition]);
|
||||
|
||||
//evaluate collections to add to orphanage
|
||||
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) {
|
||||
possibleOrphans.push(colName);
|
||||
}
|
||||
}
|
||||
);
|
||||
//change definition for ALL graphs
|
||||
var graphs = getGraphCollection().toArray();
|
||||
graphs.forEach(
|
||||
function(graph) {
|
||||
var eDs = graph.edgeDefinitions;
|
||||
eDs.forEach(
|
||||
function(eD, id) {
|
||||
if(eD.collection === edgeDefinition.collection) {
|
||||
currentEdgeDefinition.from = eD.from;
|
||||
currentEdgeDefinition.to = eD.to;
|
||||
eDs[id].from = edgeDefinition.from;
|
||||
eDs[id].to = edgeDefinition.to;
|
||||
db._graphs.update(graph._key, {edgeDefinitions: eDs});
|
||||
effectedGraphs.push(graph._key);
|
||||
if (graph._key === self.__name) {
|
||||
self.__edgeDefinitions[id].from = edgeDefinition.from;
|
||||
self.__edgeDefinitions[id].to = edgeDefinition.to;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
findOrCreateCollectionsByEdgeDefinitions([edgeDefinition]);
|
||||
|
||||
if (dropCollections !== false) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
);
|
||||
changeEdgeDefinitionsForGraph(graph, edgeDefinition, newCollections, possibleOrphans, self);
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -2724,72 +2720,63 @@ Graph.prototype._editEdgeDefinitions = function(edgeDefinition, dropCollections)
|
|||
/// @startDocuBlock JSF_general_graph__deleteEdgeDefinition
|
||||
/// Deletes an edge definition defined by the edge collection of a graph. If the
|
||||
/// collections defined in the edge definition (collection, from, to) are not used
|
||||
/// in another graph, they will be removed.
|
||||
/// in another edge definition of the graph, they will be moved to the orphanage.
|
||||
///
|
||||
/// `general-graph._deleteEdgeDefinition(edgeCollectionName, dropCollections)`
|
||||
/// `general-graph._deleteEdgeDefinition(edgeCollectionName)`
|
||||
///
|
||||
/// *edgeCollectionName* - string : name of edge collection defined in *collection* of the edge
|
||||
/// definition.
|
||||
/// *dropCollections* - bool : True, all collections are removed, if not used in another edge
|
||||
/// definition (including other graphs). Default: true.
|
||||
///
|
||||
/// @EXAMPLES
|
||||
///
|
||||
/// @EXAMPLE_ARANGOSH_OUTPUT{general_graph__deleteEdgeDefinition}
|
||||
/// var examples = require("org/arangodb/graph-examples/example-graph.js");
|
||||
/// var ed1 = examples._directedRelationDefinition("myEC1", ["myVC1"], ["myVC2"]);
|
||||
/// var ed2 = examples._directedRelationDefinition("myEC2", ["myVC1"], ["myVC3"]);
|
||||
/// var g = examples._create("myGraph", [ed1, ed2]);
|
||||
/// g._deleteEdgeDefinition("myEC1", true);
|
||||
/// var graph = require("org/arangodb/general-graph")
|
||||
/// var ed1 = graph._directedRelationDefinition("myEC1", ["myVC1"], ["myVC2"]);
|
||||
/// var ed2 = graph._directedRelationDefinition("myEC2", ["myVC1"], ["myVC3"]);
|
||||
/// var g = graph._create("myGraph", [ed1, ed2]);
|
||||
/// g._deleteEdgeDefinition("myEC1");
|
||||
/// @END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
///
|
||||
/// @endDocuBlock
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Graph.prototype._deleteEdgeDefinition = function(edgeCollection, dropCollections) {
|
||||
Graph.prototype._deleteEdgeDefinition = function(edgeCollection) {
|
||||
|
||||
//check, if in graphs edge definition
|
||||
if (this.__edgeCollections[edgeCollection] === undefined) {
|
||||
var err = new ArangoError();
|
||||
err.errorNum = arangodb.errors.ERROR_GRAPH_EDGE_COLLECTION_NOT_USED.code;
|
||||
err.errorMessage = arangodb.errors.ERROR_GRAPH_EDGE_COLLECTION_NOT_USED.message;
|
||||
throw err;
|
||||
}
|
||||
|
||||
var edgeDefinitions = this.__edgeDefinitions,
|
||||
vertexCollections = [],
|
||||
definitionFound = false,
|
||||
self = this,
|
||||
usedVertexCollections = [],
|
||||
possibleOrphans = [],
|
||||
index;
|
||||
|
||||
edgeDefinitions.forEach(
|
||||
function(edgeDefinition, idx) {
|
||||
if (edgeDefinition.collection === edgeCollection) {
|
||||
definitionFound = true;
|
||||
if (dropCollections !== false) {
|
||||
//get all vertex collections
|
||||
var vertexCols = edgeDefinition.from.concat(edgeDefinition.to);
|
||||
vertexCols.forEach(
|
||||
function(vertexCol) {
|
||||
if (vertexCollections.indexOf(vertexCol) === -1) {
|
||||
vertexCollections.push(vertexCol);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
index = idx;
|
||||
possibleOrphans = edgeDefinition.from;
|
||||
possibleOrphans = _.union(possibleOrphans, edgeDefinition.to);
|
||||
} else {
|
||||
usedVertexCollections = _.union(usedVertexCollections, edgeDefinition.from);
|
||||
usedVertexCollections = _.union(usedVertexCollections, edgeDefinition.to);
|
||||
}
|
||||
}
|
||||
);
|
||||
if (definitionFound) {
|
||||
edgeDefinitions.splice(index, 1);
|
||||
this.__edgeDefinitions = edgeDefinitions;
|
||||
db._graphs.update(this.__name, {edgeDefinitions: this.__edgeDefinitions});
|
||||
}
|
||||
if (dropCollections !== false) {
|
||||
if (checkIfMayBeDropped(edgeCollection, this.__name, getGraphCollection().toArray())) {
|
||||
db._drop(edgeCollection);
|
||||
}
|
||||
vertexCollections.forEach(
|
||||
function(vC) {
|
||||
if (checkIfMayBeDropped(vC, this.__name, getGraphCollection().toArray())) {
|
||||
db._drop(vC);
|
||||
}
|
||||
this.__edgeDefinitions.splice(index, 1);
|
||||
possibleOrphans.forEach(
|
||||
function(po) {
|
||||
if (usedVertexCollections.indexOf(po) === -1) {
|
||||
self.__orphanCollections.push(po);
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -2805,9 +2792,9 @@ Graph.prototype._deleteEdgeDefinition = function(edgeCollection, dropCollections
|
|||
/// @EXAMPLES
|
||||
///
|
||||
/// @EXAMPLE_ARANGOSH_OUTPUT{general_graph__addOrphanCollection}
|
||||
/// var examples = require("org/arangodb/graph-examples/example-graph.js");
|
||||
/// var ed1 = examples._directedRelationDefinition("myEC1", ["myVC1"], ["myVC2"]);
|
||||
/// var g = examples._create("myGraph", [ed1, ed2]);
|
||||
/// var graph = require("org/arangodb/general-graph")
|
||||
/// var ed1 = graph._directedRelationDefinition("myEC1", ["myVC1"], ["myVC2"]);
|
||||
/// var g = graph._create("myGraph", [ed1]);
|
||||
/// g._addOrphanCollection("myVC3", true);
|
||||
/// @END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
///
|
||||
|
@ -2815,17 +2802,17 @@ Graph.prototype._deleteEdgeDefinition = function(edgeCollection, dropCollections
|
|||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Graph.prototype._addOrphanCollection = function(vertexCollection, createCollection) {
|
||||
Graph.prototype._addOrphanCollection = function(orphanCollectionName, createCollection) {
|
||||
//check edgeCollection
|
||||
var ec = db._collection(vertexCollection);
|
||||
var ec = db._collection(orphanCollectionName);
|
||||
var err;
|
||||
if (ec === null) {
|
||||
if (createCollection !== false) {
|
||||
db._create(vertexCollection);
|
||||
db._create(orphanCollectionName);
|
||||
} else {
|
||||
err = new ArangoError();
|
||||
err.errorNum = arangodb.errors.ERROR_GRAPH_VERTEX_COL_DOES_NOT_EXIST.code;
|
||||
err.errorMessage = vertexCollection + arangodb.errors.ERROR_GRAPH_VERTEX_COL_DOES_NOT_EXIST.message;
|
||||
err.errorMessage = orphanCollectionName + arangodb.errors.ERROR_GRAPH_VERTEX_COL_DOES_NOT_EXIST.message;
|
||||
throw err;
|
||||
}
|
||||
} else if (ec.type() !== 2) {
|
||||
|
@ -2834,8 +2821,14 @@ Graph.prototype._addOrphanCollection = function(vertexCollection, createCollecti
|
|||
err.errorMessage = arangodb.errors.ERROR_GRAPH_WRONG_COLLECTION_TYPE_VERTEX.message;
|
||||
throw err;
|
||||
}
|
||||
if (this.__vertexCollections[orphanCollectionName] !== undefined) {
|
||||
err = new ArangoError();
|
||||
err.errorNum = arangodb.errors.ERROR_GRAPH_COLLECTION_USED_IN_EDGE_DEF.code;
|
||||
err.errorMessage = arangodb.errors.ERROR_GRAPH_COLLECTION_USED_IN_EDGE_DEF.message;
|
||||
throw err;
|
||||
}
|
||||
|
||||
this.__orphanCollections.push(vertexCollection);
|
||||
this.__orphanCollections.push(orphanCollectionName);
|
||||
db._graphs.update(this.__name, {orphanCollections: this.__orphanCollections});
|
||||
|
||||
};
|
||||
|
@ -2849,9 +2842,9 @@ Graph.prototype._addOrphanCollection = function(vertexCollection, createCollecti
|
|||
/// @EXAMPLES
|
||||
///
|
||||
/// @EXAMPLE_ARANGOSH_OUTPUT{general_graph__getOrphanCollections}
|
||||
/// var examples = require("org/arangodb/graph-examples/example-graph.js");
|
||||
/// var ed1 = examples._directedRelationDefinition("myEC1", ["myVC1"], ["myVC2"]);
|
||||
/// var g = examples._create("myGraph", [ed1]);
|
||||
/// var graph = require("org/arangodb/general-graph")
|
||||
/// var ed1 = graph._directedRelationDefinition("myEC1", ["myVC1"], ["myVC2"]);
|
||||
/// var g = graph._create("myGraph", [ed1]);
|
||||
/// g._addOrphanCollection("myVC3", true);
|
||||
/// g._getOrphanCollections();
|
||||
/// @END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
|
@ -2878,9 +2871,9 @@ Graph.prototype._getOrphanCollections = function() {
|
|||
/// @EXAMPLES
|
||||
///
|
||||
/// @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]);
|
||||
/// var graph = require("org/arangodb/general-graph")
|
||||
/// var ed1 = graph._directedRelationDefinition("myEC1", ["myVC1"], ["myVC2"]);
|
||||
/// var g = graph._create("myGraph", [ed1]);
|
||||
/// g._addOrphanCollection("myVC3", true);
|
||||
/// g._addOrphanCollection("myVC4", true);
|
||||
/// g._getOrphanCollections();
|
||||
|
|
|
@ -60,8 +60,52 @@ function GeneralGraphCreationSuite() {
|
|||
)
|
||||
);
|
||||
|
||||
var gN1 = "UnitTestEdgeDefDeleteGraph1",
|
||||
gN2 = "UnitTestEdgeDefDeleteGraph2",
|
||||
ec1 = "UnitTestEdgeDefDeleteEdgeCol1",
|
||||
ec2 = "UnitTestEdgeDefDeleteEdgeCol2",
|
||||
ec3 = "UnitTestEdgeDefDeleteEdgeCol3",
|
||||
vc1 = "UnitTestEdgeDefDeleteVertexCol1",
|
||||
vc2 = "UnitTestEdgeDefDeleteVertexCol2",
|
||||
vc3 = "UnitTestEdgeDefDeleteVertexCol3",
|
||||
vc4 = "UnitTestEdgeDefDeleteVertexCol4",
|
||||
vc5 = "UnitTestEdgeDefDeleteVertexCol5",
|
||||
vc6 = "UnitTestEdgeDefDeleteVertexCol6";
|
||||
|
||||
return {
|
||||
|
||||
setUp: function() {
|
||||
try {
|
||||
graph._drop(gN1);
|
||||
} catch(ignore) {
|
||||
}
|
||||
try {
|
||||
graph._drop(gN2);
|
||||
} catch(ignore) {
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
tearDown: function() {
|
||||
db._drop(ec1);
|
||||
db._drop(ec2);
|
||||
db._drop(ec3);
|
||||
db._drop(vc1);
|
||||
db._drop(vc2);
|
||||
db._drop(vc3);
|
||||
db._drop(vc4);
|
||||
db._drop(vc5);
|
||||
db._drop(vc6);
|
||||
try {
|
||||
graph._drop(gN1);
|
||||
} catch(ignore) {
|
||||
}
|
||||
try {
|
||||
graph._drop(gN2);
|
||||
} catch(ignore) {
|
||||
}
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test: Graph Creation
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -413,58 +457,39 @@ function GeneralGraphCreationSuite() {
|
|||
},
|
||||
|
||||
|
||||
test_deleteEdgeDefinitionFromExistingGraph: function() {
|
||||
var gN1 = "UnitTestEdgeDefDeleteGraph1",
|
||||
gN2 = "UnitTestEdgeDefDeleteGraph2",
|
||||
ec1 = "UnitTestEdgeDefDeleteEdgeCol1",
|
||||
ec2 = "UnitTestEdgeDefDeleteEdgeCol2",
|
||||
ec3 = "UnitTestEdgeDefDeleteEdgeCol3",
|
||||
vc1 = "UnitTestEdgeDefDeleteVertexCol1",
|
||||
vc2 = "UnitTestEdgeDefDeleteVertexCol2",
|
||||
vc3 = "UnitTestEdgeDefDeleteVertexCol3",
|
||||
vc4 = "UnitTestEdgeDefDeleteVertexCol4",
|
||||
vc5 = "UnitTestEdgeDefDeleteVertexCol5";
|
||||
try {
|
||||
graph._drop(gN1);
|
||||
} catch(ignore) {
|
||||
}
|
||||
try {
|
||||
graph._drop(gN2);
|
||||
} catch(ignore) {
|
||||
}
|
||||
|
||||
test_deleteEdgeDefinitionFromExistingGraph1: function() {
|
||||
var dr1 = graph._directedRelationDefinition(ec1, [vc1], [vc1, vc2]),
|
||||
dr2 = graph._directedRelationDefinition(ec2, [vc3], [vc4, vc5]),
|
||||
dr3 = graph._directedRelationDefinition(ec3, [vc4], [vc5]),
|
||||
g1 = graph._create(gN1, [dr1, dr2, dr3]),
|
||||
g2 = graph._create(gN2, [dr3]);
|
||||
|
||||
g1._deleteEdgeDefinition(ec1, false);
|
||||
assertEqual([dr2, dr3], g1.__edgeDefinitions);
|
||||
|
||||
g1._deleteEdgeDefinition(ec2, true);
|
||||
assertEqual([dr3], g1.__edgeDefinitions);
|
||||
assertTrue(db._collection(vc3) === null);
|
||||
assertFalse(db._collection(vc4) === null);
|
||||
assertFalse(db._collection(vc5) === null);
|
||||
g1 = graph._create(gN1, [dr1]);
|
||||
|
||||
try {
|
||||
graph._drop(gN1);
|
||||
} catch(ignore) {
|
||||
}
|
||||
try {
|
||||
graph._drop(gN2);
|
||||
} catch(ignore) {
|
||||
g1._deleteEdgeDefinition(ec1);
|
||||
} catch (e) {
|
||||
assertEqual(
|
||||
e.errorMessage,
|
||||
arangodb.errors.ERROR_GRAPH_EDGE_COLLECTION_NOT_USED.message
|
||||
);
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
test_deleteEdgeDefinitionFromExistingGraph2: function() {
|
||||
|
||||
var dr1 = graph._directedRelationDefinition(ec1, [vc1], [vc1, vc2]),
|
||||
dr2 = graph._directedRelationDefinition(ec2, [vc3], [vc4, vc5]),
|
||||
dr3 = graph._directedRelationDefinition(ec3, [vc4], [vc5]),
|
||||
g1 = graph._create(gN1, [dr1, dr2, dr3]);
|
||||
|
||||
assertEqual([dr1, dr2, dr3], g1.__edgeDefinitions);
|
||||
g1._deleteEdgeDefinition(ec1);
|
||||
assertEqual([dr2, dr3], g1.__edgeDefinitions);
|
||||
assertEqual([vc1, vc2], g1._getOrphanCollections());
|
||||
|
||||
g1._deleteEdgeDefinition(ec2);
|
||||
assertEqual([dr3], g1.__edgeDefinitions);
|
||||
assertEqual([vc1, vc2, vc3], g1._getOrphanCollections());
|
||||
},
|
||||
|
||||
test_extendEdgeDefinitionFromExistingGraph1: function() {
|
||||
var gN1 = "UnitTestEdgeDefExtend1Graph1",
|
||||
ec1 = "UnitTestEdgeDefExtend1EdgeCol1",
|
||||
vc1 = "UnitTestEdgeDefExtend1VertexCol1",
|
||||
vc2 = "UnitTestEdgeDefExtend1VertexCol2",
|
||||
vc3 = "UnitTestEdgeDefExtend1VertexCol3";
|
||||
|
||||
try {
|
||||
graph._drop(gN1);
|
||||
|
@ -492,24 +517,6 @@ function GeneralGraphCreationSuite() {
|
|||
},
|
||||
|
||||
test_extendEdgeDefinitionFromExistingGraph2: function() {
|
||||
var gN1 = "UnitTestEdgeDefExtend2Graph1",
|
||||
gN2 = "UnitTestEdgeDefExtend2Graph2",
|
||||
ec1 = "UnitTestEdgeDefExtend2EdgeCol1",
|
||||
ec2 = "UnitTestEdgeDefExtend2EdgeCol2",
|
||||
ec3 = "UnitTestEdgeDefExtend2EdgeCol3",
|
||||
vc1 = "UnitTestEdgeDefExtend2VertexCol1",
|
||||
vc2 = "UnitTestEdgeDefExtend2VertexCol2",
|
||||
vc3 = "UnitTestEdgeDefExtend2VertexCol3",
|
||||
vc4 = "UnitTestEdgeDefExtend2VertexCol4",
|
||||
vc5 = "UnitTestEdgeDefExtend2VertexCol5";
|
||||
try {
|
||||
graph._drop(gN1);
|
||||
} catch(ignore) {
|
||||
}
|
||||
try {
|
||||
graph._drop(gN2);
|
||||
} catch(ignore) {
|
||||
}
|
||||
|
||||
var dr1 = graph._directedRelationDefinition(ec1, [vc1], [vc1, vc2]),
|
||||
dr2 = graph._directedRelationDefinition(ec2, [vc3], [vc4, vc5]),
|
||||
|
@ -538,16 +545,6 @@ function GeneralGraphCreationSuite() {
|
|||
},
|
||||
|
||||
test_extendEdgeDefinitionFromExistingGraph3: function() {
|
||||
var gN1 = "UnitTestEdgeDefExtend3Graph1",
|
||||
gN2 = "UnitTestEdgeDefExtend3Graph2",
|
||||
ec1 = "UnitTestEdgeDefExtend3EdgeCol1",
|
||||
ec2 = "UnitTestEdgeDefExtend3EdgeCol2",
|
||||
ec3 = "UnitTestEdgeDefExtend3EdgeCol3",
|
||||
vc1 = "UnitTestEdgeDefExtend3VertexCol1",
|
||||
vc2 = "UnitTestEdgeDefExtend3VertexCol2",
|
||||
vc3 = "UnitTestEdgeDefExtend3VertexCol3",
|
||||
vc4 = "UnitTestEdgeDefExtend3VertexCol4",
|
||||
vc5 = "UnitTestEdgeDefExtend3VertexCol5";
|
||||
try {
|
||||
graph._drop(gN1);
|
||||
} catch(ignore) {
|
||||
|
@ -572,32 +569,9 @@ function GeneralGraphCreationSuite() {
|
|||
g1._extendEdgeDefinitions(dr3);
|
||||
assertEqual([dr1, dr2, dr3], g1.__edgeDefinitions);
|
||||
|
||||
|
||||
try {
|
||||
graph._drop(gN1);
|
||||
} catch(ignore) {
|
||||
}
|
||||
try {
|
||||
graph._drop(gN2);
|
||||
} catch(ignore) {
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
test_editEdgeDefinitionFromExistingGraph1: function() {
|
||||
var gN1 = "UnitTestEdgeDefEdit1Graph1",
|
||||
ec1 = "UnitTestEdgeDefEdit1EdgeCol1",
|
||||
ec2 = "UnitTestEdgeDefEdit1EdgeCol2",
|
||||
vc1 = "UnitTestEdgeDefEdit1VertexCol1",
|
||||
vc2 = "UnitTestEdgeDefEdit1VertexCol2",
|
||||
vc3 = "UnitTestEdgeDefEdit1VertexCol3",
|
||||
vc4 = "UnitTestEdgeDefEdit1VertexCol4",
|
||||
vc5 = "UnitTestEdgeDefEdit1VertexCol5";
|
||||
try {
|
||||
graph._drop(gN1);
|
||||
} catch(ignore) {
|
||||
}
|
||||
|
||||
var dr1 = graph._directedRelationDefinition(ec1, [vc1], [vc1, vc2]),
|
||||
dr2 = graph._directedRelationDefinition(ec2, [vc3], [vc4, vc5]),
|
||||
g1 = graph._create(gN1, [dr1]);
|
||||
|
@ -607,77 +581,35 @@ function GeneralGraphCreationSuite() {
|
|||
} catch (e) {
|
||||
assertEqual(
|
||||
e.errorMessage,
|
||||
arangodb.errors.ERROR_GRAPH_EDGE_COLLECTION_NOT_USED
|
||||
arangodb.errors.ERROR_GRAPH_EDGE_COLLECTION_NOT_USED.message
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
graph._drop(gN1);
|
||||
} catch(ignore) {
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
test_editEdgeDefinitionFromExistingGraph2: function() {
|
||||
var gN1 = "UnitTestEdgeDefEdit2Graph1",
|
||||
gN2 = "UnitTestEdgeDefEdit2Graph2",
|
||||
ec1 = "UnitTestEdgeDefEdit2EdgeCol1",
|
||||
vc1 = "UnitTestEdgeDefEdit2VertexCol1",
|
||||
vc2 = "UnitTestEdgeDefEdit2VertexCol2",
|
||||
vc3 = "UnitTestEdgeDefEdit2VertexCol3",
|
||||
vc4 = "UnitTestEdgeDefEdit2VertexCol4",
|
||||
vc5 = "UnitTestEdgeDefEdit2VertexCol5";
|
||||
try {
|
||||
graph._drop(gN1);
|
||||
} catch(ignore) {
|
||||
}
|
||||
try {
|
||||
graph._drop(gN2);
|
||||
} catch(ignore) {
|
||||
}
|
||||
|
||||
var dr1 = graph._directedRelationDefinition(ec1, [vc1], [vc1, vc2]),
|
||||
dr2 = graph._directedRelationDefinition(ec1, [vc3], [vc4, vc5]),
|
||||
g1 = graph._create(gN1, [dr1]),
|
||||
var dr1 = graph._directedRelationDefinition(ec1, [vc1, vc2], [vc3, vc4]),
|
||||
dr2 = graph._directedRelationDefinition(ec2, [vc1], [vc4]),
|
||||
dr3 = graph._directedRelationDefinition(ec1, [vc5], [vc5]),
|
||||
g1 = graph._create(gN1, [dr1, dr2]),
|
||||
g2 = graph._create(gN2, [dr1]);
|
||||
|
||||
g1._editEdgeDefinitions(dr2, true);
|
||||
assertEqual([dr2], g1.__edgeDefinitions);
|
||||
assertEqual([dr2], g2.__edgeDefinitions);
|
||||
assertTrue(db._collection(vc1) === null);
|
||||
assertTrue(db._collection(vc2) === null);
|
||||
|
||||
try {
|
||||
graph._drop(gN1);
|
||||
} catch(ignore) {
|
||||
}
|
||||
try {
|
||||
graph._drop(gN2);
|
||||
} catch(ignore) {
|
||||
}
|
||||
g1._editEdgeDefinitions(dr3);
|
||||
assertEqual([dr3, dr2], g1.__edgeDefinitions);
|
||||
assertEqual([dr3], g2.__edgeDefinitions);
|
||||
g1 = graph._graph(gN1);
|
||||
g2 = graph._graph(gN2);
|
||||
assertTrue(g1._getOrphanCollections().indexOf(vc2) !== -1);
|
||||
assertTrue(g1._getOrphanCollections().indexOf(vc3) !== -1);
|
||||
assertTrue(g2._getOrphanCollections().indexOf(vc1) !== -1);
|
||||
assertTrue(g2._getOrphanCollections().indexOf(vc2) !== -1);
|
||||
assertTrue(g2._getOrphanCollections().indexOf(vc3) !== -1);
|
||||
assertTrue(g2._getOrphanCollections().indexOf(vc4) !== -1);
|
||||
|
||||
},
|
||||
|
||||
test_editEdgeDefinitionFromExistingGraph3: function() {
|
||||
var prefix = "UnitTestEdgeDefEdit3",
|
||||
gN1 = prefix + "Graph1",
|
||||
gN2 = prefix + "Graph2",
|
||||
ec1 = prefix + "EdgeCol1",
|
||||
ec2 = prefix + "EdgeCol2",
|
||||
vc1 = prefix + "VertexCol1",
|
||||
vc2 = prefix + "VertexCol2",
|
||||
vc3 = prefix + "VertexCol3",
|
||||
vc4 = prefix + "VertexCol4",
|
||||
vc5 = prefix + "VertexCol5",
|
||||
vc6 = prefix + "VertexCol6";
|
||||
try {
|
||||
graph._drop(gN1);
|
||||
} catch(ignore) {
|
||||
}
|
||||
try {
|
||||
graph._drop(gN2);
|
||||
} catch(ignore) {
|
||||
}
|
||||
|
||||
var dr1 = graph._directedRelationDefinition(ec1, [vc1], [vc1, vc2]),
|
||||
dr2 = graph._directedRelationDefinition(ec1, [vc3], [vc4, vc5]),
|
||||
|
@ -689,13 +621,15 @@ function GeneralGraphCreationSuite() {
|
|||
g2._addOrphanCollection(vc5);
|
||||
g2._addOrphanCollection(vc6);
|
||||
g1._editEdgeDefinitions(dr2, true);
|
||||
|
||||
assertEqual([dr2, dr3], g1.__edgeDefinitions);
|
||||
assertEqual([dr2], g2.__edgeDefinitions);
|
||||
assertTrue(db._collection(vc1) === null);
|
||||
assertFalse(db._collection(vc2) === null);
|
||||
assertEqual([], g1._getOrphanCollections());
|
||||
g1 = graph._graph(gN1);
|
||||
g2 = graph._graph(gN2);
|
||||
assertEqual([vc6], g2._getOrphanCollections());
|
||||
assertEqual([vc1], g1._getOrphanCollections());
|
||||
assertTrue(g2._getOrphanCollections().indexOf(vc1) !== -1);
|
||||
assertTrue(g2._getOrphanCollections().indexOf(vc2) !== -1);
|
||||
assertTrue(g2._getOrphanCollections().indexOf(vc6) !== -1);
|
||||
|
||||
try {
|
||||
graph._drop(gN1);
|
||||
|
@ -2562,8 +2496,8 @@ function OrphanCollectionSuite() {
|
|||
},
|
||||
|
||||
test_addOrphanCollection1: function() {
|
||||
g1._addOrphanCollection(vC1, false);
|
||||
assertEqual(g1._getOrphanCollections(), [vC1]);
|
||||
g1._addOrphanCollection(vC5, true);
|
||||
assertEqual(g1._getOrphanCollections(), [vC5]);
|
||||
},
|
||||
|
||||
test_addOrphanCollection2: function() {
|
||||
|
@ -2588,6 +2522,15 @@ function OrphanCollectionSuite() {
|
|||
assertEqual(g1._getOrphanCollections(), []);
|
||||
},
|
||||
|
||||
test_addOrphanCollection4: function() {
|
||||
try {
|
||||
g1._addOrphanCollection(vC1);
|
||||
} catch (e) {
|
||||
assertEqual(e.errorNum, ERRORS.ERROR_GRAPH_COLLECTION_USED_IN_EDGE_DEF.code);
|
||||
assertEqual(e.errorMessage, ERRORS.ERROR_GRAPH_COLLECTION_USED_IN_EDGE_DEF.message);
|
||||
}
|
||||
},
|
||||
|
||||
test_removeOrphanCollection1: function() {
|
||||
var name = "completelyNonsenseNameForACollectionBLUBBBBB"
|
||||
try {
|
||||
|
|
|
@ -4437,13 +4437,15 @@ function TRAVERSAL_FUNC (func,
|
|||
maxIterations: params.maxIterations,
|
||||
uniqueness: params.uniqueness,
|
||||
expander: direction,
|
||||
direction: direction,
|
||||
strategy: params.strategy,
|
||||
order: params.order,
|
||||
itemOrder: params.itemOrder,
|
||||
startVertex : startVertex,
|
||||
endVertex : endVertex,
|
||||
weight : params.weight,
|
||||
defaultWeight : params.defaultWeight
|
||||
defaultWeight : params.defaultWeight,
|
||||
prefill : params.prefill
|
||||
|
||||
};
|
||||
|
||||
|
@ -4643,18 +4645,6 @@ function DETERMINE_WEIGHT (edge, weight, defaultWeight) {
|
|||
return Infinity;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief visitor callback function for traversal
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function TRAVERSAL_SHORTEST_PATH_VISITOR (config, result, vertex, path) {
|
||||
"use strict";
|
||||
|
||||
if (config.endVertex && config.endVertex === vertex._id) {
|
||||
result.push(CLONE({ vertex: vertex, path: path , startVertex : config.startVertex}));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief visitor callback function for traversal
|
||||
|
@ -4664,18 +4654,19 @@ function TRAVERSAL_DISTANCE_VISITOR (config, result, vertex, path) {
|
|||
"use strict";
|
||||
|
||||
if (config.endVertex && config.endVertex === vertex._id) {
|
||||
var subPaths = [];
|
||||
var dist = 0;
|
||||
if (config.weight) {
|
||||
path.edges.forEach(function (e) {
|
||||
path.edges.forEach(function (e) {
|
||||
if (config.weight) {
|
||||
if (typeof e[config.weight] === "number") {
|
||||
dist = dist + e[config.weight];
|
||||
} else if (config.defaultWeight) {
|
||||
dist = dist + config.defaultWeight;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
dist = path.edges.length;
|
||||
}
|
||||
} else {
|
||||
dist++;
|
||||
}
|
||||
});
|
||||
result.push(
|
||||
CLONE({ vertex: vertex, distance: dist , path: path , startVertex : config.startVertex})
|
||||
);
|
||||
|
@ -4683,6 +4674,62 @@ function TRAVERSAL_DISTANCE_VISITOR (config, result, vertex, path) {
|
|||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief visitor callback function for traversal
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function TRAVERSAL_DIJSKTRA_VISITOR (config, result, vertex, path) {
|
||||
"use strict";
|
||||
if (config.endVertex && config.endVertex === vertex._id) {
|
||||
path.vertices.forEach(function (from) {
|
||||
path.vertices.forEach(function (to) {
|
||||
if (config.prefill.indexOf(JSON.stringify({ from : TO_ID(from), to : TO_ID(to)})) !== -1) {
|
||||
return;
|
||||
}
|
||||
var positionFrom = path.vertices.indexOf(from);
|
||||
var positionTo = path.vertices.indexOf(to);
|
||||
if (positionFrom > positionTo && config.direction !== 'any') {
|
||||
return;
|
||||
}
|
||||
var startVertex = from._id;
|
||||
var vertex = to;
|
||||
|
||||
var distance = 0;
|
||||
var pathNew = {vertices : [from], edges : []};
|
||||
while (positionFrom !== positionTo) {
|
||||
var edgePosition;
|
||||
if (positionFrom > positionTo) {
|
||||
edgePosition = positionFrom-1;
|
||||
} else {
|
||||
edgePosition = positionFrom;
|
||||
}
|
||||
if (positionFrom > positionTo) {
|
||||
positionFrom = positionFrom -1;
|
||||
} else {
|
||||
positionFrom ++;
|
||||
}
|
||||
pathNew.vertices.push(path.vertices[positionFrom]);
|
||||
pathNew.edges.push(path.edges[edgePosition]);
|
||||
if (config.weight) {
|
||||
if (path.edges[edgePosition][config.weight] &&
|
||||
typeof path.edges[edgePosition][config.weight] === "number") {
|
||||
distance = distance + path.edges[edgePosition][config.weight];
|
||||
} else if (config.defaultWeight) {
|
||||
distance = distance + config.defaultWeight;
|
||||
}
|
||||
} else {
|
||||
distance++;
|
||||
}
|
||||
}
|
||||
result.push(
|
||||
CLONE({ vertex: vertex, distance: distance , path: pathNew , startVertex : startVertex})
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief helper function to determine parameters for SHORTEST_PATH and
|
||||
|
@ -4920,6 +4967,8 @@ function MERGE_EXAMPLES_WITH_EDGES (examples, edges) {
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief calculate shortest paths by dijkstra
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -4931,17 +4980,29 @@ function CALCULATE_SHORTEST_PATHES_WITH_DIJKSTRA (graphName, graphData, options)
|
|||
params.weight = options.weight;
|
||||
params.defaultWeight = options.defaultWeight;
|
||||
params = SHORTEST_PATH_PARAMS(params);
|
||||
params.visitor = TRAVERSAL_DISTANCE_VISITOR;
|
||||
params.visitor = TRAVERSAL_DIJSKTRA_VISITOR;
|
||||
var result = [];
|
||||
|
||||
var calculated = {};
|
||||
graphData.fromVertices.forEach(function (v) {
|
||||
graphData.toVertices.forEach(function (t) {
|
||||
if (calculated[JSON.stringify({ from : TO_ID(v), to : TO_ID(t)})]) {
|
||||
result.push(calculated[JSON.stringify({ from : TO_ID(v), to : TO_ID(t)})]);
|
||||
return;
|
||||
}
|
||||
params.prefill = Object.keys(calculated);
|
||||
var e = TRAVERSAL_FUNC("GENERAL_GRAPH_SHORTEST_PATH",
|
||||
factory,
|
||||
TO_ID(v),
|
||||
TO_ID(t),
|
||||
options.direction,
|
||||
params);
|
||||
result = result.concat(e);
|
||||
e.forEach(function (f) {
|
||||
if (TO_ID(v) === f.startVertex && TO_ID(t) === f.vertex._id) {
|
||||
result.push(f);
|
||||
}
|
||||
calculated[JSON.stringify({ from : f.startVertex, to : f.vertex._id})] = f;
|
||||
});
|
||||
});
|
||||
});
|
||||
result.forEach(function (r) {
|
||||
|
|
|
@ -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;
|
||||
appContextTempl.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;
|
||||
|
||||
|
|
|
@ -1475,6 +1475,16 @@ function ahuacatlQueryGeneralTraversalTestSuite() {
|
|||
assertEqual(actual[0]["UnitTests_Leipziger/Gerda"], 1);
|
||||
|
||||
|
||||
actual = getQueryResults("RETURN GRAPH_ECCENTRICITY('werKenntWen')");
|
||||
assertEqual(actual[0]["UnitTests_Berliner/Anton"].toFixed(1), 0.6);
|
||||
assertEqual(actual[0]["UnitTests_Berliner/Berta"].toFixed(2), 0.75);
|
||||
assertEqual(actual[0]["UnitTests_Frankfurter/Emil"].toFixed(2), 0.75);
|
||||
assertEqual(actual[0]["UnitTests_Frankfurter/Fritz"].toFixed(1), 0.6);
|
||||
assertEqual(actual[0]["UnitTests_Hamburger/Caesar"].toFixed(1), 0.6);
|
||||
assertEqual(actual[0]["UnitTests_Hamburger/Dieter"], 1);
|
||||
assertEqual(actual[0]["UnitTests_Leipziger/Gerda"], 1);
|
||||
|
||||
|
||||
actual = getQueryResults("RETURN GRAPH_ECCENTRICITY('werKenntWen', {algorithm : 'dijkstra', direction : 'inbound'})");
|
||||
assertEqual(actual[0]["UnitTests_Berliner/Anton"], 1);
|
||||
assertEqual(actual[0]["UnitTests_Berliner/Berta"], 1);
|
||||
|
|
|
@ -296,6 +296,8 @@ ERROR_GRAPH_DUPLICATE,1925,"graph already exists","a graph with this name alread
|
|||
ERROR_GRAPH_VERTEX_COL_DOES_NOT_EXIST,1926,"collection does not exist"," does not exist.",
|
||||
ERROR_GRAPH_WRONG_COLLECTION_TYPE_VERTEX,1927,"not a vertex collection","the collection is not a vertex collection.",
|
||||
ERROR_GRAPH_NOT_IN_ORPHAN_COLLECTION,1928,"not in orphan collection","Vertex collection not in orphan collection of the graph.",
|
||||
ERROR_GRAPH_COLLECTION_USED_IN_EDGE_DEF,1929,"collection used in edge def","The collection is already used in an edge definition of the graph.",
|
||||
ERROR_GRAPH_EDGE_COLLECTION_NOT_USED,1930,"edge collection not used in graph","The edge collection is not used in any edge definition of the graph.",
|
||||
|
||||
################################################################################
|
||||
## Session errors
|
||||
|
|
|
@ -212,6 +212,8 @@ void TRI_InitialiseErrorMessages (void) {
|
|||
REG_ERROR(ERROR_GRAPH_VERTEX_COL_DOES_NOT_EXIST, "collection does not exist");
|
||||
REG_ERROR(ERROR_GRAPH_WRONG_COLLECTION_TYPE_VERTEX, "not a vertex collection");
|
||||
REG_ERROR(ERROR_GRAPH_NOT_IN_ORPHAN_COLLECTION, "not in orphan collection");
|
||||
REG_ERROR(ERROR_GRAPH_COLLECTION_USED_IN_EDGE_DEF, "collection used in edge def");
|
||||
REG_ERROR(ERROR_GRAPH_EDGE_COLLECTION_NOT_USED, "edge collection not used in graph");
|
||||
REG_ERROR(ERROR_SESSION_UNKNOWN, "unknown session");
|
||||
REG_ERROR(ERROR_SESSION_EXPIRED, "session expired");
|
||||
REG_ERROR(SIMPLE_CLIENT_UNKNOWN_ERROR, "unknown client error");
|
||||
|
|
|
@ -498,6 +498,10 @@ extern "C" {
|
|||
/// the collection is not a vertex collection.
|
||||
/// - 1928: @LIT{not in orphan collection}
|
||||
/// Vertex collection not in orphan collection of the graph.
|
||||
/// - 1929: @LIT{collection used in edge def}
|
||||
/// The collection is already used in an edge definition of the graph.
|
||||
/// - 1930: @LIT{edge collection not used in graph}
|
||||
/// The edge collection is not used in any edge definition of the graph.
|
||||
/// - 1950: @LIT{unknown session}
|
||||
/// Will be raised when an invalid/unknown session id is passed to the server.
|
||||
/// - 1951: @LIT{session expired}
|
||||
|
@ -2638,6 +2642,26 @@ void TRI_InitialiseErrorMessages (void);
|
|||
|
||||
#define TRI_ERROR_GRAPH_NOT_IN_ORPHAN_COLLECTION (1928)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief 1929: ERROR_GRAPH_COLLECTION_USED_IN_EDGE_DEF
|
||||
///
|
||||
/// collection used in edge def
|
||||
///
|
||||
/// The collection is already used in an edge definition of the graph.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TRI_ERROR_GRAPH_COLLECTION_USED_IN_EDGE_DEF (1929)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief 1930: ERROR_GRAPH_EDGE_COLLECTION_NOT_USED
|
||||
///
|
||||
/// edge collection not used in graph
|
||||
///
|
||||
/// The edge collection is not used in any edge definition of the graph.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TRI_ERROR_GRAPH_EDGE_COLLECTION_NOT_USED (1930)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief 1950: ERROR_SESSION_UNKNOWN
|
||||
///
|
||||
|
|
Loading…
Reference in New Issue