mirror of https://gitee.com/bigwinds/arangodb
added module in database
This commit is contained in:
parent
88b72adea4
commit
2ce0c4336a
|
@ -1550,7 +1550,7 @@ HIDE_UNDOC_RELATIONS = YES
|
|||
# toolkit from AT&T and Lucent Bell Labs. The other options in this section
|
||||
# have no effect if this option is set to NO (the default)
|
||||
|
||||
HAVE_DOT = YES
|
||||
HAVE_DOT = NO
|
||||
|
||||
# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is
|
||||
# allowed to run in parallel. When set to 0 (the default) doxygen will
|
||||
|
|
|
@ -1550,7 +1550,7 @@ HIDE_UNDOC_RELATIONS = YES
|
|||
# toolkit from AT&T and Lucent Bell Labs. The other options in this section
|
||||
# have no effect if this option is set to NO (the default)
|
||||
|
||||
HAVE_DOT = YES
|
||||
HAVE_DOT = NO
|
||||
|
||||
# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is
|
||||
# allowed to run in parallel. When set to 0 (the default) doxygen will
|
||||
|
|
|
@ -347,6 +347,12 @@
|
|||
///
|
||||
/// <ul>
|
||||
/// <li>@ref UserManualActions
|
||||
/// <ul>
|
||||
/// <li>@ref UserManualActionsIntro</li>
|
||||
/// <li>@ref UserManualActionsHelloWorld</li>
|
||||
/// <li>@ref UserManualActionsHelloJson</li>
|
||||
/// <li>@ref UserManualActionsEcho</li>
|
||||
/// </ul>
|
||||
/// </li>
|
||||
/// </ul>
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -418,7 +424,7 @@
|
|||
/// The client API or browser sends a HTTP request to the ArangoDB server and
|
||||
/// the server returns a HTTP response to the client. A HTTP requests consists
|
||||
/// of a method, normally @LIT{GET} or @LIT{POST} when using a browser, and a
|
||||
/// request path like "/hello/world". For a real Web server there are a zillion
|
||||
/// request path like @LIT{/hello/world}. For a real Web server there are a zillion
|
||||
/// of other thing to consider, we will ignore this for the moment. The HTTP
|
||||
/// response contains a content type, describing how to interpret the returned
|
||||
/// data, and the data itself.
|
||||
|
@ -462,7 +468,7 @@
|
|||
///
|
||||
/// Now use the browser and access
|
||||
///
|
||||
/// @LIT{http://localhost:8529/hello/world"}
|
||||
/// @LIT{http://localhost:8529/hello/world}
|
||||
///
|
||||
/// @section UserManualActionsHelloJson A Hello World Example for JSON
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
@ -562,6 +568,79 @@
|
|||
/// "options": { }
|
||||
/// }
|
||||
/// @endcode
|
||||
///
|
||||
/// Please note that
|
||||
///
|
||||
/// @code
|
||||
/// arangosh> db._routing.save({
|
||||
/// ........> path : "/hello/echo",
|
||||
/// ........> callback: "org/arangodb/actions/echoRequest" });
|
||||
/// @endcode
|
||||
///
|
||||
/// is a short-cut for
|
||||
///
|
||||
/// @code
|
||||
/// arangosh> db._routing.save({
|
||||
/// ........> path : "/hello/echo-long",
|
||||
/// ........> callback: {
|
||||
/// ........> type: "function",
|
||||
/// ........> module: "org/arangodb/actions",
|
||||
/// ........> function: "echoRequest" }});
|
||||
/// @endcode
|
||||
///
|
||||
/// The verbose form allows you to pass options to the called function:
|
||||
///
|
||||
/// @code
|
||||
/// arangosh> a = db._routing.firstExample({path : "/hello/echo-long"});
|
||||
/// arangosh> a.callback.options = { option: "my option1" };
|
||||
/// arangosh> db._replace(a, a);
|
||||
/// @endcode
|
||||
///
|
||||
/// You should now see the options in the result.
|
||||
///
|
||||
/// @code
|
||||
/// {
|
||||
/// "request": {
|
||||
/// "prefix": "/hello/echo-long",
|
||||
/// ...
|
||||
/// },
|
||||
/// "options": {
|
||||
/// "option": "my option1"
|
||||
/// }
|
||||
/// }
|
||||
/// @endcode
|
||||
///
|
||||
/// @section UserManualActionsDYO Define Your Own Callback
|
||||
//////////////////////////////////////////////////////////
|
||||
///
|
||||
/// You can define your own callbacks by adding a new module to ArangoDB. In
|
||||
/// order to avoid name clashes modules should be named
|
||||
///
|
||||
/// @LIT{tld/domain/modulename}
|
||||
///
|
||||
/// where @LIT{domain.tld} is your domain name. For development you can store
|
||||
/// your code in files in the filesystem, see @ref MODULES_PATH and @MODULES.
|
||||
///
|
||||
/// However, when you are finished with the development you can rollout the
|
||||
/// module code by storing it inside the @LIT{_modules} collection.
|
||||
///
|
||||
/// Create a file @LIT{hello-world.js} with the following content:
|
||||
///
|
||||
/// @code
|
||||
/// var actions = require("org/arangodb/actions");
|
||||
///
|
||||
/// exports.helloWorld = function (req, res) {
|
||||
/// res.contentType = "text/html";
|
||||
/// res.responseCode = actions.HTTP_OK;
|
||||
/// res.body = "<html><body>Hello World!</body></html>";
|
||||
/// };
|
||||
/// @endcode
|
||||
///
|
||||
/// Load this file as new module @LIT{de.triagens.hello-world} into the database
|
||||
///
|
||||
/// @code
|
||||
/// arangosh> require("internal").defineModule("de/triagens/hello-world", "hello-world.js");
|
||||
/// @endcode
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -52,15 +52,9 @@ function Routing (req, res) {
|
|||
console.log("request = %s", JSON.stringify(req));
|
||||
|
||||
callbacks = actions.routing(req.requestType, req.suffix);
|
||||
|
||||
for (i = 0; i < callbacks.length; ++i) {
|
||||
console.log("callback %d = %s", i, callbacks[i]);
|
||||
}
|
||||
|
||||
current = 0;
|
||||
|
||||
next = function () {
|
||||
var options = {};
|
||||
var callback;
|
||||
|
||||
if (callbacks.length <= current) {
|
||||
|
@ -70,14 +64,13 @@ function Routing (req, res) {
|
|||
|
||||
callback = callbacks[current++];
|
||||
|
||||
console.error("trying callback #%d / %d: %s # %s", current, callbacks.length, typeof callback, callback);
|
||||
|
||||
if (callback == null) {
|
||||
actions.resultNotImplemented(req, res, "not implemented '" + req.suffix.join("/") + "'");
|
||||
actions.resultNotImplemented(req, res,
|
||||
"not implemented '" + req.suffix.join("/") + "'");
|
||||
}
|
||||
else {
|
||||
req.prefix = callback.path;
|
||||
callback.func(req, res, next, options);
|
||||
callback.func(req, res, next, callback.options);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,8 @@ static string JS_common_bootstrap_modules =
|
|||
" SYS_LOAD, SYS_LOG, SYS_LOG_LEVEL, SYS_OUTPUT,\n"
|
||||
" SYS_PROCESS_STAT, SYS_READ, SYS_SPRINTF, SYS_TIME,\n"
|
||||
" SYS_START_PAGER, SYS_STOP_PAGER, ARANGO_QUIET, MODULES_PATH,\n"
|
||||
" COLOR_OUTPUT, COLOR_OUTPUT_RESET, COLOR_BRIGHT, PRETTY_PRINT */\n"
|
||||
" COLOR_OUTPUT, COLOR_OUTPUT_RESET, COLOR_BRIGHT, PRETTY_PRINT,\n"
|
||||
" SYS_SHA256, SYS_WAIT, SYS_GETLINE */\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"/// @brief JavaScript server functions\n"
|
||||
|
@ -180,6 +181,20 @@ static string JS_common_bootstrap_modules =
|
|||
"};\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"/// @brief unloads module\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
"Module.prototype.unloadAll = function () {\n"
|
||||
" var path;\n"
|
||||
"\n"
|
||||
" for (path in ModuleCache) {\n"
|
||||
" if (ModuleCache.hasOwnProperty(path)) {\n"
|
||||
" this.unload(path);\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"/// @brief top-level module\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
|
@ -226,7 +241,7 @@ static string JS_common_bootstrap_modules =
|
|||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"/// @brief fs module\n"
|
||||
"/// @brief file-system module\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
"ModuleCache[\"/fs\"] = new Module(\"/fs\");\n"
|
||||
|
@ -321,18 +336,19 @@ static string JS_common_bootstrap_modules =
|
|||
" }\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"/// @brief reads a file\n"
|
||||
"/// @brief reads a file from the module path or the database\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
" internal.readFile = function (path) {\n"
|
||||
" var i;\n"
|
||||
" var mc;\n"
|
||||
" var n;\n"
|
||||
"\n"
|
||||
" // try to load the file\n"
|
||||
" var paths = internal.MODULES_PATH;\n"
|
||||
"\n"
|
||||
" for (i = 0; i < paths.length; ++i) {\n"
|
||||
" var p = paths[i];\n"
|
||||
" var n;\n"
|
||||
"\n"
|
||||
" if (p === \"\") {\n"
|
||||
" n = \".\" + path + \".js\";\n"
|
||||
|
@ -342,7 +358,18 @@ static string JS_common_bootstrap_modules =
|
|||
" }\n"
|
||||
"\n"
|
||||
" if (fs.exists(n)) {\n"
|
||||
" return { path : n, content : SYS_READ(n) };\n"
|
||||
" return { path : n, content : internal.read(n) };\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" // try to load the module from the database\n"
|
||||
" mc = internal.db._collection(\"_modules\");\n"
|
||||
"\n"
|
||||
" if (mc !== null) {\n"
|
||||
" n = mc.firstExample({ path: path });\n"
|
||||
"\n"
|
||||
" if (n !== null) {\n"
|
||||
" return { path : \"_collection/\" + path, content : n.module };\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
|
@ -353,7 +380,7 @@ static string JS_common_bootstrap_modules =
|
|||
" };\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"/// @brief loads a file\n"
|
||||
"/// @brief loads a file from the file-system\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
" internal.loadFile = function (path) {\n"
|
||||
|
@ -385,6 +412,35 @@ static string JS_common_bootstrap_modules =
|
|||
" };\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"/// @brief defines a module\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
" internal.defineModule = function (path, file) {\n"
|
||||
" var content;\n"
|
||||
" var m;\n"
|
||||
" var mc;\n"
|
||||
"\n"
|
||||
" content = internal.read(file);\n"
|
||||
"\n"
|
||||
" mc = internal.db._collection(\"_modules\");\n"
|
||||
"\n"
|
||||
" if (mc === null) {\n"
|
||||
" throw \"you need to upgrade your database using 'arango-upgrade'\";\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" path = module.normalise(path);\n"
|
||||
" m = mc.firstExample({ path: path });\n"
|
||||
"\n"
|
||||
" if (m === null) {\n"
|
||||
" mc.save({ path: path, module: content });\n"
|
||||
" }\n"
|
||||
" else {\n"
|
||||
" m.content = content;\n"
|
||||
" mc.replace(m, m);\n"
|
||||
" }\n"
|
||||
" };\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"/// @}\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
|
@ -534,6 +590,10 @@ static string JS_common_bootstrap_modules =
|
|||
"\n"
|
||||
"}());\n"
|
||||
"\n"
|
||||
"// -----------------------------------------------------------------------------\n"
|
||||
"// --SECTION-- END-OF-FILE\n"
|
||||
"// -----------------------------------------------------------------------------\n"
|
||||
"\n"
|
||||
"// Local Variables:\n"
|
||||
"// mode: outline-minor\n"
|
||||
"// outline-regexp: \"^\\\\(/// @brief\\\\|/// @addtogroup\\\\|// --SECTION--\\\\|/// @page\\\\|/// @}\\\\)\"\n"
|
||||
|
|
|
@ -10,7 +10,8 @@
|
|||
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 */
|
||||
COLOR_OUTPUT, COLOR_OUTPUT_RESET, COLOR_BRIGHT, PRETTY_PRINT,
|
||||
SYS_SHA256, SYS_WAIT, SYS_GETLINE */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief JavaScript server functions
|
||||
|
@ -178,6 +179,20 @@ Module.prototype.unload = function (path) {
|
|||
delete ModuleCache[norm];
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief unloads module
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Module.prototype.unloadAll = function () {
|
||||
var path;
|
||||
|
||||
for (path in ModuleCache) {
|
||||
if (ModuleCache.hasOwnProperty(path)) {
|
||||
this.unload(path);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief top-level module
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -225,7 +240,7 @@ function require (path) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief fs module
|
||||
/// @brief file-system module
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ModuleCache["/fs"] = new Module("/fs");
|
||||
|
@ -320,18 +335,19 @@ ModuleCache["/internal"] = new Module("/internal");
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief reads a file
|
||||
/// @brief reads a file from the module path or the database
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.readFile = function (path) {
|
||||
var i;
|
||||
var mc;
|
||||
var n;
|
||||
|
||||
// try to load the file
|
||||
var paths = internal.MODULES_PATH;
|
||||
|
||||
for (i = 0; i < paths.length; ++i) {
|
||||
var p = paths[i];
|
||||
var n;
|
||||
|
||||
if (p === "") {
|
||||
n = "." + path + ".js";
|
||||
|
@ -341,7 +357,18 @@ ModuleCache["/internal"] = new Module("/internal");
|
|||
}
|
||||
|
||||
if (fs.exists(n)) {
|
||||
return { path : n, content : SYS_READ(n) };
|
||||
return { path : n, content : internal.read(n) };
|
||||
}
|
||||
}
|
||||
|
||||
// try to load the module from the database
|
||||
mc = internal.db._collection("_modules");
|
||||
|
||||
if (mc !== null) {
|
||||
n = mc.firstExample({ path: path });
|
||||
|
||||
if (n !== null) {
|
||||
return { path : "_collection/" + path, content : n.module };
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -352,7 +379,7 @@ ModuleCache["/internal"] = new Module("/internal");
|
|||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief loads a file
|
||||
/// @brief loads a file from the file-system
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.loadFile = function (path) {
|
||||
|
@ -383,6 +410,35 @@ ModuleCache["/internal"] = new Module("/internal");
|
|||
+ internal.MODULES_PATH + "'";
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief defines a module
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.defineModule = function (path, file) {
|
||||
var content;
|
||||
var m;
|
||||
var mc;
|
||||
|
||||
content = internal.read(file);
|
||||
|
||||
mc = internal.db._collection("_modules");
|
||||
|
||||
if (mc === null) {
|
||||
throw "you need to upgrade your database using 'arango-upgrade'";
|
||||
}
|
||||
|
||||
path = module.normalise(path);
|
||||
m = mc.firstExample({ path: path });
|
||||
|
||||
if (m === null) {
|
||||
mc.save({ path: path, module: content });
|
||||
}
|
||||
else {
|
||||
m.content = content;
|
||||
mc.replace(m, m);
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -533,6 +589,10 @@ ModuleCache["/console"] = new Module("/console");
|
|||
|
||||
}());
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @}\\)"
|
||||
|
|
|
@ -92,6 +92,33 @@ function LookupCallbackString (callback) {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief looks up a callback for a function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function LookupCallbackFunction (callback) {
|
||||
var module;
|
||||
var fn;
|
||||
|
||||
try {
|
||||
module = require(callback.module);
|
||||
}
|
||||
catch (err) {
|
||||
console.error("cannot load callback '%s' from module '%s': %s",
|
||||
fn, callback.module, "" + err);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
fn = callback.function;
|
||||
|
||||
if (fn in module) {
|
||||
return module[fn];
|
||||
}
|
||||
|
||||
console.error("callback '%s' is not defined in module '%s'", fn, module);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief looks up a callback for static data
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -124,6 +151,9 @@ function LookupCallback (callback) {
|
|||
if (type === "static") {
|
||||
return LookupCallbackStatic(callback);
|
||||
}
|
||||
else if (type === "function") {
|
||||
return LookupCallbackFunction(callback);
|
||||
}
|
||||
else {
|
||||
console.error("unknown callback type '%s'", type);
|
||||
return undefined;
|
||||
|
@ -431,13 +461,20 @@ function ReloadRouting () {
|
|||
var cb = LookupCallback(callback[i]);
|
||||
|
||||
if (cb === undefined) {
|
||||
console.error("route '%s' contains invalid callback '%s'", route._id, JSON.stringify(callback[i]));
|
||||
console.error("route '%s' contains invalid callback '%s'",
|
||||
route._id, JSON.stringify(callback[i]));
|
||||
}
|
||||
else if (typeof cb !== "function") {
|
||||
console.error("route '%s' contains non-function callback '%s'", route._id, JSON.stringify(callback[i]));
|
||||
console.error("route '%s' contains non-function callback '%s'",
|
||||
route._id, JSON.stringify(callback[i]));
|
||||
}
|
||||
else {
|
||||
tmp.push(cb);
|
||||
var result = {
|
||||
func: cb,
|
||||
options: callback[i].options || {}
|
||||
};
|
||||
|
||||
tmp.push(result);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -588,7 +625,11 @@ function Routing (method, path) {
|
|||
var callback = td.callback;
|
||||
|
||||
for (j = 0; j < callback.length; ++j) {
|
||||
result.push({ func : callback[j], path : td.path });
|
||||
result.push({
|
||||
func: callback[j].func,
|
||||
options: callback[j].options,
|
||||
path: td.path
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -597,7 +638,11 @@ function Routing (method, path) {
|
|||
var callback = bu.callback;
|
||||
|
||||
for (j = 0; j < callback.length; ++j) {
|
||||
result.push({ func : callback[j], path : bu.path });
|
||||
result.push({
|
||||
func: callback[j].func,
|
||||
options: callback[j].options,
|
||||
path: bu.path
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue