diff --git a/BasicsC/voc-errors.c b/BasicsC/voc-errors.c index 13b462f866..d18dd98c52 100644 --- a/BasicsC/voc-errors.c +++ b/BasicsC/voc-errors.c @@ -105,6 +105,10 @@ void TRI_InitialiseErrorMessages (void) { REG_ERROR(ERROR_KEYVALUE_KEY_NOT_UNIQUE, "key is not unique"); REG_ERROR(ERROR_KEYVALUE_KEY_NOT_CHANGED, "key value not changed"); REG_ERROR(ERROR_KEYVALUE_KEY_NOT_REMOVED, "key value not removed"); + REG_ERROR(ERROR_GRAPH_INVALID_GRAPH, "invalid graph"); + REG_ERROR(ERROR_GRAPH_COULD_NOT_CREATE_GRAPH, "could not create graph"); + REG_ERROR(ERROR_GRAPH_INVALID_VERTEX, "invalid vertex"); + REG_ERROR(ERROR_GRAPH_COULD_NOT_CREATE_VERTEX, "could not create vertex"); REG_ERROR(SIMPLE_CLIENT_UNKNOWN_ERROR, "unknown client error"); REG_ERROR(SIMPLE_CLIENT_COULD_NOT_CONNECT, "could not connect to server"); REG_ERROR(SIMPLE_CLIENT_COULD_NOT_WRITE, "could not write to server"); diff --git a/BasicsC/voc-errors.h b/BasicsC/voc-errors.h index 58de0812a2..959e76cd19 100644 --- a/BasicsC/voc-errors.h +++ b/BasicsC/voc-errors.h @@ -227,6 +227,15 @@ extern "C" { /// Will be raised when updating the value for a key does not work /// - 1805: @CODE{key value not removed} /// Will be raised when deleting a key/value pair does not work +/// - 1901: @CODE{invalid graph} +/// Will be raised when an invalid name is passed to the server +/// - 1902: @CODE{could not create graph} +/// Will be raised when an invalid name, vertices or edges is passed to the +/// server +/// - 1903: @CODE{invalid vertex} +/// Will be raised when an invalid vertex id is passed to the server +/// - 1904: @CODE{could not create vertex} +/// Will be raised when the vertex could not be created /// - 2000: @CODE{unknown client error} /// This error should not happen. /// - 2001: @CODE{could not connect to server} @@ -1225,6 +1234,47 @@ void TRI_InitialiseErrorMessages (void); #define TRI_ERROR_KEYVALUE_KEY_NOT_REMOVED (1805) +//////////////////////////////////////////////////////////////////////////////// +/// @brief 1901: ERROR_GRAPH_INVALID_GRAPH +/// +/// invalid graph +/// +/// Will be raised when an invalid name is passed to the server +//////////////////////////////////////////////////////////////////////////////// + +#define TRI_ERROR_GRAPH_INVALID_GRAPH (1901) + +//////////////////////////////////////////////////////////////////////////////// +/// @brief 1902: ERROR_GRAPH_COULD_NOT_CREATE_GRAPH +/// +/// could not create graph +/// +/// Will be raised when an invalid name, vertices or edges is passed to the +/// server +//////////////////////////////////////////////////////////////////////////////// + +#define TRI_ERROR_GRAPH_COULD_NOT_CREATE_GRAPH (1902) + +//////////////////////////////////////////////////////////////////////////////// +/// @brief 1903: ERROR_GRAPH_INVALID_VERTEX +/// +/// invalid vertex +/// +/// Will be raised when an invalid vertex id is passed to the server +//////////////////////////////////////////////////////////////////////////////// + +#define TRI_ERROR_GRAPH_INVALID_VERTEX (1903) + +//////////////////////////////////////////////////////////////////////////////// +/// @brief 1904: ERROR_GRAPH_COULD_NOT_CREATE_VERTEX +/// +/// could not create vertex +/// +/// Will be raised when the vertex could not be created +//////////////////////////////////////////////////////////////////////////////// + +#define TRI_ERROR_GRAPH_COULD_NOT_CREATE_VERTEX (1904) + //////////////////////////////////////////////////////////////////////////////// /// @brief 2000: SIMPLE_CLIENT_UNKNOWN_ERROR /// diff --git a/V8/v8-utils.cpp b/V8/v8-utils.cpp index e01273e1bc..45a8bd45c4 100644 --- a/V8/v8-utils.cpp +++ b/V8/v8-utils.cpp @@ -735,9 +735,7 @@ static void WeakDictionaryCallback (v8::Persistent object, void* para WD* dictionary; char* key; - TRI_v8_global_t* v8g; - v8g = (TRI_v8_global_t*) v8::Isolate::GetCurrent()->GetData(); dictionary = (WD*) ((wd_key_pair_t*) parameter)->_dictionary; key = ((wd_key_pair_t*) parameter)->_key; @@ -767,10 +765,6 @@ static v8::Handle WeakDictionaryInvocationCallback (v8::Arguments con typedef Dictionary< v8::Persistent* > WD; static uint64_t MIN_SIZE = 100; - TRI_v8_global_t* v8g; - - v8g = (TRI_v8_global_t*) v8::Isolate::GetCurrent()->GetData(); - v8::Handle self = args.Holder(); if (self->InternalFieldCount() <= 1) { diff --git a/V8Client/avocimp.cpp b/V8Client/avocimp.cpp index b376fbc9de..371bc8d68e 100644 --- a/V8Client/avocimp.cpp +++ b/V8Client/avocimp.cpp @@ -164,6 +164,9 @@ static void ParseProgramOptions (int argc, char* argv[]) { ("max-upload-size", &maxUploadSize, "maximum size of import chunks") ; + vector myargs; + description.arguments(&myargs); + ProgramOptions options; if (! options.parse(description, argc, argv)) { @@ -171,6 +174,10 @@ static void ParseProgramOptions (int argc, char* argv[]) { exit(EXIT_FAILURE); } + if (FileName == "" && myargs.size() > 0) { + FileName = myargs[0]; + } + // check for help set help = options.needHelp("help"); diff --git a/V8Client/avocsh.cpp b/V8Client/avocsh.cpp index 5bda743a95..11a21778d9 100644 --- a/V8Client/avocsh.cpp +++ b/V8Client/avocsh.cpp @@ -949,6 +949,7 @@ static void RunShell (v8::Handle context) { string i = triagens::basics::StringUtils::trim(input); if (i == "exit" || i == "quit") { + TRI_FreeString(input); break; } @@ -1318,7 +1319,9 @@ int main (int argc, char* argv[]) { context->Exit(); context.Dispose(); - v8::V8::Dispose(); + + // calling dispose in V8 3.10.x causes a segfault. the v8 docs says its not necessary to call it upon program termination + // v8::V8::Dispose(); return ret; } diff --git a/js/actions/system/api-graph.js b/js/actions/system/api-graph.js new file mode 100644 index 0000000000..279bd94905 --- /dev/null +++ b/js/actions/system/api-graph.js @@ -0,0 +1,214 @@ +//////////////////////////////////////////////////////////////////////////////// +/// @brief graph api +/// +/// @file +/// +/// DISCLAIMER +/// +/// Copyright 2012 triagens GmbH, Cologne, Germany +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// +/// Copyright holder is triAGENS GmbH, Cologne, Germany +/// +/// @author Achim Brandt +/// @author Jan Steemann +/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany +//////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +/// @addtogroup AvocadoAPI +/// @{ +//////////////////////////////////////////////////////////////////////////////// + +// ----------------------------------------------------------------------------- +// --SECTION-- global variables +// ----------------------------------------------------------------------------- + +var actions = require("actions"); +var graph = require("graph"); + +// ----------------------------------------------------------------------------- +// --SECTION-- private functions +// ----------------------------------------------------------------------------- + + +//////////////////////////////////////////////////////////////////////////////// +/// @brief create a key value pair +//////////////////////////////////////////////////////////////////////////////// + +function postGraph(req, res) { + try { + var name = req.parameters['name']; + var vertices = req.parameters['vertices']; + var edges = req.parameters['edges']; + + var g = new graph.Graph(name, vertices, edges); + + if (g._properties == null) { + throw "no properties of graph found"; + } + actions.resultOk(req, res, actions.HTTP_OK, { "graph" : g._properties} ); + } + catch (err) { + actions.resultBad(req, res, actions.ERROR_GRAPH_COULD_NOT_CREATE_GRAPH, err); + } +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief return graph data +//////////////////////////////////////////////////////////////////////////////// + +function getGraph(req, res) { + try { + var name = req.parameters['name']; + var g = new graph.Graph(name); + + if (g._properties == null) { + throw "no properties of graph found"; + } + actions.resultOk(req, res, actions.HTTP_OK, { "graph" : g._properties} ); + } + catch (err) { + actions.resultBad(req, res, actions.ERROR_GRAPH_INVALID_GRAPH, err); + } +} + +// ----------------------------------------------------------------------------- +// --SECTION-- initialiser +// ----------------------------------------------------------------------------- + +//////////////////////////////////////////////////////////////////////////////// +/// @brief key value pair actions gateway +//////////////////////////////////////////////////////////////////////////////// + +actions.defineHttp({ + url : "_api/graph/graph", + context : "api", + + callback : function (req, res) { + switch (req.requestType) { + case (actions.POST) : + postGraph(req, res); + break; + + case (actions.GET) : + getGraph(req, res); + break; + + default: + actions.resultUnsupported(req, res); + } + } +}); + + +//////////////////////////////////////////////////////////////////////////////// +/// @} +//////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +/// @addtogroup AvocadoAPI +/// @{ +//////////////////////////////////////////////////////////////////////////////// + +// ----------------------------------------------------------------------------- +// --SECTION-- private functions +// ----------------------------------------------------------------------------- + +//////////////////////////////////////////////////////////////////////////////// +/// @brief add a vertex +//////////////////////////////////////////////////////////////////////////////// + +function postVertex(req, res) { + try { + // name/id of the graph + var name = req.parameters['name']; + + var g = new graph.Graph(name); + + var id = req.parameters['id']; + var v; + if (req.requestBody != null && req.requestBody != "") { + var body = JSON.parse(req.requestBody); + v = g.addVertex(id, body); + } + else { + v = g.addVertex(id); + } + + if (v == undefined || v._properties == undefined) { + throw "could not create vertex"; + } + + actions.resultOk(req, res, actions.HTTP_OK, { "vertex" : v._properties } ); + } + catch (err) { + actions.resultBad(req, res, actions.ERROR_GRAPH_COULD_NOT_CREATE_VERTEX, err); + } +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief add a vertex +//////////////////////////////////////////////////////////////////////////////// + +function getVertex(req, res) { + try { + // name/id of the graph + var name = req.parameters['name']; + + var g = new graph.Graph(name); + + var id = req.parameters['id']; + + var v = g.getVertex(id); + + if (v == undefined || v._properties == undefined) { + throw "no vertex found"; + } + + actions.resultOk(req, res, actions.HTTP_OK, { "vertex" : v._properties} ); + } + catch (err) { + actions.resultBad(req, res, actions.ERROR_GRAPH_INVALID_VERTEX, err); + } +} + +actions.defineHttp({ + url : "_api/graph/vertex", + context : "api", + + callback : function (req, res) { + switch (req.requestType) { + case (actions.POST) : + postVertex(req, res); + break; + + case (actions.GET) : + getVertex(req, res); + break; + + default: + actions.resultUnsupported(req, res); + } + } +}); + +//////////////////////////////////////////////////////////////////////////////// +/// @} +//////////////////////////////////////////////////////////////////////////////// + +// Local Variables: +// mode: outline-minor +// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @}\\)" +// End: diff --git a/js/actions/system/key-value.js b/js/actions/system/key-value.js index 426197ff03..7edd76c727 100644 --- a/js/actions/system/key-value.js +++ b/js/actions/system/key-value.js @@ -328,19 +328,19 @@ actions.defineHttp({ callback : function (req, res) { switch (req.requestType) { - case (actions.HTTP_POST) : + case (actions.POST) : postKeyValue(req, res); break; - case (actions.HTTP_GET) : + case (actions.GET) : getKeyValue(req, res); break; - case (actions.HTTP_PUT) : + case (actions.PUT) : putKeyValue(req, res); break; - case (actions.HTTP_DELETE) : + case (actions.DELETE) : deleteKeyValue(req, res); break; @@ -427,7 +427,7 @@ actions.defineHttp({ callback : function (req, res) { switch (req.requestType) { - case (actions.HTTP_GET) : + case (actions.GET) : searchKeyValue(req, res); break; diff --git a/js/common/bootstrap/errors.js b/js/common/bootstrap/errors.js index f84c626db2..f759a313ce 100644 --- a/js/common/bootstrap/errors.js +++ b/js/common/bootstrap/errors.js @@ -99,6 +99,10 @@ ModuleCache["/internal"].exports.errors = { "ERROR_KEYVALUE_KEY_NOT_UNIQUE" : { "code" : 1803, "message" : "key is not unique" }, "ERROR_KEYVALUE_KEY_NOT_CHANGED" : { "code" : 1804, "message" : "key value not changed" }, "ERROR_KEYVALUE_KEY_NOT_REMOVED" : { "code" : 1805, "message" : "key value not removed" }, + "ERROR_GRAPH_INVALID_GRAPH" : { "code" : 1901, "message" : "invalid graph" }, + "ERROR_GRAPH_COULD_NOT_CREATE_GRAPH" : { "code" : 1902, "message" : "could not create graph" }, + "ERROR_GRAPH_INVALID_VERTEX" : { "code" : 1903, "message" : "invalid vertex" }, + "ERROR_GRAPH_COULD_NOT_CREATE_VERTEX" : { "code" : 1904, "message" : "could not create vertex" }, "SIMPLE_CLIENT_UNKNOWN_ERROR" : { "code" : 2000, "message" : "unknown client error" }, "SIMPLE_CLIENT_COULD_NOT_CONNECT" : { "code" : 2001, "message" : "could not connect to server" }, "SIMPLE_CLIENT_COULD_NOT_WRITE" : { "code" : 2002, "message" : "could not write to server" }, diff --git a/js/common/bootstrap/js-errors.h b/js/common/bootstrap/js-errors.h index 6752c5661d..aca52d86c5 100644 --- a/js/common/bootstrap/js-errors.h +++ b/js/common/bootstrap/js-errors.h @@ -100,6 +100,10 @@ static string JS_common_bootstrap_errors = " \"ERROR_KEYVALUE_KEY_NOT_UNIQUE\" : { \"code\" : 1803, \"message\" : \"key is not unique\" }, \n" " \"ERROR_KEYVALUE_KEY_NOT_CHANGED\" : { \"code\" : 1804, \"message\" : \"key value not changed\" }, \n" " \"ERROR_KEYVALUE_KEY_NOT_REMOVED\" : { \"code\" : 1805, \"message\" : \"key value not removed\" }, \n" + " \"ERROR_GRAPH_INVALID_GRAPH\" : { \"code\" : 1901, \"message\" : \"invalid graph\" }, \n" + " \"ERROR_GRAPH_COULD_NOT_CREATE_GRAPH\" : { \"code\" : 1902, \"message\" : \"could not create graph\" }, \n" + " \"ERROR_GRAPH_INVALID_VERTEX\" : { \"code\" : 1903, \"message\" : \"invalid vertex\" }, \n" + " \"ERROR_GRAPH_COULD_NOT_CREATE_VERTEX\" : { \"code\" : 1904, \"message\" : \"could not create vertex\" }, \n" " \"SIMPLE_CLIENT_UNKNOWN_ERROR\" : { \"code\" : 2000, \"message\" : \"unknown client error\" }, \n" " \"SIMPLE_CLIENT_COULD_NOT_CONNECT\" : { \"code\" : 2001, \"message\" : \"could not connect to server\" }, \n" " \"SIMPLE_CLIENT_COULD_NOT_WRITE\" : { \"code\" : 2002, \"message\" : \"could not write to server\" }, \n" diff --git a/js/common/modules/graph.js b/js/common/modules/graph.js index 30a80a6913..935cd6a0f7 100644 --- a/js/common/modules/graph.js +++ b/js/common/modules/graph.js @@ -705,13 +705,14 @@ Vertex.prototype._PRINT = function (seen, path, names) { /// @verbinclude graph1 //////////////////////////////////////////////////////////////////////////////// -function Graph (vertices, edges) { +function Graph (name, vertices, edges) { // collection var gdb = internal.db._collection("_graph"); if (gdb == null) { gdb = internal.db._create("_graph", { waitForSync : true, isSystem : true }); + gdb.ensureUniqueConstraint("name"); } // get the vertices collection @@ -747,19 +748,105 @@ function Graph (vertices, edges) { if (! edges instanceof AvocadoEdgesCollection) { throw " must be an edges collection"; } - - // check if know that graph - var props = gdb.firstExample('vertices', vertices._id, 'edges', edges._id); - + + // find graph by name + if (typeof name != "string" || name === "") { + throw " must be a string"; + } + + var props = gdb.firstExample('name', name); if (props == null) { - var d = gdb.save({ 'vertices' : vertices._id, + // name is unknown + // + // check if know that graph + props = gdb.firstExample('vertices', vertices._id, 'edges', edges._id); + if (props == null) { + var d = gdb.save({ 'vertices' : vertices._id, 'verticesName' : vertices.name(), 'edges' : edges._id, - 'edgesName' : edges.name() }); + 'edgesName' : edges.name(), + 'name' : name }); - props = gdb.document(d); + props = gdb.document(d); + } + else { + throw "found graph but has different "; + } + + } + else { + if (props.vertices != vertices._id) { + throw "found graph but has different "; + } + if (props.edges != edges._id) { + throw "found graph but has different "; + } + } + + this._properties = props; + + // and store the collections + this._vertices = vertices; + this._edges = edges; + + // and weak dictionary for vertices and edges + this._weakVertices = new WeakDictionary(); + this._weakEdges = new WeakDictionary(); +} + +function Graph (name) { + + // collection + var gdb = internal.db._collection("_graph"); + + if (gdb == null) { + gdb = internal.db._create("_graph", { waitForSync : true, isSystem : true }); + gdb.ensureUniqueConstraint("name"); } + + var props = gdb.firstExample('name', name); + if (props == null) { + throw "graph not found"; + } + + var vertices = props.verticesName; + var edges = props.edgesName; + + // get the vertices collection + if (typeof vertices === "string") { + var col = internal.db._collection(vertices); + + if (col == null) { + col = internal.db._create(vertices); + } + + // col.ensureUniqueConstraint("$id"); + + vertices = col; + } + + if (! vertices instanceof AvocadoCollection) { + throw " must be a document collection"; + } + + // get the edges collection + if (typeof edges === "string") { + var col = internal.edges._collection(edges); + + if (col == null) { + col = internal.db._create(edges); + } + + // col.ensureUniqueConstraint("$id"); + + edges = col; + } + + if (! edges instanceof AvocadoEdgesCollection) { + throw " must be an edges collection"; + } + this._properties = props; // and store the collections @@ -903,7 +990,7 @@ Graph.prototype.addVertex = function (id, data) { Graph.prototype.getVertex = function (id) { var e = this._vertices.firstExample('$id', id); - if (e !== null) { + if (e !== null && e != undefined) { return this.constructVertex(e._id); } else { @@ -1108,7 +1195,7 @@ Graph.prototype.constructEdge = function(id) { //////////////////////////////////////////////////////////////////////////////// Graph.prototype._PRINT = function (seen, path, names) { - internal.output("Graph(\"", this._vertices.name(), "\", \"" + this._edges.name(), "\")"); + internal.output("Graph(\"", this._properties.name, "\", \"", this._vertices.name(), "\", \"" + this._edges.name(), "\")"); } ////////////////////////////////////////////////////////////////////////////////