diff --git a/Documentation/Books/bot.py b/Documentation/Books/bot.py index d3a9992e4c..b0f8906db5 100644 --- a/Documentation/Books/bot.py +++ b/Documentation/Books/bot.py @@ -2,35 +2,7 @@ import sys import re import os -def replaceText(text,pathOfFile): - f=open(pathOfFile,"rU") - if f: - s=f.read() - f.close() - f=open(pathOfFile,'w') - - replaced=re.sub('@startDocuBlock\s+\w+',text,s) - - f.write(replaced) - f.close() - -def getTextFromSourceFile(searchText): - f=open("allComments.txt", 'rU') - s=f.read() - match = re.search(r'@startDocuBlock\s+'+re.escape(searchText)+'(.+?)@endDocuBlock', s,re.DOTALL) - if match: - global textExtracted - textExtracted = match.group(1) - return textExtracted -def findStartCode(textFile,full_path): - match = re.findall(r'@startDocuBlock\s*(\w+)', textFile) - if match: - for find in match: - textToReplace=getTextFromSourceFile(find) - replaceText(textToReplace,full_path) - return - -def walk_on_files(dirpatp): +def walk_on_files(dirpath): for root, dirs, files in os.walk(dirpath): for file in files: if file.endswith(".md"): @@ -42,11 +14,34 @@ def walk_on_files(dirpatp): findStartCode(textFile,full_path) return -def main(): - walk_on_files() - +def findStartCode(textFile,full_path): + match = re.findall(r'@startDocuBlock\s*(\w+)', textFile) + if match: + for find in match: + textToReplace=getTextFromSourceFile(find, full_path) + +def getTextFromSourceFile(searchText, full_path): + f=open("allComments.txt", 'rU') + s=f.read() + match = re.search(r'@startDocuBlock\s+'+re.escape(searchText)+'(.+?)@endDocuBlock', s,re.DOTALL) + if match: + textExtracted = match.group(1) + replaceText(textExtracted, full_path, searchText) + +def replaceText(text, pathOfFile, searchText): + f=open(pathOfFile,"rU") + if f: + s=f.read() + f.close() + f=open(pathOfFile,'w') + + replaced=re.sub('@startDocuBlock\s+'+ searchText + "(?:\s+|$)",text,s) + + f.write(replaced) + f.close() + if __name__ == '__main__': - path = ["Documentation/Books/Users/"] + path = ["Documentation/Books/Users"] for i in path: dirpath = os.path.abspath(os.path.join(os.path.dirname( __file__ ), os.pardir,"ArangoDB/../../"+i)) walk_on_files(dirpath) \ No newline at end of file diff --git a/build.h b/build.h index 5aee7f27bf..296acb248c 100644 --- a/build.h +++ b/build.h @@ -1 +1 @@ -#define TRI_VERSION "2.1.0-devel" +#define TRI_VERSION "2.2.0-devel" diff --git a/configure.ac b/configure.ac index e54912ba53..b210b51f5a 100644 --- a/configure.ac +++ b/configure.ac @@ -6,7 +6,7 @@ dnl ============================================================================ dnl --SECTION-- triAGENS GmbH Build Environment dnl ============================================================================ -AC_INIT([triAGENS ArangoDB], [2.1.0-devel], [info@triagens.de], [arangodb], [http://www.arangodb.org]) +AC_INIT([triAGENS ArangoDB], [2.2.0-devel], [info@triagens.de], [arangodb], [http://www.arangodb.org]) dnl ---------------------------------------------------------------------------- dnl auxillary directory for install-sh and missing diff --git a/js/apps/system/gharial/gharial.js b/js/apps/system/gharial/gharial.js index 934fce6bd5..952005c568 100644 --- a/js/apps/system/gharial/gharial.js +++ b/js/apps/system/gharial/gharial.js @@ -157,8 +157,8 @@ /** Drops an existing graph * * Drops an existing graph object by name. - * By default all collections not used by other graphs will be dropped as - * well. It can be optionally configured to not drop the collections. + * Optionally all collections not used by other graphs can be dropped as + * well. */ controller.del("/:graph", function(req, res) { var name = req.params("graph"); diff --git a/js/common/modules/org/arangodb/general-graph.js b/js/common/modules/org/arangodb/general-graph.js index b542305677..1ebb60bc9d 100644 --- a/js/common/modules/org/arangodb/general-graph.js +++ b/js/common/modules/org/arangodb/general-graph.js @@ -3078,7 +3078,7 @@ Graph.prototype._editEdgeDefinitions = function(edgeDefinition) { /// /// `general-graph._deleteEdgeDefinition(edgeCollectionName)` /// -/// * *edgeCollectionName* - string : name of edge collection defined in *collection* of the edge +/// * *edgeCollectionName*: string - name of edge collection defined in *collection* of the edge /// definition. /// /// @EXAMPLES diff --git a/js/server/bootstrap/module-internal.js b/js/server/bootstrap/module-internal.js index 48a8bb7c9a..444c1e57f1 100644 --- a/js/server/bootstrap/module-internal.js +++ b/js/server/bootstrap/module-internal.js @@ -86,11 +86,35 @@ // --SECTION-- private functions // ----------------------------------------------------------------------------- +//////////////////////////////////////////////////////////////////////////////// +/// @brief returns mount point for system apps +//////////////////////////////////////////////////////////////////////////////// + + function systemMountPoint (appName) { + 'use strict'; + + if (appName === "aardvark") { + return "/_admin/aardvark"; + } + + if (appName === "gharial") { + return "/_api/gharial"; + } + + if (appName === "cerberus") { + return "/system/cerberus"; + } + + return false; + } + //////////////////////////////////////////////////////////////////////////////// /// @brief resets engine in development mode //////////////////////////////////////////////////////////////////////////////// internal.resetEngine = function () { + 'use strict'; + internal.flushModuleCache(); require("org/arangodb/actions").reloadRouting(); }; @@ -120,6 +144,8 @@ // autoload specific actions internal.actionLoaded = function () { + 'use strict'; + console.debug("autoloading actions"); var modules = internal.db._collection("_modules"); @@ -163,6 +189,8 @@ //////////////////////////////////////////////////////////////////////////////// internal.initializeFoxx = function () { + 'use strict'; + var fm = require("org/arangodb/foxx/manager"); try { @@ -186,20 +214,18 @@ } apps.forEach(function (appName) { + var mount = systemMountPoint(appName); + // for all unknown system apps: check that the directory actually exists - if (appName !== "aardvark" && - ! fs.isDirectory(fs.join(systemAppPath, appName))) { + if (! mount && ! fs.isDirectory(fs.join(systemAppPath, appName))) { return; } try { - var mount; - if (appName === 'aardvark') { - mount = '/_admin/' + appName; - } - else { + if (! mount) { mount = '/system/' + appName; } + var found = aal.firstExample({ type: "mount", mount: mount }); if (found === null) { diff --git a/js/server/modules/org/arangodb/foxx/controller.js b/js/server/modules/org/arangodb/foxx/controller.js index 9cee1b57b0..27b9896148 100644 --- a/js/server/modules/org/arangodb/foxx/controller.js +++ b/js/server/modules/org/arangodb/foxx/controller.js @@ -87,6 +87,8 @@ Controller = function (context, options) { urlPrefix = context.prefix + "/" + urlPrefix; } + this.injected = Object.create(null); + this.injectors = Object.create(null); this.routingInfo.urlPrefix = urlPrefix; this.collectionPrefix = context.collectionPrefix; @@ -133,6 +135,14 @@ extend(Controller.prototype, { return this.applicationContext.collection(name); }, + addInjector: function(name, factory) { + if (factory === undefined) { + _.extend(this.injectors, name); + } else { + this.injectors[name] = factory; + } + }, + //////////////////////////////////////////////////////////////////////////////// /// @fn JSF_foxx_controller_handleRequest /// @brief Handle a request @@ -147,7 +157,7 @@ extend(Controller.prototype, { handleRequest: function (method, route, callback) { 'use strict'; - var newRoute = internal.constructRoute(method, route, callback), + var newRoute = internal.constructRoute(method, route, callback, this), requestContext = new RequestContext(this.allRoutes, this.models, newRoute, this.rootElement), summary; diff --git a/js/server/modules/org/arangodb/foxx/internals.js b/js/server/modules/org/arangodb/foxx/internals.js index 72b83d64ea..05a374ed2b 100644 --- a/js/server/modules/org/arangodb/foxx/internals.js +++ b/js/server/modules/org/arangodb/foxx/internals.js @@ -84,12 +84,23 @@ constructNickname = function (httpMethod, url) { .toLowerCase(); }; -constructRoute = function (method, route, callback) { +constructRoute = function (method, route, callback, controller) { 'use strict'; return { url: constructUrlObject(route, undefined, method), action: { - callback: callback + callback: function(req, res) { + Object.keys(controller.injectors).forEach(function(key) { + if (Object.prototype.hasOwnProperty.call(controller.injected, key)) return; + var injector = controller.injectors[key]; + if (typeof injector === 'function') { + controller.injected[key] = injector(); + } else { + controller.injected[key] = injector; + } + }); + callback(req, res, controller.injected); + } }, docs: { parameters: [], diff --git a/js/server/tests/shell-foxx.js b/js/server/tests/shell-foxx.js index 0eacee735a..e36f3a43fd 100644 --- a/js/server/tests/shell-foxx.js +++ b/js/server/tests/shell-foxx.js @@ -245,6 +245,135 @@ function SetRoutesFoxxControllerSpec () { }; } +function ControllerInjectionSpec () { + var app, routes, models; + + return { + testInjectFactoryFunction: function () { + var app = new FoxxController(fakeContext), + req = {}, + res = {}, + timesCalled = 0; + + app.addInjector({thing: function() {timesCalled++;}}); + + app.get('/foxx', function () {}); + + app.routingInfo.routes[0].action.callback(req, res); + app.routingInfo.routes[0].action.callback(req, res); + + assertEqual(timesCalled, 1); + }, + testInjectNameValue: function () { + var app = new FoxxController(fakeContext), + req = {}, + res = {}, + timesCalled = 0; + + app.addInjector('thing', function() {timesCalled++;}); + + app.get('/foxx', function () {}); + + app.routingInfo.routes[0].action.callback(req, res); + app.routingInfo.routes[0].action.callback(req, res); + + assertEqual(timesCalled, 1); + }, + testInjectOverwrite: function () { + var app = new FoxxController(fakeContext), + req = {}, + res = {}, + wrongFuncCalled = false, + timesCalled = 0; + + app.addInjector({thing: function() {wrongFuncCalled = true;}}); + app.addInjector({thing: function() {timesCalled++;}}); + + app.get('/foxx', function () {}); + + app.routingInfo.routes[0].action.callback(req, res); + app.routingInfo.routes[0].action.callback(req, res); + + assertFalse(wrongFuncCalled); + assertEqual(timesCalled, 1); + }, + testInjectInRoute: function () { + var app = new FoxxController(fakeContext), + req = {}, + res = {}, + calledA = false, + calledB = false, + calledC = false; + + app.addInjector({thing: function() {calledA = true;}}); + + app.get('/foxx', function () { + app.addInjector({ + thing: function() {calledB = true;}, + other: function() {calledC = true;} + }); + }); + + app.routingInfo.routes[0].action.callback(req, res); + app.routingInfo.routes[0].action.callback(req, res); + app.routingInfo.routes[0].action.callback(req, res); + + assertTrue(calledA); + assertFalse(calledB); + assertTrue(calledC); + }, + testInjectResultPassedThrough: function () { + var app = new FoxxController(fakeContext), + req = {}, + res = {}, + called = false; + + app.addInjector({thing: function() {return 'value';}}); + + app.get('/foxx', function (req, res, injected) { + assertEqual(injected.thing, 'value'); + called = true; + }); + + app.routingInfo.routes[0].action.callback(req, res); + + assertTrue(called); + }, + testInjectSimpleValues: function () { + var app = new FoxxController(fakeContext), + req = {}, + res = {}, + called = false; + + var injectors = { + obj: {a: 0, b: 1}, + arr: ['one', 'two'], + str: 'hello', + num: 42 + }; + + app.addInjector(injectors); + + app.get('/foxx', function (req, res, injected) { + assertEqual(typeof injected.obj, 'object'); + assertEqual(typeof injected.arr, 'object'); + assertEqual(typeof injected.str, 'string'); + assertEqual(typeof injected.num, 'number'); + assertTrue(Array.isArray(injected.arr)); + assertEqual(injected.obj, injectors.obj); + assertEqual(injected.arr, injectors.arr); + assertEqual(injected.str, injectors.str); + assertEqual(injected.num, injectors.num); + called = true; + }); + + app.routingInfo.routes[0].action.callback(req, res); + + assertTrue(called); + } + }; +} + function DocumentationAndConstraintsSpec () { var app, routes, models; @@ -872,6 +1001,7 @@ function FoxxControllerWithRootElement () { jsunity.run(CreateFoxxControllerSpec); jsunity.run(SetRoutesFoxxControllerSpec); +jsunity.run(ControllerInjectionSpec); jsunity.run(DocumentationAndConstraintsSpec); jsunity.run(AddMiddlewareFoxxControllerSpec); jsunity.run(CommentDrivenDocumentationSpec);