From 53364b7f15693bdbc8acf1e23712ead6ec81fe7a Mon Sep 17 00:00:00 2001 From: Frank Celler Date: Thu, 3 Jan 2013 16:27:59 +0100 Subject: [PATCH 1/4] updated error codes --- Makefile.in | 2 +- arangod/RestServer/ArangoServer.cpp | 5 - arangod/V8Server/ApplicationV8.cpp | 33 +- etc/arangodb/arangod.conf.in | 3 +- etc/relative/arangod.conf | 1 + js/actions/system/api-collection.js | 2 +- js/actions/system/api-structure.js | 144 ++++++ js/client/client.js | 6 +- js/common/bootstrap/errors.js | 3 + js/common/bootstrap/modules.js | 103 +++-- js/server/ArangoStructure.js | 466 ++++++++++++++++++++ js/server/modules/org/arangodb/actions.js | 136 +++--- js/server/modules/org/arangodb/formatter.js | 85 ++++ js/server/modules/org/arangodb/new 2.txt | 51 --- js/server/modules/org/arangodb/parser.js | 99 +++++ js/server/modules/org/arangodb/validator.js | 136 ++++++ js/server/server.js | 2 + js/server/version-check.js | 21 +- lib/BasicsC/errors.dat | 2 + lib/BasicsC/voc-errors.c | 2 + lib/BasicsC/voc-errors.h | 24 + lib/Utilities/ScriptLoader.cpp | 16 +- lib/V8/JSLoader.cpp | 32 ++ lib/V8/JSLoader.h | 7 + 24 files changed, 1193 insertions(+), 188 deletions(-) create mode 100644 js/actions/system/api-structure.js create mode 100644 js/server/ArangoStructure.js create mode 100644 js/server/modules/org/arangodb/formatter.js delete mode 100644 js/server/modules/org/arangodb/new 2.txt create mode 100644 js/server/modules/org/arangodb/parser.js create mode 100644 js/server/modules/org/arangodb/validator.js diff --git a/Makefile.in b/Makefile.in index b6b157c951..07dcd16167 100644 --- a/Makefile.in +++ b/Makefile.in @@ -5289,7 +5289,7 @@ unittests-import: @echo $(VALGRIND) @builddir@/bin/arangosh $(CLIENT_OPT) --server.username "$(USERNAME)" --server.password "$(PASSWORD)" --server.endpoint unix://$(VOCDIR)/arango.sock --javascript.unit-tests @top_srcdir@/js/server/tests/import-setup.js || test "x$(FORCE)" == "x1" - for i in 1 2; do $(VALGRIND) @builddir@/bin/arangoimp --server.username "$(USERNAME)" --server.password "$(PASSWORD)" --server.endpoint unix://$(VOCDIR)/arango.sock --file UnitTests/import-$$i.json --collection UnitTestsImportJson$$i --type json || test "x$(FORCE)" == "x1"; done + for i in 1 2 3 4; do $(VALGRIND) @builddir@/bin/arangoimp --server.username "$(USERNAME)" --server.password "$(PASSWORD)" --server.endpoint unix://$(VOCDIR)/arango.sock --file UnitTests/import-$$i.json --collection UnitTestsImportJson$$i --type json || test "x$(FORCE)" == "x1"; done for i in 1 2; do $(VALGRIND) @builddir@/bin/arangoimp --server.username "$(USERNAME)" --server.password "$(PASSWORD)" --server.endpoint unix://$(VOCDIR)/arango.sock --file UnitTests/import-$$i.csv --collection UnitTestsImportCsv$$i --create-collection true --type csv || test "x$(FORCE)" == "x1"; done for i in 1 2; do $(VALGRIND) @builddir@/bin/arangoimp --server.username "$(USERNAME)" --server.password "$(PASSWORD)" --server.endpoint unix://$(VOCDIR)/arango.sock --file UnitTests/import-$$i.tsv --collection UnitTestsImportTsv$$i --create-collection true --type tsv --eol "\r\n" || test "x$(FORCE)" == "x1"; done $(VALGRIND) @builddir@/bin/arangosh $(CLIENT_OPT) --server.username "$(USERNAME)" --server.password "$(PASSWORD)" --server.endpoint unix://$(VOCDIR)/arango.sock --javascript.unit-tests @top_srcdir@/js/server/tests/import.js || test "x$(FORCE)" == "x1" diff --git a/arangod/RestServer/ArangoServer.cpp b/arangod/RestServer/ArangoServer.cpp index 674b74e126..461d126ad6 100644 --- a/arangod/RestServer/ArangoServer.cpp +++ b/arangod/RestServer/ArangoServer.cpp @@ -90,11 +90,6 @@ using namespace triagens::rest; using namespace triagens::admin; using namespace triagens::arango; -#ifdef TRI_ENABLE_MRUBY -#include "mr/common/bootstrap/mr-error.h" -#include "mr/server/mr-server.h" -#endif - // ----------------------------------------------------------------------------- // --SECTION-- private functions // ----------------------------------------------------------------------------- diff --git a/arangod/V8Server/ApplicationV8.cpp b/arangod/V8Server/ApplicationV8.cpp index c7a8c3b5ce..714559b712 100644 --- a/arangod/V8Server/ApplicationV8.cpp +++ b/arangod/V8Server/ApplicationV8.cpp @@ -43,14 +43,6 @@ using namespace triagens::basics; using namespace triagens::arango; using namespace std; -#include "js/common/bootstrap/js-modules.h" -#include "js/common/bootstrap/js-monkeypatches.h" -#include "js/common/bootstrap/js-print.h" -#include "js/common/bootstrap/js-errors.h" -#include "js/server/js-ahuacatl.h" -#include "js/server/js-server.h" -#include "js/server/js-version-check.h" - // ----------------------------------------------------------------------------- // --SECTION-- class V8GcThread // ----------------------------------------------------------------------------- @@ -519,7 +511,6 @@ void ApplicationV8::setupOptions (map bool ApplicationV8::prepare () { LOGGER_DEBUG << "V8 version: " << v8::V8::GetVersion(); - // use a minimum of 1 second for GC if (_gcFrequency < 1) { @@ -538,17 +529,12 @@ bool ApplicationV8::prepare () { // set up the startup loader if (_startupPath.empty()) { - LOGGER_INFO << "using built-in JavaScript startup files"; - _startupLoader.defineScript("common/bootstrap/modules.js", JS_common_bootstrap_modules); - _startupLoader.defineScript("common/bootstrap/monkeypatches.js", JS_common_bootstrap_monkeypatches); - _startupLoader.defineScript("common/bootstrap/print.js", JS_common_bootstrap_print); - _startupLoader.defineScript("common/bootstrap/errors.js", JS_common_bootstrap_errors); - _startupLoader.defineScript("server/ahuacatl.js", JS_server_ahuacatl); - _startupLoader.defineScript("server/server.js", JS_server_server); + LOGGER_FATAL << "no 'javascript.startup-directory' has been supplied, giving up"; + TRI_FlushLogging(); + exit(EXIT_FAILURE); } else { LOGGER_INFO << "using JavaScript startup files at '" << _startupPath << "'"; - _startupLoader.setDirectory(_startupPath); } @@ -566,7 +552,7 @@ bool ApplicationV8::prepare () { } } - + // add v8 options if (_v8Options.size() > 0) { LOGGER_INFO << "using V8 options '" << _v8Options << "'"; v8::V8::SetFlagsFromString(_v8Options.c_str(), _v8Options.size()); @@ -649,7 +635,8 @@ bool ApplicationV8::prepareV8Instance (const size_t i) { "common/bootstrap/print.js", "common/bootstrap/errors.js", "server/ahuacatl.js", - "server/server.js" + "server/server.js", + "server/ArangoStructure.js" }; LOGGER_TRACE << "initialising V8 context #" << i; @@ -707,15 +694,11 @@ bool ApplicationV8::prepareV8Instance (const size_t i) { if (i == 0 && ! _skipUpgrade) { LOGGER_DEBUG << "running database version check"; - const string script = _startupLoader.buildScript(JS_server_version_check); - // special check script to be run just once in first thread (not in all) v8::HandleScope scope; context->_context->Global()->Set(v8::String::New("UPGRADE"), _performUpgrade ? v8::True() : v8::False()); - v8::Handle result = TRI_ExecuteJavaScriptString(context->_context, - v8::String::New(script.c_str()), - v8::String::New("version-check.js"), - false); + + v8::Handle result = _startupLoader.executeGlobalScript(context->_context, "server/version-check.js"); if (! TRI_ObjectToBoolean(result)) { if (_performUpgrade) { diff --git a/etc/arangodb/arangod.conf.in b/etc/arangodb/arangod.conf.in index 722458439f..681f7c7931 100644 --- a/etc/arangodb/arangod.conf.in +++ b/etc/arangodb/arangod.conf.in @@ -36,7 +36,8 @@ threads = 5 threads = 3 [javascript] -action-directory= @PKGDATADIR@/js/actions/system +startup-directory = @PKGDATADIR@/js +action-directory = @PKGDATADIR@/js/actions/system modules-path = @PKGDATADIR@/js/server/modules;@PKGDATADIR@/js/common/modules [ruby] diff --git a/etc/relative/arangod.conf b/etc/relative/arangod.conf index 570cdfdb44..c5703889d0 100644 --- a/etc/relative/arangod.conf +++ b/etc/relative/arangod.conf @@ -14,6 +14,7 @@ threads = 5 threads = 3 [javascript] +startup-directory = ./js action-directory = ./js/actions/system modules-path = ./js/server/modules;./js/common/modules diff --git a/js/actions/system/api-collection.js b/js/actions/system/api-collection.js index 5b2ac9c209..4cfd25a047 100644 --- a/js/actions/system/api-collection.js +++ b/js/actions/system/api-collection.js @@ -749,7 +749,7 @@ } //////////////////////////////////////////////////////////////////////////////// -/// @brief reads or creates a collection +/// @brief handles a collection request //////////////////////////////////////////////////////////////////////////////// actions.defineHttp({ diff --git a/js/actions/system/api-structure.js b/js/actions/system/api-structure.js new file mode 100644 index 0000000000..1ff00609a0 --- /dev/null +++ b/js/actions/system/api-structure.js @@ -0,0 +1,144 @@ +//////////////////////////////////////////////////////////////////////////////// +/// @brief querying and managing structures +/// +/// @file +/// +/// DISCLAIMER +/// +/// Copyright 2013 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 Dr. Frank Celler +/// @author Copyright 2013, triAGENS GmbH, Cologne, Germany +//////////////////////////////////////////////////////////////////////////////// + +var arangodb = require("org/arangodb"); +var actions = require("org/arangodb/actions"); + +var API = "_api/structures"; + +// ----------------------------------------------------------------------------- +// --SECTION-- private functions +// ----------------------------------------------------------------------------- + +//////////////////////////////////////////////////////////////////////////////// +/// @addtogroup ArangoAPI +/// @{ +//////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +/// @} +//////////////////////////////////////////////////////////////////////////////// + +// ----------------------------------------------------------------------------- +// --SECTION-- public functions +// ----------------------------------------------------------------------------- + +//////////////////////////////////////////////////////////////////////////////// +/// @addtogroup ArangoAPI +/// @{ +//////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +/// @brief creates a collection +/// +/// @RESTHEADER{POST /_api/structure,creates a structured document} +/// +/// @REST{POST /_api/structure?collection=@FA{collection-identifier}} +/// +/// Creates a new document in the collection identified by the +/// @FA{collection-identifier}. A JSON representation of the document must be +/// passed as the body of the POST request. The document must fullfill the +/// requirements of the structure definition, see @ref ArangoStructures. +/// +/// In all other respects the function is identical to the +/// @ref triagens::arango::RestDocumentHandler::createDocument "POST /_api/structure". +//////////////////////////////////////////////////////////////////////////////// + +function POST_api_structure (req, res) { + var body; + var collection; + var id; + var name; + var result; + var vertex; + + body = actions.getJsonBody(req, res); + + if (body === undefined) { + return; + } + + name = decodeURIComponent(req.suffix[0]); + id = parseInt(name) || name; + collection = arangodb.db._structure(id); + + if (collection === null) { + actions.collectionNotFound(req, res, name); + return; + } + + res = collection.save(body); + + actions.resultOk(req, res, actions.HTTP_OK, result); +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief handles a structure request +//////////////////////////////////////////////////////////////////////////////// + +actions.defineHttp({ + url : API, + context : "api", + + callback : function (req, res) { + try { + if (req.requestType === actions.GET) { + GET_api_structure(req, res); + } + else if (req.requestType === actions.DELETE) { + DELETE_api_structure(req, res); + } + else if (req.requestType === actions.POST) { + POST_api_structure(req, res); + } + else if (req.requestType === actions.PUT) { + PUT_api_structure(req, res); + } + else { + actions.resultUnsupported(req, res); + } + } + catch (err) { + actions.resultException(req, res, err); + } + } +}); + +//////////////////////////////////////////////////////////////////////////////// +/// @} +//////////////////////////////////////////////////////////////////////////////// + +})(); + +// ----------------------------------------------------------------------------- +// --SECTION-- END-OF-FILE +// ----------------------------------------------------------------------------- + +// Local Variables: +// mode: outline-minor +// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @\\}\\)" +// End: diff --git a/js/client/client.js b/js/client/client.js index 92142aa0f4..cff1394a82 100755 --- a/js/client/client.js +++ b/js/client/client.js @@ -5,7 +5,7 @@ vars: true, white: true, plusplus: true */ -/*global require, arango, db, edges, ModuleCache, Module */ +/*global require, arango, db, edges, Module */ //////////////////////////////////////////////////////////////////////////////// /// @brief ArangoShell client API @@ -129,11 +129,11 @@ function ArangoError (error) { /// @{ //////////////////////////////////////////////////////////////////////////////// -ModuleCache["/arangosh"] = new Module("/arangosh"); +Module.prototype.ModuleCache["/arangosh"] = new Module("/arangosh"); (function () { var internal = require("internal"); - var client = ModuleCache["/arangosh"].exports; + var client = Module.prototype.ModuleCache["/arangosh"].exports; //////////////////////////////////////////////////////////////////////////////// /// @} diff --git a/js/common/bootstrap/errors.js b/js/common/bootstrap/errors.js index c79bc645be..95cc1e265d 100644 --- a/js/common/bootstrap/errors.js +++ b/js/common/bootstrap/errors.js @@ -52,6 +52,7 @@ "ERROR_ARANGO_DATAFILE_ALREADY_EXISTS" : { "code" : 1106, "message" : "cannot create/rename datafile because it already exists" }, "ERROR_ARANGO_DATABASE_LOCKED" : { "code" : 1107, "message" : "database is locked" }, "ERROR_ARANGO_COLLECTION_DIRECTORY_ALREADY_EXISTS" : { "code" : 1108, "message" : "cannot create/rename collection because directory already exists" }, + "ERROR_ARANGO_MSYNC_FAILED" : { "code" : 1109, "message" : "msync failed" }, "ERROR_ARANGO_CONFLICT" : { "code" : 1200, "message" : "conflict" }, "ERROR_ARANGO_WRONG_VOCBASE_PATH" : { "code" : 1201, "message" : "wrong path for database" }, "ERROR_ARANGO_DOCUMENT_NOT_FOUND" : { "code" : 1202, "message" : "document not found" }, @@ -71,6 +72,8 @@ "ERROR_ARANGO_DOCUMENT_TOO_LARGE" : { "code" : 1216, "message" : "document too large" }, "ERROR_ARANGO_COLLECTION_NOT_UNLOADED" : { "code" : 1217, "message" : "collection must be unloaded" }, "ERROR_ARANGO_COLLECTION_TYPE_INVALID" : { "code" : 1218, "message" : "collection type invalid" }, + "ERROR_ARANGO_VALIDATION_FAILED" : { "code" : 1219, "message" : "validator failed" }, + "ERROR_ARANGO_PARSER_FAILED" : { "code" : 1219, "message" : "parser failed" }, "ERROR_ARANGO_DATAFILE_FULL" : { "code" : 1300, "message" : "datafile full" }, "ERROR_QUERY_KILLED" : { "code" : 1500, "message" : "query killed" }, "ERROR_QUERY_PARSE" : { "code" : 1501, "message" : "%s" }, diff --git a/js/common/bootstrap/modules.js b/js/common/bootstrap/modules.js index d44dff3008..f92b1a16f4 100644 --- a/js/common/bootstrap/modules.js +++ b/js/common/bootstrap/modules.js @@ -5,13 +5,13 @@ vars: true, white: true, plusplus: true */ -/*global require, module, ModuleCache, SYS_EXECUTE, CONSOLE_ERROR, - FS_MOVE, FS_REMOVE, FS_EXISTS, - SYS_LOAD, SYS_LOG, SYS_LOG_LEVEL, SYS_OUTPUT, - SYS_PROCESS_STAT, SYS_READ, SYS_SPRINTF, SYS_TIME, - SYS_START_PAGER, SYS_STOP_PAGER, ARANGO_QUIET, MODULES_PATH, - COLOR_OUTPUT, COLOR_OUTPUT_RESET, COLOR_BRIGHT, PRETTY_PRINT, - SYS_SHA256, SYS_WAIT, SYS_GETLINE */ +/*global + require, module, + SYS_EXECUTE, CONSOLE_ERROR, FS_MOVE, FS_REMOVE, FS_EXISTS, SYS_LOAD, SYS_LOG, + SYS_LOG_LEVEL, SYS_OUTPUT, SYS_PROCESS_STAT, SYS_READ, SYS_SPRINTF, SYS_TIME, + SYS_START_PAGER, SYS_STOP_PAGER, ARANGO_QUIET, MODULES_PATH, COLOR_OUTPUT, + COLOR_OUTPUT_RESET, COLOR_BRIGHT, PRETTY_PRINT, SYS_SHA256, SYS_WAIT, SYS_GETLINE +*/ //////////////////////////////////////////////////////////////////////////////// /// @brief JavaScript server functions @@ -49,18 +49,6 @@ /// @{ //////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -/// @brief module cache -//////////////////////////////////////////////////////////////////////////////// - -ModuleCache = {}; - -//////////////////////////////////////////////////////////////////////////////// -/// @brief file exists cache -//////////////////////////////////////////////////////////////////////////////// - -ExistsCache = {}; - //////////////////////////////////////////////////////////////////////////////// /// @brief module constructor //////////////////////////////////////////////////////////////////////////////// @@ -70,6 +58,18 @@ function Module (id) { this.exports = {}; } +//////////////////////////////////////////////////////////////////////////////// +/// @brief module cache +//////////////////////////////////////////////////////////////////////////////// + +Module.prototype.ModuleCache = {}; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief file exists cache +//////////////////////////////////////////////////////////////////////////////// + +Module.prototype.ModuleExistsCache = {}; + //////////////////////////////////////////////////////////////////////////////// /// @brief loads a file and creates a new module descriptor //////////////////////////////////////////////////////////////////////////////// @@ -86,12 +86,12 @@ Module.prototype.require = function (path) { path = this.normalise(path); // check if you already know the module, return the exports - if (ModuleCache.hasOwnProperty(path)) { - return ModuleCache[path].exports; + if (this.ModuleCache.hasOwnProperty(path)) { + return this.ModuleCache[path].exports; } // locate file and read content - raw = ModuleCache["/internal"].exports.readFile(path); + raw = this.ModuleCache["/internal"].exports.readFile(path); // test for parse errors first and fail early if a parse error detected if (! SYS_PARSE(raw.content, path)) { @@ -99,7 +99,7 @@ Module.prototype.require = function (path) { } // create a new sandbox and execute - module = ModuleCache[path] = new Module(path); + module = this.ModuleCache[path] = new Module(path); content = "(function (module, exports, require, print) {" + raw.content @@ -115,7 +115,7 @@ Module.prototype.require = function (path) { f(module, module.exports, function(path) { return module.require(path); }, - ModuleCache["/internal"].exports.print); + this.ModuleCache["/internal"].exports.print); } catch (err) { throw "Javascript exception in file '" + path + "': " + err.stack; @@ -124,6 +124,14 @@ Module.prototype.require = function (path) { return module.exports; }; +//////////////////////////////////////////////////////////////////////////////// +/// @brief returns true if require found a file +//////////////////////////////////////////////////////////////////////////////// + +Module.prototype.exists = function (path) { + return this.ModuleExistsCache[path]; +} + //////////////////////////////////////////////////////////////////////////////// /// @brief normalises a path //////////////////////////////////////////////////////////////////////////////// @@ -192,7 +200,7 @@ Module.prototype.unload = function (path) { return; } - delete ModuleCache[norm]; + delete this.ModuleCache[norm]; }; //////////////////////////////////////////////////////////////////////////////// @@ -202,8 +210,8 @@ Module.prototype.unload = function (path) { Module.prototype.unloadAll = function () { var path; - for (path in ModuleCache) { - if (ModuleCache.hasOwnProperty(path)) { + for (path in this.ModuleCache) { + if (this.ModuleCache.hasOwnProperty(path)) { this.unload(path); } } @@ -213,7 +221,7 @@ Module.prototype.unloadAll = function () { /// @brief top-level module //////////////////////////////////////////////////////////////////////////////// -module = ModuleCache["/"] = new Module("/"); +module = Module.prototype.ModuleCache["/"] = new Module("/"); //////////////////////////////////////////////////////////////////////////////// /// @brief global require function @@ -259,10 +267,10 @@ function require (path) { /// @brief file-system module //////////////////////////////////////////////////////////////////////////////// -ModuleCache["/fs"] = new Module("/fs"); +Module.prototype.ModuleCache["/fs"] = new Module("/fs"); (function () { - var fs = ModuleCache["/fs"].exports; + var fs = Module.prototype.ModuleCache["/fs"].exports; fs.exists = FS_EXISTS; fs.move = FS_MOVE; @@ -286,11 +294,11 @@ ModuleCache["/fs"] = new Module("/fs"); /// @brief internal module //////////////////////////////////////////////////////////////////////////////// -ModuleCache["/internal"] = new Module("/internal"); +Module.prototype.ModuleCache["/internal"] = new Module("/internal"); (function () { - var internal = ModuleCache["/internal"].exports; - var fs = ModuleCache["/fs"].exports; + var internal = Module.prototype.ModuleCache["/internal"].exports; + var fs = Module.prototype.ModuleCache["/fs"].exports; // system functions internal.execute = SYS_EXECUTE; @@ -386,6 +394,20 @@ ModuleCache["/internal"] = new Module("/internal"); internal.COLOR_OUTPUT_RESET = COLOR_OUTPUT_RESET; } +//////////////////////////////////////////////////////////////////////////////// +/// @brief extends a prototype +//////////////////////////////////////////////////////////////////////////////// + + internal.extend = function (target, source) { + Object.getOwnPropertyNames(source) + .forEach(function(propName) { + Object.defineProperty(target, propName, + Object.getOwnPropertyDescriptor(source, propName)); + }); + + return target; + }; + //////////////////////////////////////////////////////////////////////////////// /// @brief reads a file from the module path or the database //////////////////////////////////////////////////////////////////////////////// @@ -395,8 +417,6 @@ ModuleCache["/internal"] = new Module("/internal"); var mc; var n; - var existsCache = ExistsCache; - // try to load the file var paths = internal.MODULES_PATH; @@ -411,7 +431,7 @@ ModuleCache["/internal"] = new Module("/internal"); } if (fs.exists(n)) { - existsCache[path] = true; + Module.prototype.ModuleExistsCache[path] = true; return { path : n, content : internal.read(n) }; } } @@ -424,7 +444,7 @@ ModuleCache["/internal"] = new Module("/internal"); if (n !== null) { if (n.hasOwnProperty('content')) { - existsCache[path] = true; + Module.prototype.ModuleExistsCache[path] = true; return { path : "_collection/" + path, content : n.content }; } else { @@ -433,7 +453,8 @@ ModuleCache["/internal"] = new Module("/internal"); } } - existsCache[path] = false; + Module.prototype.ModuleExistsCache[path] = false; + throw "cannot find a file named '" + path + "' using the module path(s) '" @@ -520,11 +541,11 @@ ModuleCache["/internal"] = new Module("/internal"); /// @brief console module //////////////////////////////////////////////////////////////////////////////// -ModuleCache["/console"] = new Module("/console"); +Module.prototype.ModuleCache["/console"] = new Module("/console"); (function () { - var internal = ModuleCache["/internal"].exports; - var console = ModuleCache["/console"].exports; + var internal = Module.prototype.ModuleCache["/internal"].exports; + var console = Module.prototype.ModuleCache["/console"].exports; console.getline = SYS_GETLINE; diff --git a/js/server/ArangoStructure.js b/js/server/ArangoStructure.js new file mode 100644 index 0000000000..edd98bf89a --- /dev/null +++ b/js/server/ArangoStructure.js @@ -0,0 +1,466 @@ +/*jslint indent: 2, + nomen: true, + maxlen: 100, + sloppy: true, + vars: true, + white: true, + plusplus: true */ +/*global require */ + +//////////////////////////////////////////////////////////////////////////////// +/// @brief ArangoStructure +/// +/// @file +/// +/// DISCLAIMER +/// +/// Copyright 2011-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 Dr. Frank Celler +/// @author Copyright 2011-2012, triAGENS GmbH, Cologne, Germany +//////////////////////////////////////////////////////////////////////////////// + +(function () { + var internal = require("internal"); + var console = require("console"); + + var ArangoDatabase = internal.ArangoDatabase; + var ArangoCollection = internal.ArangoCollection; + var ArangoError = internal.ArangoError; + +// ----------------------------------------------------------------------------- +// --SECTION-- constructors and destructors +// ----------------------------------------------------------------------------- + +//////////////////////////////////////////////////////////////////////////////// +/// @addtogroup V8Shell +/// @{ +//////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +/// @brief constructor +//////////////////////////////////////////////////////////////////////////////// + + function ArangoStructure (collection, lang) { + this._id = collection._id; + this._collection = collection; + this._language = lang; + }; + + internal.ArangoStructure = ArangoStructure; + +//////////////////////////////////////////////////////////////////////////////// +/// @} +//////////////////////////////////////////////////////////////////////////////// + +// ----------------------------------------------------------------------------- +// --SECTION-- public methods +// ----------------------------------------------------------------------------- + +//////////////////////////////////////////////////////////////////////////////// +/// @addtogroup V8Shell +/// @{ +//////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +/// @brief name of a structure +//////////////////////////////////////////////////////////////////////////////// + + ArangoStructure.prototype.name = function () { + return this._collection.name(); + } + +//////////////////////////////////////////////////////////////////////////////// +/// @brief status of a structure +//////////////////////////////////////////////////////////////////////////////// + + ArangoStructure.prototype.status = function () { + return this._collection.status(); + } + +//////////////////////////////////////////////////////////////////////////////// +/// @brief type of a structure +//////////////////////////////////////////////////////////////////////////////// + + ArangoStructure.prototype.type = function () { + return this._collection.type(); + } + +//////////////////////////////////////////////////////////////////////////////// +/// @brief saves a document +//////////////////////////////////////////////////////////////////////////////// + + ArangoStructure.prototype.save = function (data, waitForSync) { + data = ParseStructureInformation(this._language, this._collection.name(), data); + + return this._collection.save(data, waitForSync); + } + +//////////////////////////////////////////////////////////////////////////////// +/// @brief replaces a document +//////////////////////////////////////////////////////////////////////////////// + + ArangoStructure.prototype.replace = function (document, data, overwrite, waitForSync) { + data = ParseStructureInformation(this._language, this._collection.name(), data); + + return this._collection.save(document, data, overwrite, waitForSync); + } + +//////////////////////////////////////////////////////////////////////////////// +/// @brief deletes a document +//////////////////////////////////////////////////////////////////////////////// + + ArangoStructure.prototype.remove = function (document, overwrite, waitForSync) { + return this._collection.remove(document, overwrite, waitForSync); + } + +//////////////////////////////////////////////////////////////////////////////// +/// @brief reads a document +//////////////////////////////////////////////////////////////////////////////// + + ArangoStructure.prototype.document = function (handle) { + var data; + + data = this._collection.document(handle); + + return FormatStructureInformation(this._language, this._collection.name(), data); + } + +//////////////////////////////////////////////////////////////////////////////// +/// @brief database accessor +//////////////////////////////////////////////////////////////////////////////// + + ArangoDatabase.prototype._structure = function (name, lang) { + var collection; + + collection = internal.db._collection(name); + + if (collection === null) { + return null; + } + + if (lang === undefined || lang === null) { + lang = "en"; + } + + return new ArangoStructure(collection, lang); + }; + +//////////////////////////////////////////////////////////////////////////////// +/// @} +//////////////////////////////////////////////////////////////////////////////// + +// ----------------------------------------------------------------------------- +// --SECTION-- private methods +// ----------------------------------------------------------------------------- + +//////////////////////////////////////////////////////////////////////////////// +/// @addtogroup V8Shell +/// @{ +//////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +/// @brief prints a collection +//////////////////////////////////////////////////////////////////////////////// + + ArangoStructure.prototype._PRINT = function () { + var status = type = "unknown"; + + switch (this.status()) { + case ArangoCollection.STATUS_NEW_BORN: status = "new born"; break; + case ArangoCollection.STATUS_UNLOADED: status = "unloaded"; break; + case ArangoCollection.STATUS_UNLOADING: status = "unloading"; break; + case ArangoCollection.STATUS_LOADED: status = "loaded"; break; + case ArangoCollection.STATUS_CORRUPTED: status = "corrupted"; break; + case ArangoCollection.STATUS_DELETED: status = "deleted"; break; + } + + switch (this.type()) { + case ArangoCollection.TYPE_DOCUMENT: type = "document"; break; + case ArangoCollection.TYPE_EDGE: type = "edge"; break; + case ArangoCollection.TYPE_ATTACHMENT: type = "attachment"; break; + } + + internal.output("[ArangoStructure ", + this._id, + ", \"", this.name(), "\" (type ", type, ", status ", status, "lang ", this._language, ")]"); + }; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief parses and validates the structure information +//////////////////////////////////////////////////////////////////////////////// + + function ParseStructureInformation (lang, name, data) { + var info; + var key; + var validated; + + info = internal.db._collection("_structures").firstExample({ collection: name }); + + if (info === null) { + return data; + } + + validated = {}; + + for (key in data) { + if (data.hasOwnProperty(key)) { + validated[key] = ParseStructureInformationRecursive(lang, info, key, key, data[key]); + } + } + + return validated; + } + +//////////////////////////////////////////////////////////////////////////////// +/// @brief parses and validates the structure information recursively +//////////////////////////////////////////////////////////////////////////////// + + function ParseStructureInformationRecursive (lang, info, path, key, value) { + var k; + var result; + + if (info.attributes.hasOwnProperty(path)) { + value = ParseAndValidate(lang, info.attributes[path], value); + } + + if (value instanceof Array) { + return value; + } + else if (value instanceof Object) { + result = {}; + + for (k in value) { + if (value.hasOwnProperty(k)) { + result[k] = ParseStructureInformationRecursive(lang, info, path + "." + k, k, value[k]); + } + } + + return result; + } + else { + return value; + } + } + +//////////////////////////////////////////////////////////////////////////////// +/// @brief parses and validates a single attribute +//////////////////////////////////////////////////////////////////////////////// + + function ParseAndValidate (lang, info, value) { + var type; + + // parse the input + if (info.hasOwnProperty("parser")) { + if (info.parser.hasOwnProperty(lang)) { + value = Parse(lang, info.parser[lang], value); + } + else if (info.parser.hasOwnProperty('default')) { + value = Parse(lang, info.parser['default'], value); + } + } + else if (info.hasOwnProperty("type")) { + type = info.type; + + if (type === "number") { + value = parseFloat(value); + } + else if (type === "string") { + value = String(value); + } + else if (type === "boolean") { + if (value === 1 || value === "1" || (/^true$/i).test(value)) { + value = true; + } + else { + value = false; + } + } + } + + // validate the input + if (info.hasOwnProperty("validator")) { + if (info.validator.hasOwnProperty(lang)) { + Validate(lang, info.validator[lang], value); + } + else if (info.validator.hasOwnProperty('default')) { + Validate(lang, info.validator['default'], value); + } + } + + // and return + return value; + } + +//////////////////////////////////////////////////////////////////////////////// +/// @brief parses a single attribute +//////////////////////////////////////////////////////////////////////////////// + + function Parse (lang, info, value) { + var error; + var module; + + try { + module = require(info.module); + } + catch (err) { + error = new ArangoError(); + error.errorNum = internal.errors.ERROR_NOT_IMPLEMENTED.code; + error.errorMessage = String(err); + + throw error; + } + + return module[info['do']](value, info, lang); + } + +//////////////////////////////////////////////////////////////////////////////// +/// @brief validates a single attribute +//////////////////////////////////////////////////////////////////////////////// + + function Validate (lang, info, value) { + var error; + var module; + + try { + module = require(info.module); + } + catch (err) { + error = new ArangoError(); + error.errorNum = internal.errors.ERROR_NOT_IMPLEMENTED.code; + error.errorMessage = String(err); + + throw error; + } + + module[info['do']](value, info, lang); + } + +//////////////////////////////////////////////////////////////////////////////// +/// @brief formats the structure information +//////////////////////////////////////////////////////////////////////////////// + + function FormatStructureInformation (lang, name, data) { + var info; + var key; + var formatted; + + info = internal.db._collection("_structures").firstExample({ collection: name }); + + if (info === null) { + return data; + } + + formatted = {}; + + for (key in data) { + if (data.hasOwnProperty(key)) { + formatted[key] = FormatStructureInformationRecursive(lang, info, key, key, data[key]); + } + } + + return formatted; + } + +//////////////////////////////////////////////////////////////////////////////// +/// @brief formats the structure information recursively +//////////////////////////////////////////////////////////////////////////////// + + function FormatStructureInformationRecursive (lang, info, path, key, value) { + var k; + var result; + + if (info.attributes.hasOwnProperty(path)) { + value = FormatValue(lang, info.attributes[path], value); + } + + if (value instanceof Array) { + return value; + } + else if (value instanceof Object) { + result = {}; + + for (k in value) { + if (value.hasOwnProperty(k)) { + result[k] = FormatStructureInformationRecursive(lang, info, path + "." + k, k, value[k]); + } + } + + return result; + } + else { + return value; + } + } + +//////////////////////////////////////////////////////////////////////////////// +/// @brief formats a single attribute +//////////////////////////////////////////////////////////////////////////////// + + function FormatValue (lang, info, value) { + var type; + + // parse the input + if (info.hasOwnProperty("formatter")) { + if (info.formatter.hasOwnProperty(lang)) { + value = Format(lang, info.formatter[lang], value); + } + else if (info.formatter.hasOwnProperty('default')) { + value = Format(lang, info.formatter['default'], value); + } + } + + // and return + return value; + } + +//////////////////////////////////////////////////////////////////////////////// +/// @brief formats a single attribute +//////////////////////////////////////////////////////////////////////////////// + + function Format (lang, info, value) { + var error; + var module; + + try { + module = require(info.module); + } + catch (err) { + error = new ArangoError(); + error.errorNum = internal.errors.ERROR_NOT_IMPLEMENTED.code; + error.errorMessage = String(err); + + throw error; + } + + return module[info['do']](value, info, lang); + } + +//////////////////////////////////////////////////////////////////////////////// +/// @} +//////////////////////////////////////////////////////////////////////////////// + +}()); + +// ----------------------------------------------------------------------------- +// --SECTION-- END-OF-FILE +// ----------------------------------------------------------------------------- + +// Local Variables: +// mode: outline-minor +// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @\\}\\)" +// End: diff --git a/js/server/modules/org/arangodb/actions.js b/js/server/modules/org/arangodb/actions.js index f0032f3712..78e25a5e4d 100644 --- a/js/server/modules/org/arangodb/actions.js +++ b/js/server/modules/org/arangodb/actions.js @@ -5,7 +5,7 @@ vars: true, white: true, plusplus: true */ -/*global require, exports */ +/*global require, exports, module */ //////////////////////////////////////////////////////////////////////////////// /// @brief JavaScript actions module @@ -69,8 +69,8 @@ var RoutingCache; /// @brief function that's returned for non-implemented actions //////////////////////////////////////////////////////////////////////////////// -function notImplementedFunction (triggerRoute, message) { - message += "\nThis error is triggered by the following route " + JSON.stringify(triggerRoute); +function NotImplementedFunction (route, message) { + message += "\nThis error was triggered by the following route " + JSON.stringify(route); console.error(message); @@ -85,8 +85,8 @@ function notImplementedFunction (triggerRoute, message) { /// @brief function that's returned for actions that produce an error //////////////////////////////////////////////////////////////////////////////// -function errorFunction (triggerRoute, message) { - message += "\nThis error is triggered by the following route " + JSON.stringify(triggerRoute); +function ErrorFunction (route, message) { + message += "\nThis error was triggered by the following route " + JSON.stringify(route); console.error(message); @@ -101,7 +101,7 @@ function errorFunction (triggerRoute, message) { /// @brief splits an URL into parts //////////////////////////////////////////////////////////////////////////////// -function splitUrl (url) { +function SplitUrl (url) { var cleaned; var i; var parts; @@ -151,14 +151,14 @@ function splitUrl (url) { /// @brief looks up an URL //////////////////////////////////////////////////////////////////////////////// -function lookupUrl (prefix, url) { +function LookupUrl (prefix, url) { if (url === undefined || url === '') { return null; } if (typeof url === 'string') { return { - urlParts: splitUrl(prefix + "/" + url), + urlParts: SplitUrl(prefix + "/" + url), methods: [ exports.GET, exports.HEAD ], constraint: {} }; @@ -166,7 +166,7 @@ function lookupUrl (prefix, url) { if (url.hasOwnProperty('match')) { return { - urlParts: splitUrl(prefix + "/" + url.match), + urlParts: SplitUrl(prefix + "/" + url.match), methods: url.methods || exports.ALL_METHODS, constraint: url.constraint || {} }; @@ -179,7 +179,7 @@ function lookupUrl (prefix, url) { /// @brief looks up a callback for static data //////////////////////////////////////////////////////////////////////////////// -function lookupCallbackStatic (content) { +function LookupCallbackStatic (content) { var type; var body; var methods; @@ -213,11 +213,12 @@ function lookupCallbackStatic (content) { /// @brief looks up a callback for an action //////////////////////////////////////////////////////////////////////////////// -function lookupCallbackAction (route, action) { +function LookupCallbackAction (route, action) { var path; var name; var func; var module; + var joined; var httpMethods = { 'get': exports.GET, 'head': exports.HEAD, @@ -228,35 +229,42 @@ function lookupCallbackAction (route, action) { }; if (typeof action === 'string') { - return lookupCallbackAction(route, { prefixController: action }); + return LookupCallbackAction(route, { prefixController: action }); } if (action.hasOwnProperty('do')) { path = action['do'].split("/"); name = path.pop(); func = null; + joined = path.join("/"); try { - module = require(path.join("/")); + module = require(joined); if (module.hasOwnProperty(name)) { func = module[name]; } else { - func = notImplementedFunction(route, "Could not find action named '" + name + "' in module '" + path.join("/") + "'"); + func = NotImplementedFunction(route, "could not find action named '" + name + "' in module '" + joined + "'"); } } catch (err) { - if (! ExistsCache[path.join("/")]) { - func = notImplementedFunction(route, "An error occurred while loading action named '" + name + "' in module '" + path.join("/") + "': " + String(err)); + if (! module.exists(joined)) { + func = NotImplementedFunction(route, + "an error occurred while loading action named '" + name + + "' in module '" + joined + "': " + String(err)); } else { - func = errorFunction(route, "An error occurred while loading action named '" + name + "' in module '" + path.join("/") + "': " + String(err)); + func = ErrorFunction(route, + "an error occurred while loading action named '" + name + + "' in module '" + joined + "': " + String(err)); } } if (func === null || typeof func !== 'function') { - func = errorFunction(route, "Invalid definition for the action named '" + name + "' in module '" + path.join("/") + "'"); + func = ErrorFunction(route, + "invalid definition for the action named '" + name + + "' in module '" + joined + "'"); } return { @@ -279,16 +287,20 @@ function lookupCallbackAction (route, action) { } if (req.requestType == httpMethods[m] && module.hasOwnProperty(m)) { - func = module[m] || - errorFunction(route, "Invalid definition for " + m + " action in action controller module '" + action.controller + "'"); + func = module[m] + || ErrorFunction(route, + "invalid definition for " + m + " action in action controller module '" + + action.controller + "'"); return func(req, res, options, next); } } if (module.hasOwnProperty('do')) { - func = module['do'] || - errorFunction(route, "Invalid definition for do action in action controller module '" + action.controller + "'"); + func = module['do'] + || ErrorFunction(route, + "invalid definition for do action in action controller module '" + + action.controller + "'"); return func(req, res, options, next); } @@ -300,11 +312,15 @@ function lookupCallbackAction (route, action) { }; } catch (err) { - if (! ExistsCache[action.controller]) { - return notImplementedFunction(route, "cannot load/execute action controller module '" + action.controller + ": " + String(err)); + if (! module.exists(action.controller)) { + return NotImplementedFunction(route, + "cannot load/execute action controller module '" + + action.controller + ": " + String(err)); } - return errorFunction(route, "cannot load/execute action controller module '" + action.controller + ": " + String(err)); + return ErrorFunction(route, + "cannot load/execute action controller module '" + + action.controller + ": " + String(err)); } } @@ -315,6 +331,7 @@ function lookupCallbackAction (route, action) { controller: function (req, res, options, next) { var module; var path; + var efunc; // determine path if (req.hasOwnProperty('suffix')) { @@ -329,11 +346,13 @@ function lookupCallbackAction (route, action) { require(path); } catch (err) { - if (! ExistsCache[path]) { - return notImplementedFunction(route, "cannot load prefix controller: " + String(err))(req, res, options, next); + efunc = ErrorFunction; + + if (! module.exists(path)) { + efunc = NotImplementedFunction; } - return errorFunction(route, "cannot load prefix controller: " + String(err))(req, res, options, next); + return efunc(route, "cannot load prefix controller: " + String(err))(req, res, options, next); } try { @@ -344,21 +363,28 @@ function lookupCallbackAction (route, action) { } if (req.requestType == httpMethods[m] && module.hasOwnProperty(m)) { - func = module[m] || - errorFunction(route, "Invalid definition for " + m + " action in prefix controller '" + action.prefixController + "'"); + func = module[m] + || ErrorFunction(route, + "Invalid definition for " + m + " action in prefix controller '" + + action.prefixController + "'"); return func(req, res, options, next); } } if (module.hasOwnProperty('do')) { - func = module['do'] || - errorFunction(route, "Invalid definition for do action in prefix controller '" + action.prefixController + "'"); + func = module['do'] + || ErrorFunction(route, + "Invalid definition for do action in prefix controller '" + + action.prefixController + "'"); + return func(req, res, options, next); } } catch (err) { - return errorFunction(route, "Cannot load/execute prefix controller '" + action.prefixController + "': " + String(err))(req, res, options, next); + return ErrorFunction(route, + "Cannot load/execute prefix controller '" + + action.prefixController + "': " + String(err))(req, res, options, next); } next(); @@ -375,14 +401,14 @@ function lookupCallbackAction (route, action) { /// @brief looks up a callback //////////////////////////////////////////////////////////////////////////////// -function lookupCallback (route) { +function LookupCallback (route) { var result = null; if (route.hasOwnProperty('content')) { - result = lookupCallbackStatic(route.content); + result = LookupCallbackStatic(route.content); } else if (route.hasOwnProperty('action')) { - result = lookupCallbackAction(route, route.action); + result = LookupCallbackAction(route, route.action); } return result; @@ -392,7 +418,7 @@ function lookupCallback (route) { /// @brief intersect methods //////////////////////////////////////////////////////////////////////////////// -function intersectMethods (a, b) { +function IntersectMethods (a, b) { var d = {}; var i; var j; @@ -420,7 +446,7 @@ function intersectMethods (a, b) { /// @brief defines a new route part //////////////////////////////////////////////////////////////////////////////// -function defineRoutePart (route, subwhere, parts, pos, constraint, callback) { +function DefineRoutePart (route, subwhere, parts, pos, constraint, callback) { var i; var p; var part; @@ -443,7 +469,7 @@ function defineRoutePart (route, subwhere, parts, pos, constraint, callback) { } if (pos + 1 < parts.length) { - defineRoutePart(route, subwhere.exact[part], parts, pos + 1, constraint, callback); + DefineRoutePart(route, subwhere.exact[part], parts, pos + 1, constraint, callback); } else { subwhere.exact[part].route = route; @@ -481,7 +507,7 @@ function defineRoutePart (route, subwhere, parts, pos, constraint, callback) { subsub.optional = part.optional || false; if (pos + 1 < parts.length) { - defineRoutePart(route, subsub.match, parts, pos + 1, constraint, callback); + DefineRoutePart(route, subsub.match, parts, pos + 1, constraint, callback); } else { subsub.match.route = route; @@ -509,18 +535,18 @@ function defineRoutePart (route, subwhere, parts, pos, constraint, callback) { /// @brief defines a new route //////////////////////////////////////////////////////////////////////////////// -function defineRoute (route, where, url, callback) { +function DefineRoute (route, where, url, callback) { var methods; var branch; var i; var j; - methods = intersectMethods(url.methods, callback.methods); + methods = IntersectMethods(url.methods, callback.methods); for (j = 0; j < methods.length; ++j) { var method = methods[j]; - defineRoutePart(route, where[method], url.urlParts, 0, url.constraint, callback); + DefineRoutePart(route, where[method], url.urlParts, 0, url.constraint, callback); } } @@ -528,7 +554,7 @@ function defineRoute (route, where, url, callback) { /// @brief extracts the routing for a path and a a method //////////////////////////////////////////////////////////////////////////////// -function flattenRouting (routes, path, urlParameters, depth, prefix) { +function FlattenRouting (routes, path, urlParameters, depth, prefix) { var cur; var i; var k; @@ -538,7 +564,7 @@ function flattenRouting (routes, path, urlParameters, depth, prefix) { for (k in routes.exact) { if (routes.exact.hasOwnProperty(k)) { cur = path + "/" + k.replace(/([\.\+\*\?\^\$\(\)\[\]])/g, "\\$1"); - result = result.concat(flattenRouting(routes.exact[k], + result = result.concat(FlattenRouting(routes.exact[k], cur, urlParameters.shallowCopy, depth + 1, @@ -576,7 +602,7 @@ function flattenRouting (routes, path, urlParameters, depth, prefix) { newUrlParameters[parameter.parameter] = depth; - result = result.concat(flattenRouting(parameter.match, + result = result.concat(FlattenRouting(parameter.match, cur, newUrlParameters, depth + 1, @@ -602,7 +628,7 @@ function flattenRouting (routes, path, urlParameters, depth, prefix) { } else { cur = path + "(/[^/]+)*"; - result = result.concat(flattenRouting(routes.prefix, + result = result.concat(FlattenRouting(routes.prefix, cur, urlParameters.shallowCopy, depth + 1, @@ -693,7 +719,7 @@ function flattenRouting (routes, path, urlParameters, depth, prefix) { /// - @c "string" //////////////////////////////////////////////////////////////////////////////// -function defineHttp (options) { +function DefineHttp (options) { var url = options.url; var contexts = options.context; var callback = options.callback; @@ -896,21 +922,21 @@ function reloadRouting () { var url; var callback; - url = lookupUrl(urlPrefix, route.url); + url = LookupUrl(urlPrefix, route.url); if (url === null) { console.error("route '%s' has an unkown url, ignoring", JSON.stringify(route)); return; } - callback = lookupCallback(route); + callback = LookupCallback(route); if (callback === null) { console.error("route '%s' has an unknown callback, ignoring", JSON.stringify(route)); return; } - defineRoute(route, storage, url, callback); + DefineRoute(route, storage, url, callback); }; // ............................................................................. @@ -958,8 +984,8 @@ function reloadRouting () { method = exports.ALL_METHODS[i]; - a = flattenRouting(RoutingCache.routes[method], "", {}, 0, false); - b = flattenRouting(RoutingCache.middleware[method], "", {}, 0, false).reverse(); + a = FlattenRouting(RoutingCache.routes[method], "", {}, 0, false); + b = FlattenRouting(RoutingCache.middleware[method], "", {}, 0, false).reverse(); RoutingCache.flat[method] = b.concat(a); } @@ -1472,10 +1498,10 @@ function redirectRequest (req, res, options, next) { //////////////////////////////////////////////////////////////////////////////// // public functions -exports.defineHttp = defineHttp; +exports.defineHttp = DefineHttp; exports.getErrorMessage = getErrorMessage; exports.getJsonBody = getJsonBody; -exports.errorFunction = errorFunction; +exports.errorFunction = ErrorFunction; exports.reloadRouting = reloadRouting; exports.firstRouting = firstRouting; exports.nextRouting = nextRouting; diff --git a/js/server/modules/org/arangodb/formatter.js b/js/server/modules/org/arangodb/formatter.js new file mode 100644 index 0000000000..e96ee1145b --- /dev/null +++ b/js/server/modules/org/arangodb/formatter.js @@ -0,0 +1,85 @@ +/*jslint indent: 2, + nomen: true, + maxlen: 100, + sloppy: true, + vars: true, + white: true, + plusplus: true */ +/*global require, exports */ + +//////////////////////////////////////////////////////////////////////////////// +/// @brief formatter functions +/// +/// @file +/// +/// DISCLAIMER +/// +/// Copyright 2011-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 Dr. Frank Celler +/// @author Copyright 2011-2012, triAGENS GmbH, Cologne, Germany +//////////////////////////////////////////////////////////////////////////////// + +// ----------------------------------------------------------------------------- +// --SECTION-- number parsers +// ----------------------------------------------------------------------------- + +//////////////////////////////////////////////////////////////////////////////// +/// @brief parses a number +//////////////////////////////////////////////////////////////////////////////// + +exports.number = function (value, info, lang) { + var error; + var format; + var result; + + if (info.hasOwnProperty('format')) { + format = info.format; + + if (format === "%d") { + result = value.toFixed(0); + } + else if (format === "%f") { + result = String(value); + } + else { + error = new ArangoError(); + error.errorNum = internal.errors.ERROR_NOT_IMPLEMENTED.code; + error.errorMessage = "format '" + format + "' not implemented"; + + throw error; + } + } + else { + result = value; + } + + return result; +} + +//////////////////////////////////////////////////////////////////////////////// +/// @} +//////////////////////////////////////////////////////////////////////////////// + +// ----------------------------------------------------------------------------- +// --SECTION-- END-OF-FILE +// ----------------------------------------------------------------------------- + +// Local Variables: +// mode: outline-minor +// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @\\}\\)" +// End: diff --git a/js/server/modules/org/arangodb/new 2.txt b/js/server/modules/org/arangodb/new 2.txt deleted file mode 100644 index 1f036d3af8..0000000000 --- a/js/server/modules/org/arangodb/new 2.txt +++ /dev/null @@ -1,51 +0,0 @@ -/I"..\..\lib" -/I"..\" -/I"..\..\" -/I"..\..\VisualStudio" -/I"..\..\3rdParty\VisualStudio\openssl\x86\include" -/I"..\..\3rdParty\VisualStudio\mygetopt" -/I"..\..\3rdParty\VisualStudio\regex-2.7\src" -/I"..\..\3rdParty\VisualStudio\readline-5.0-1-lib\include" -/I"..\..\arangod" -/I"..\..\3rdParty\VisualStudio\V8\include" -/Zi (debug information format) -/nologo (suppress startup banner) -/W3 (warnings) -/WX- (warnings) - -/O2 (optimise) -/Oi -/Oy- - - -/GL -/D "WIN32" -/D "NDEBUG" -/D "_CONSOLE" -/D "_WIN32" -/D "YY_NO_UNISTD_H" -/D "_UNICODE" -/D "UNICODE" -/D ")" - - -/Gm- -/EHsc - - -/MT -/GS !!!!!!!!!!!!!! -/Gy ????????????? - -/fp:precise -/Zc:wchar_t ??????????????????? -/Zc:forScope !!!!!!!!!!!!!!!!!! - -/Gd ??????????????????? -/analyze- -/errorReport:queue - -/Fp"Release\arangod.pch" -/Fa"Release\" -/Fo"Release\" -/Fd"Release\vc100.pdb" diff --git a/js/server/modules/org/arangodb/parser.js b/js/server/modules/org/arangodb/parser.js new file mode 100644 index 0000000000..e1009b0a42 --- /dev/null +++ b/js/server/modules/org/arangodb/parser.js @@ -0,0 +1,99 @@ +/*jslint indent: 2, + nomen: true, + maxlen: 100, + sloppy: true, + vars: true, + white: true, + plusplus: true */ +/*global require, exports */ + +//////////////////////////////////////////////////////////////////////////////// +/// @brief parser functions +/// +/// @file +/// +/// DISCLAIMER +/// +/// Copyright 2011-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 Dr. Frank Celler +/// @author Copyright 2011-2012, triAGENS GmbH, Cologne, Germany +//////////////////////////////////////////////////////////////////////////////// + +// ----------------------------------------------------------------------------- +// --SECTION-- number parsers +// ----------------------------------------------------------------------------- + +//////////////////////////////////////////////////////////////////////////////// +/// @brief parses a number +//////////////////////////////////////////////////////////////////////////////// + +exports.number = function (value, info, lang) { + var error; + var format; + var result; + + if (info.hasOwnProperty('format')) { + format = info.format; + + if (format === "%d") { + result = parseInt(value); + } + else if (format === "%f") { + result = parseFloat(value); + } + else if (format === "%x") { + result = parseInt(value, 16); + } + else if (format === "%o") { + result = parseInt(value, 8); + } + else { + error = new ArangoError(); + error.errorNum = internal.errors.ERROR_NOT_IMPLEMENTED.code; + error.errorMessage = "format '" + format + "' not implemented"; + + throw error; + } + } + else { + result = parseFloat(value); + } + + if (result === null || result === undefined || isNaN(result)) { + error = new ArangoError(); + error.errorNum = internal.errors.ERROR_ARANGO_PARSER_FAILED; + error.errorMessage = "format '" + format + "' not implemented"; + + throw error; + } + + return result; +} + +//////////////////////////////////////////////////////////////////////////////// +/// @} +//////////////////////////////////////////////////////////////////////////////// + +// ----------------------------------------------------------------------------- +// --SECTION-- END-OF-FILE +// ----------------------------------------------------------------------------- + +// Local Variables: +// mode: outline-minor +// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @\\}\\)" +// End: diff --git a/js/server/modules/org/arangodb/validator.js b/js/server/modules/org/arangodb/validator.js new file mode 100644 index 0000000000..034b5a4354 --- /dev/null +++ b/js/server/modules/org/arangodb/validator.js @@ -0,0 +1,136 @@ +/*jslint indent: 2, + nomen: true, + maxlen: 100, + sloppy: true, + vars: true, + white: true, + plusplus: true */ +/*global require, exports */ + +//////////////////////////////////////////////////////////////////////////////// +/// @brief validator functions +/// +/// @file +/// +/// DISCLAIMER +/// +/// Copyright 2011-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 Dr. Frank Celler +/// @author Copyright 2011-2012, triAGENS GmbH, Cologne, Germany +//////////////////////////////////////////////////////////////////////////////// + +// ----------------------------------------------------------------------------- +// --SECTION-- number validators +// ----------------------------------------------------------------------------- + +//////////////////////////////////////////////////////////////////////////////// +/// @brief positive number +//////////////////////////////////////////////////////////////////////////////// + +exports.positiveNumber = function (value, info, lang) { + if (value <= 0.0) { + error = new ArangoError(); + error.errorNum = internal.errors.ERROR_ARANGO_VALIDATION_FAILED.code; + error.errorMessage = "number must be positive"; + + throw error; + } +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief negative number +//////////////////////////////////////////////////////////////////////////////// + +exports.negativeNumber = function (value, info, lang) { + if (0.0 <= value) { + error = new ArangoError(); + error.errorNum = internal.errors.ERROR_ARANGO_VALIDATION_FAILED.code; + error.errorMessage = "number must be negative"; + + throw error; + } +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief zero +//////////////////////////////////////////////////////////////////////////////// + +exports.zeroNumber = function (value, info, lang) { + if (value === 0.0) { + error = new ArangoError(); + error.errorNum = internal.errors.ERROR_ARANGO_VALIDATION_FAILED.code; + error.errorMessage = "number must be zero"; + + throw error; + } +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief non-positive number +//////////////////////////////////////////////////////////////////////////////// + +exports.nonPositiveNumber = function (value, info, lang) { + if (0.0 < value) { + error = new ArangoError(); + error.errorNum = internal.errors.ERROR_ARANGO_VALIDATION_FAILED.code; + error.errorMessage = "number must be non-positive"; + + throw error; + } +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief non-negative number +//////////////////////////////////////////////////////////////////////////////// + +exports.nonNegativeNumber = function (value, info, lang) { + if (value < 0.0) { + error = new ArangoError(); + error.errorNum = internal.errors.ERROR_ARANGO_VALIDATION_FAILED.code; + error.errorMessage = "number must be non-negative"; + + throw error; + } +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief zero +//////////////////////////////////////////////////////////////////////////////// + +exports.nonZeroNumber = function (value, info, lang) { + if (value !== 0.0) { + error = new ArangoError(); + error.errorNum = internal.errors.ERROR_ARANGO_VALIDATION_FAILED.code; + error.errorMessage = "number must be non-zero"; + + throw error; + } +} + +//////////////////////////////////////////////////////////////////////////////// +/// @} +//////////////////////////////////////////////////////////////////////////////// + +// ----------------------------------------------------------------------------- +// --SECTION-- END-OF-FILE +// ----------------------------------------------------------------------------- + +// Local Variables: +// mode: outline-minor +// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @\\}\\)" +// End: diff --git a/js/server/server.js b/js/server/server.js index 19c0cc7105..8257a2c5ec 100644 --- a/js/server/server.js +++ b/js/server/server.js @@ -57,6 +57,8 @@ internal.db = db; internal.edges = db; internal.ArangoCollection = ArangoCollection; + internal.ArangoDatabase = ArangoDatabase; + internal.ArangoError = ArangoError; if (typeof SYS_DEFINE_ACTION === "undefined") { internal.defineAction = function() { diff --git a/js/server/version-check.js b/js/server/version-check.js index 2a95421709..89ea783fb5 100644 --- a/js/server/version-check.js +++ b/js/server/version-check.js @@ -225,9 +225,10 @@ return createSystemCollection("_routing"); }); - // create the _routing collection + // create the default route in the _routing collection addTask("insertDefaultRoute", "insert default route for the admin interface", function () { var routing = getCollection("_routing"); + if (! routing) { return false; } @@ -240,6 +241,24 @@ return true; }); + // set up the collection _structures + addTask("setupStructures", "setup _structures collection", function () { + return createSystemCollection("_structures", { waitForSync : true }); + }); + + // create a unique index on collection attribute in _structures + addTask("createStructuresIndex", "create index on collection attribute in _structures collection", function () { + var structures = getCollection("_structures"); + + if (! structures) { + return false; + } + + structures.ensureUniqueConstraint("collection"); + + return true; + }); + // loop through all tasks and execute them console.log("Found " + allTasks.length + " defined task(s), " + activeTasks.length + " task(s) to run"); diff --git a/lib/BasicsC/errors.dat b/lib/BasicsC/errors.dat index 5748605739..18c58662d6 100755 --- a/lib/BasicsC/errors.dat +++ b/lib/BasicsC/errors.dat @@ -90,6 +90,8 @@ ERROR_ARANGO_CAP_CONSTRAINT_ALREADY_DEFINED,1215,"cap constraint already defined ERROR_ARANGO_DOCUMENT_TOO_LARGE,1216,"document too large","Will be raised when the document cannot fit into any datafile because of it is too large." ERROR_ARANGO_COLLECTION_NOT_UNLOADED,1217,"collection must be unloaded","Will be raised when a collection should be unloaded, but has a different status." ERROR_ARANGO_COLLECTION_TYPE_INVALID,1218,"collection type invalid","Will be raised when an invalid collection type is used in a request." +ERROR_ARANGO_VALIDATION_FAILED,1219,"validator failed","Will be raised when the validation of an attribute of a structure failed." +ERROR_ARANGO_PARSER_FAILED,1219,"parser failed","Will be raised when the parsing of an attribute of a structure failed." ################################################################################ ## ArangoDB storage errors diff --git a/lib/BasicsC/voc-errors.c b/lib/BasicsC/voc-errors.c index 38aae56793..d91206302e 100644 --- a/lib/BasicsC/voc-errors.c +++ b/lib/BasicsC/voc-errors.c @@ -68,6 +68,8 @@ void TRI_InitialiseErrorMessages (void) { REG_ERROR(ERROR_ARANGO_DOCUMENT_TOO_LARGE, "document too large"); REG_ERROR(ERROR_ARANGO_COLLECTION_NOT_UNLOADED, "collection must be unloaded"); REG_ERROR(ERROR_ARANGO_COLLECTION_TYPE_INVALID, "collection type invalid"); + REG_ERROR(ERROR_ARANGO_VALIDATION_FAILED, "validator failed"); + REG_ERROR(ERROR_ARANGO_PARSER_FAILED, "parser failed"); REG_ERROR(ERROR_ARANGO_DATAFILE_FULL, "datafile full"); REG_ERROR(ERROR_QUERY_KILLED, "query killed"); REG_ERROR(ERROR_QUERY_PARSE, "%s"); diff --git a/lib/BasicsC/voc-errors.h b/lib/BasicsC/voc-errors.h index 75d22d5272..37ed0cd1a0 100644 --- a/lib/BasicsC/voc-errors.h +++ b/lib/BasicsC/voc-errors.h @@ -137,6 +137,10 @@ extern "C" { /// status. /// - 1218: @LIT{collection type invalid} /// Will be raised when an invalid collection type is used in a request. +/// - 1219: @LIT{validator failed} +/// Will be raised when the validation of an attribute of a structure failed. +/// - 1219: @LIT{parser failed} +/// Will be raised when the parsing of an attribute of a structure failed. /// - 1300: @LIT{datafile full} /// Will be raised when the datafile reaches its limit. /// - 1500: @LIT{query killed} @@ -902,6 +906,26 @@ void TRI_InitialiseErrorMessages (void); #define TRI_ERROR_ARANGO_COLLECTION_TYPE_INVALID (1218) +//////////////////////////////////////////////////////////////////////////////// +/// @brief 1219: ERROR_ARANGO_VALIDATION_FAILED +/// +/// validator failed +/// +/// Will be raised when the validation of an attribute of a structure failed. +//////////////////////////////////////////////////////////////////////////////// + +#define TRI_ERROR_ARANGO_VALIDATION_FAILED (1219) + +//////////////////////////////////////////////////////////////////////////////// +/// @brief 1219: ERROR_ARANGO_PARSER_FAILED +/// +/// parser failed +/// +/// Will be raised when the parsing of an attribute of a structure failed. +//////////////////////////////////////////////////////////////////////////////// + +#define TRI_ERROR_ARANGO_PARSER_FAILED (1219) + //////////////////////////////////////////////////////////////////////////////// /// @brief 1300: ERROR_ARANGO_DATAFILE_FULL /// diff --git a/lib/Utilities/ScriptLoader.cpp b/lib/Utilities/ScriptLoader.cpp index 19491371cc..c286a8c3f6 100644 --- a/lib/Utilities/ScriptLoader.cpp +++ b/lib/Utilities/ScriptLoader.cpp @@ -96,12 +96,16 @@ string ScriptLoader::buildScript (const char** script) { while (true) { string tempStr = string(*script); + if (tempStr == "//__end__") { break; } + scriptString += tempStr + "\n"; + ++script; } + return scriptString; } @@ -115,6 +119,10 @@ void ScriptLoader::defineScript (string const& name, string const& script) { _scripts[name] = script; } +//////////////////////////////////////////////////////////////////////////////// +/// @brief defines a new named script +//////////////////////////////////////////////////////////////////////////////// + void ScriptLoader::defineScript (const string& name, const char** script) { string scriptString = buildScript(script); @@ -128,9 +136,9 @@ void ScriptLoader::defineScript (const string& name, const char** script) { //////////////////////////////////////////////////////////////////////////////// string const& ScriptLoader::findScript (string const& name) { - MUTEX_LOCKER(_lock); static string empty = ""; + MUTEX_LOCKER(_lock); map::iterator i = _scripts.find(name); @@ -189,11 +197,11 @@ vector ScriptLoader::getDirectoryParts () { // implementations, otherwise we will only allow ";" // ......................................................................... - #ifdef _WIN32 +#ifdef _WIN32 TRI_vector_string_t parts = TRI_Split2String(_directory.c_str(), ";"); - #else +#else TRI_vector_string_t parts = TRI_Split2String(_directory.c_str(), ":;"); - #endif +#endif for (size_t i = 0; i < parts._length; i++) { string part = StringUtils::trim(parts._buffer[i]); diff --git a/lib/V8/JSLoader.cpp b/lib/V8/JSLoader.cpp index aee27d303e..464e765173 100644 --- a/lib/V8/JSLoader.cpp +++ b/lib/V8/JSLoader.cpp @@ -67,6 +67,38 @@ JSLoader::JSLoader () { /// @{ //////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +/// @brief executes a named script in the global context +//////////////////////////////////////////////////////////////////////////////// + +v8::Handle JSLoader::executeGlobalScript (v8::Persistent context, + string const& name) { + v8::HandleScope scope; + v8::TryCatch tryCatch; + + findScript(name); + + map::iterator i = _scripts.find(name); + + if (i == _scripts.end()) { + // correct the path/name + LOGGER_ERROR << "unknown script '" << StringUtils::correctPath(name) << "'"; + return scope.Close(v8::Undefined()); + } + + v8::Handle result = TRI_ExecuteJavaScriptString(context, + v8::String::New(i->second.c_str()), + v8::String::New(name.c_str()), + false); + + if (tryCatch.HasCaught()) { + TRI_LogV8Exception(&tryCatch); + return scope.Close(v8::Undefined()); + } + + return scope.Close(result); +} + //////////////////////////////////////////////////////////////////////////////// /// @brief loads a named script //////////////////////////////////////////////////////////////////////////////// diff --git a/lib/V8/JSLoader.h b/lib/V8/JSLoader.h index c2bfbccb6c..905c1be6a8 100644 --- a/lib/V8/JSLoader.h +++ b/lib/V8/JSLoader.h @@ -86,6 +86,13 @@ namespace triagens { public: +//////////////////////////////////////////////////////////////////////////////// +/// @brief executes a named script in the global context +//////////////////////////////////////////////////////////////////////////////// + + v8::Handle executeGlobalScript (v8::Persistent context, + string const& name); + //////////////////////////////////////////////////////////////////////////////// /// @brief loads a named script //////////////////////////////////////////////////////////////////////////////// From 114de1481632b2d11cc1d3321cfb5ddc17626a76 Mon Sep 17 00:00:00 2001 From: Frank Celler Date: Thu, 3 Jan 2013 17:16:08 +0100 Subject: [PATCH 2/4] fixed duplicate --- js/common/bootstrap/errors.js | 2 +- lib/BasicsC/errors.dat | 2 +- lib/BasicsC/voc-errors.h | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/js/common/bootstrap/errors.js b/js/common/bootstrap/errors.js index 95cc1e265d..63d9e2fffc 100644 --- a/js/common/bootstrap/errors.js +++ b/js/common/bootstrap/errors.js @@ -73,7 +73,7 @@ "ERROR_ARANGO_COLLECTION_NOT_UNLOADED" : { "code" : 1217, "message" : "collection must be unloaded" }, "ERROR_ARANGO_COLLECTION_TYPE_INVALID" : { "code" : 1218, "message" : "collection type invalid" }, "ERROR_ARANGO_VALIDATION_FAILED" : { "code" : 1219, "message" : "validator failed" }, - "ERROR_ARANGO_PARSER_FAILED" : { "code" : 1219, "message" : "parser failed" }, + "ERROR_ARANGO_PARSER_FAILED" : { "code" : 1220, "message" : "parser failed" }, "ERROR_ARANGO_DATAFILE_FULL" : { "code" : 1300, "message" : "datafile full" }, "ERROR_QUERY_KILLED" : { "code" : 1500, "message" : "query killed" }, "ERROR_QUERY_PARSE" : { "code" : 1501, "message" : "%s" }, diff --git a/lib/BasicsC/errors.dat b/lib/BasicsC/errors.dat index 18c58662d6..6c1d385180 100755 --- a/lib/BasicsC/errors.dat +++ b/lib/BasicsC/errors.dat @@ -91,7 +91,7 @@ ERROR_ARANGO_DOCUMENT_TOO_LARGE,1216,"document too large","Will be raised when t ERROR_ARANGO_COLLECTION_NOT_UNLOADED,1217,"collection must be unloaded","Will be raised when a collection should be unloaded, but has a different status." ERROR_ARANGO_COLLECTION_TYPE_INVALID,1218,"collection type invalid","Will be raised when an invalid collection type is used in a request." ERROR_ARANGO_VALIDATION_FAILED,1219,"validator failed","Will be raised when the validation of an attribute of a structure failed." -ERROR_ARANGO_PARSER_FAILED,1219,"parser failed","Will be raised when the parsing of an attribute of a structure failed." +ERROR_ARANGO_PARSER_FAILED,1220,"parser failed","Will be raised when the parsing of an attribute of a structure failed." ################################################################################ ## ArangoDB storage errors diff --git a/lib/BasicsC/voc-errors.h b/lib/BasicsC/voc-errors.h index 37ed0cd1a0..f760a7823a 100644 --- a/lib/BasicsC/voc-errors.h +++ b/lib/BasicsC/voc-errors.h @@ -139,7 +139,7 @@ extern "C" { /// Will be raised when an invalid collection type is used in a request. /// - 1219: @LIT{validator failed} /// Will be raised when the validation of an attribute of a structure failed. -/// - 1219: @LIT{parser failed} +/// - 1220: @LIT{parser failed} /// Will be raised when the parsing of an attribute of a structure failed. /// - 1300: @LIT{datafile full} /// Will be raised when the datafile reaches its limit. @@ -917,14 +917,14 @@ void TRI_InitialiseErrorMessages (void); #define TRI_ERROR_ARANGO_VALIDATION_FAILED (1219) //////////////////////////////////////////////////////////////////////////////// -/// @brief 1219: ERROR_ARANGO_PARSER_FAILED +/// @brief 1220: ERROR_ARANGO_PARSER_FAILED /// /// parser failed /// /// Will be raised when the parsing of an attribute of a structure failed. //////////////////////////////////////////////////////////////////////////////// -#define TRI_ERROR_ARANGO_PARSER_FAILED (1219) +#define TRI_ERROR_ARANGO_PARSER_FAILED (1220) //////////////////////////////////////////////////////////////////////////////// /// @brief 1300: ERROR_ARANGO_DATAFILE_FULL From d1a1ab462a82b0beeff4de8a5d0be117df4b01ef Mon Sep 17 00:00:00 2001 From: Frank Celler Date: Thu, 3 Jan 2013 17:45:54 +0100 Subject: [PATCH 3/4] fixed typo --- js/actions/system/api-structure.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/js/actions/system/api-structure.js b/js/actions/system/api-structure.js index 1ff00609a0..375ceb6a56 100644 --- a/js/actions/system/api-structure.js +++ b/js/actions/system/api-structure.js @@ -132,8 +132,6 @@ actions.defineHttp({ /// @} //////////////////////////////////////////////////////////////////////////////// -})(); - // ----------------------------------------------------------------------------- // --SECTION-- END-OF-FILE // ----------------------------------------------------------------------------- From 1c1106d8259697cd32ce6aa5f2c2eb1c059b30d5 Mon Sep 17 00:00:00 2001 From: Frank Celler Date: Thu, 3 Jan 2013 18:45:44 +0100 Subject: [PATCH 4/4] fixed names --- js/server/modules/org/arangodb/actions.js | 88 +++++++++++------------ 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/js/server/modules/org/arangodb/actions.js b/js/server/modules/org/arangodb/actions.js index 78e25a5e4d..7b8cf3e0ed 100644 --- a/js/server/modules/org/arangodb/actions.js +++ b/js/server/modules/org/arangodb/actions.js @@ -69,7 +69,7 @@ var RoutingCache; /// @brief function that's returned for non-implemented actions //////////////////////////////////////////////////////////////////////////////// -function NotImplementedFunction (route, message) { +function notImplementedFunction (route, message) { message += "\nThis error was triggered by the following route " + JSON.stringify(route); console.error(message); @@ -85,7 +85,7 @@ function NotImplementedFunction (route, message) { /// @brief function that's returned for actions that produce an error //////////////////////////////////////////////////////////////////////////////// -function ErrorFunction (route, message) { +function errorFunction (route, message) { message += "\nThis error was triggered by the following route " + JSON.stringify(route); console.error(message); @@ -101,7 +101,7 @@ function ErrorFunction (route, message) { /// @brief splits an URL into parts //////////////////////////////////////////////////////////////////////////////// -function SplitUrl (url) { +function splitUrl (url) { var cleaned; var i; var parts; @@ -151,14 +151,14 @@ function SplitUrl (url) { /// @brief looks up an URL //////////////////////////////////////////////////////////////////////////////// -function LookupUrl (prefix, url) { +function lookupUrl (prefix, url) { if (url === undefined || url === '') { return null; } if (typeof url === 'string') { return { - urlParts: SplitUrl(prefix + "/" + url), + urlParts: splitUrl(prefix + "/" + url), methods: [ exports.GET, exports.HEAD ], constraint: {} }; @@ -166,7 +166,7 @@ function LookupUrl (prefix, url) { if (url.hasOwnProperty('match')) { return { - urlParts: SplitUrl(prefix + "/" + url.match), + urlParts: splitUrl(prefix + "/" + url.match), methods: url.methods || exports.ALL_METHODS, constraint: url.constraint || {} }; @@ -179,7 +179,7 @@ function LookupUrl (prefix, url) { /// @brief looks up a callback for static data //////////////////////////////////////////////////////////////////////////////// -function LookupCallbackStatic (content) { +function lookupCallbackStatic (content) { var type; var body; var methods; @@ -213,7 +213,7 @@ function LookupCallbackStatic (content) { /// @brief looks up a callback for an action //////////////////////////////////////////////////////////////////////////////// -function LookupCallbackAction (route, action) { +function lookupCallbackAction (route, action) { var path; var name; var func; @@ -229,7 +229,7 @@ function LookupCallbackAction (route, action) { }; if (typeof action === 'string') { - return LookupCallbackAction(route, { prefixController: action }); + return lookupCallbackAction(route, { prefixController: action }); } if (action.hasOwnProperty('do')) { @@ -245,24 +245,24 @@ function LookupCallbackAction (route, action) { func = module[name]; } else { - func = NotImplementedFunction(route, "could not find action named '" + name + "' in module '" + joined + "'"); + func = notImplementedFunction(route, "could not find action named '" + name + "' in module '" + joined + "'"); } } catch (err) { if (! module.exists(joined)) { - func = NotImplementedFunction(route, + func = notImplementedFunction(route, "an error occurred while loading action named '" + name + "' in module '" + joined + "': " + String(err)); } else { - func = ErrorFunction(route, + func = errorFunction(route, "an error occurred while loading action named '" + name + "' in module '" + joined + "': " + String(err)); } } if (func === null || typeof func !== 'function') { - func = ErrorFunction(route, + func = errorFunction(route, "invalid definition for the action named '" + name + "' in module '" + joined + "'"); } @@ -288,7 +288,7 @@ function LookupCallbackAction (route, action) { if (req.requestType == httpMethods[m] && module.hasOwnProperty(m)) { func = module[m] - || ErrorFunction(route, + || errorFunction(route, "invalid definition for " + m + " action in action controller module '" + action.controller + "'"); @@ -298,7 +298,7 @@ function LookupCallbackAction (route, action) { if (module.hasOwnProperty('do')) { func = module['do'] - || ErrorFunction(route, + || errorFunction(route, "invalid definition for do action in action controller module '" + action.controller + "'"); @@ -313,12 +313,12 @@ function LookupCallbackAction (route, action) { } catch (err) { if (! module.exists(action.controller)) { - return NotImplementedFunction(route, + return notImplementedFunction(route, "cannot load/execute action controller module '" + action.controller + ": " + String(err)); } - return ErrorFunction(route, + return errorFunction(route, "cannot load/execute action controller module '" + action.controller + ": " + String(err)); } @@ -346,10 +346,10 @@ function LookupCallbackAction (route, action) { require(path); } catch (err) { - efunc = ErrorFunction; + efunc = errorFunction; if (! module.exists(path)) { - efunc = NotImplementedFunction; + efunc = notImplementedFunction; } return efunc(route, "cannot load prefix controller: " + String(err))(req, res, options, next); @@ -364,7 +364,7 @@ function LookupCallbackAction (route, action) { if (req.requestType == httpMethods[m] && module.hasOwnProperty(m)) { func = module[m] - || ErrorFunction(route, + || errorFunction(route, "Invalid definition for " + m + " action in prefix controller '" + action.prefixController + "'"); @@ -374,7 +374,7 @@ function LookupCallbackAction (route, action) { if (module.hasOwnProperty('do')) { func = module['do'] - || ErrorFunction(route, + || errorFunction(route, "Invalid definition for do action in prefix controller '" + action.prefixController + "'"); @@ -382,7 +382,7 @@ function LookupCallbackAction (route, action) { } } catch (err) { - return ErrorFunction(route, + return errorFunction(route, "Cannot load/execute prefix controller '" + action.prefixController + "': " + String(err))(req, res, options, next); } @@ -401,14 +401,14 @@ function LookupCallbackAction (route, action) { /// @brief looks up a callback //////////////////////////////////////////////////////////////////////////////// -function LookupCallback (route) { +function lookupCallback (route) { var result = null; if (route.hasOwnProperty('content')) { - result = LookupCallbackStatic(route.content); + result = lookupCallbackStatic(route.content); } else if (route.hasOwnProperty('action')) { - result = LookupCallbackAction(route, route.action); + result = lookupCallbackAction(route, route.action); } return result; @@ -418,7 +418,7 @@ function LookupCallback (route) { /// @brief intersect methods //////////////////////////////////////////////////////////////////////////////// -function IntersectMethods (a, b) { +function intersectMethods (a, b) { var d = {}; var i; var j; @@ -446,7 +446,7 @@ function IntersectMethods (a, b) { /// @brief defines a new route part //////////////////////////////////////////////////////////////////////////////// -function DefineRoutePart (route, subwhere, parts, pos, constraint, callback) { +function defineRoutePart (route, subwhere, parts, pos, constraint, callback) { var i; var p; var part; @@ -469,7 +469,7 @@ function DefineRoutePart (route, subwhere, parts, pos, constraint, callback) { } if (pos + 1 < parts.length) { - DefineRoutePart(route, subwhere.exact[part], parts, pos + 1, constraint, callback); + defineRoutePart(route, subwhere.exact[part], parts, pos + 1, constraint, callback); } else { subwhere.exact[part].route = route; @@ -507,7 +507,7 @@ function DefineRoutePart (route, subwhere, parts, pos, constraint, callback) { subsub.optional = part.optional || false; if (pos + 1 < parts.length) { - DefineRoutePart(route, subsub.match, parts, pos + 1, constraint, callback); + defineRoutePart(route, subsub.match, parts, pos + 1, constraint, callback); } else { subsub.match.route = route; @@ -535,18 +535,18 @@ function DefineRoutePart (route, subwhere, parts, pos, constraint, callback) { /// @brief defines a new route //////////////////////////////////////////////////////////////////////////////// -function DefineRoute (route, where, url, callback) { +function defineRoute (route, where, url, callback) { var methods; var branch; var i; var j; - methods = IntersectMethods(url.methods, callback.methods); + methods = intersectMethods(url.methods, callback.methods); for (j = 0; j < methods.length; ++j) { var method = methods[j]; - DefineRoutePart(route, where[method], url.urlParts, 0, url.constraint, callback); + defineRoutePart(route, where[method], url.urlParts, 0, url.constraint, callback); } } @@ -554,7 +554,7 @@ function DefineRoute (route, where, url, callback) { /// @brief extracts the routing for a path and a a method //////////////////////////////////////////////////////////////////////////////// -function FlattenRouting (routes, path, urlParameters, depth, prefix) { +function flattenRouting (routes, path, urlParameters, depth, prefix) { var cur; var i; var k; @@ -564,7 +564,7 @@ function FlattenRouting (routes, path, urlParameters, depth, prefix) { for (k in routes.exact) { if (routes.exact.hasOwnProperty(k)) { cur = path + "/" + k.replace(/([\.\+\*\?\^\$\(\)\[\]])/g, "\\$1"); - result = result.concat(FlattenRouting(routes.exact[k], + result = result.concat(flattenRouting(routes.exact[k], cur, urlParameters.shallowCopy, depth + 1, @@ -602,7 +602,7 @@ function FlattenRouting (routes, path, urlParameters, depth, prefix) { newUrlParameters[parameter.parameter] = depth; - result = result.concat(FlattenRouting(parameter.match, + result = result.concat(flattenRouting(parameter.match, cur, newUrlParameters, depth + 1, @@ -628,7 +628,7 @@ function FlattenRouting (routes, path, urlParameters, depth, prefix) { } else { cur = path + "(/[^/]+)*"; - result = result.concat(FlattenRouting(routes.prefix, + result = result.concat(flattenRouting(routes.prefix, cur, urlParameters.shallowCopy, depth + 1, @@ -719,7 +719,7 @@ function FlattenRouting (routes, path, urlParameters, depth, prefix) { /// - @c "string" //////////////////////////////////////////////////////////////////////////////// -function DefineHttp (options) { +function defineHttp (options) { var url = options.url; var contexts = options.context; var callback = options.callback; @@ -922,21 +922,21 @@ function reloadRouting () { var url; var callback; - url = LookupUrl(urlPrefix, route.url); + url = lookupUrl(urlPrefix, route.url); if (url === null) { console.error("route '%s' has an unkown url, ignoring", JSON.stringify(route)); return; } - callback = LookupCallback(route); + callback = lookupCallback(route); if (callback === null) { console.error("route '%s' has an unknown callback, ignoring", JSON.stringify(route)); return; } - DefineRoute(route, storage, url, callback); + defineRoute(route, storage, url, callback); }; // ............................................................................. @@ -984,8 +984,8 @@ function reloadRouting () { method = exports.ALL_METHODS[i]; - a = FlattenRouting(RoutingCache.routes[method], "", {}, 0, false); - b = FlattenRouting(RoutingCache.middleware[method], "", {}, 0, false).reverse(); + a = flattenRouting(RoutingCache.routes[method], "", {}, 0, false); + b = flattenRouting(RoutingCache.middleware[method], "", {}, 0, false).reverse(); RoutingCache.flat[method] = b.concat(a); } @@ -1498,10 +1498,10 @@ function redirectRequest (req, res, options, next) { //////////////////////////////////////////////////////////////////////////////// // public functions -exports.defineHttp = DefineHttp; +exports.defineHttp = defineHttp; exports.getErrorMessage = getErrorMessage; exports.getJsonBody = getJsonBody; -exports.errorFunction = ErrorFunction; +exports.errorFunction = errorFunction; exports.reloadRouting = reloadRouting; exports.firstRouting = firstRouting; exports.nextRouting = nextRouting;