mirror of https://gitee.com/bigwinds/arangodb
added first go at user actions
This commit is contained in:
parent
9212351c13
commit
4f6762436c
|
@ -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
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
/// <li>@ref ShellEdge</li>
|
||||
/// <li>@ref SimpleQueries</li>
|
||||
/// <li>@ref Aql</li>
|
||||
/// <li>@ref UserManualActions</li>
|
||||
///
|
||||
/// @latexonly\appendix@endlatexonly
|
||||
/// <li>@ref CommandLine</li>
|
||||
|
@ -56,6 +57,7 @@
|
|||
/// @copydetails ShellEdgeTOC
|
||||
/// @copydetails SimpleQueriesTOC
|
||||
/// @copydetails AqlTOC
|
||||
/// @copydetails UserManualActionsTOC
|
||||
/// @copydetails CommandLineTOC
|
||||
/// @endif
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -336,6 +338,103 @@
|
|||
/// JSON output format.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- USER MANUAL ACTIONS
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @page UserManualActionsTOC
|
||||
///
|
||||
/// <ul>
|
||||
/// <li>@ref UserManualActions
|
||||
/// </li>
|
||||
/// </ul>
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @page UserManualActions Arango Actions
|
||||
///
|
||||
/// Please note, that user Actions in ArangoDB are still preliminary and details
|
||||
/// are subject to change.
|
||||
///
|
||||
/// @EMBEDTOC{UserManualActionsTOC}
|
||||
///
|
||||
/// @section UserManualActionsIntro Introduction to User Actions
|
||||
////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// In same ways the ArangoDB server behaves like a Web server. It responses to
|
||||
/// HTTP request by delivering JSON objects in general. The idea is that
|
||||
/// sometimes it is better to store parts of the business logic within
|
||||
/// AnrangoDB. For instance, if you want to apply some statistics to large
|
||||
/// data-set and you cannot easily express this as query, then you can define a
|
||||
/// action instead of transferring the whole data-set to the client and do the
|
||||
/// computation there. Actions are also useful if you want to restrict and
|
||||
/// filter data according to some complex permission system.
|
||||
///
|
||||
/// The ArangoDB server deliver all kinds of information, JSON being only one
|
||||
/// possible format. You can also generate HTML or images. However, a Web server
|
||||
/// is normally better suited for the task as it also implements various caching
|
||||
/// strategies, language selection, compression and so on. Having said that,
|
||||
/// there are still situations where it might be suitable to use the ArangoDB to
|
||||
/// deliver HTML pages - static or dynamic. An simple example is the built-in
|
||||
/// administration interface. You can access it using any modern browser and
|
||||
/// there is no need for a separate Apache or IIS.
|
||||
///
|
||||
/// In the following sections we will introduce you to actions within ArangoDB
|
||||
/// and how to define them. The examples start with delivering static HTML pages
|
||||
/// - even if this is not the primary use-case for actions. The later sections
|
||||
/// will then show you, how to code some pieces of your business logic and
|
||||
/// return JSON objects.
|
||||
///
|
||||
/// The interface is loosely modelled after the JavaScript classes for HTTP
|
||||
/// request and responses found in node.js and the middleware/routing aspects
|
||||
/// of connect.js and express.js.
|
||||
///
|
||||
/// Note that unlike node.js, ArangoDB is multi-threaded and there is no easy
|
||||
/// way to share state between queries inside the JavaScript engine. If such
|
||||
/// state information is required, you need to use the database itself.
|
||||
///
|
||||
/// @section UserManualActionsHelloWorld A Hello World
|
||||
///
|
||||
/// 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
|
||||
/// 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.
|
||||
///
|
||||
/// In the following example, we want to define action in ArangoDB, so that the
|
||||
/// server returns the HTML document
|
||||
///
|
||||
/// @code
|
||||
/// <html>
|
||||
/// <body>
|
||||
/// Hallo World
|
||||
/// </body>
|
||||
/// </html>
|
||||
/// @endcode
|
||||
///
|
||||
/// if asked @LIT{GET /hello/world}.
|
||||
///
|
||||
/// The server needs to know what function to call or what document to deliver
|
||||
/// if it receives a request. This is called routing. All the routing information
|
||||
/// of ArangoDB is stored in a collection @LIT{_routing}. Each entry in this
|
||||
/// collections describes how to deal with a particular request path.
|
||||
///
|
||||
/// For the above example, add the following document to the @{_routing}
|
||||
/// collection:
|
||||
///
|
||||
/// @code
|
||||
/// arangosh> db._routing.save({
|
||||
/// ........> path : "/hello/world",
|
||||
/// ........> callback: {
|
||||
/// ........> type: "static",
|
||||
/// ........> contentType: "text/html",
|
||||
/// ........> body: "<html><body>Hello</body></html>" }});
|
||||
/// @endcode
|
||||
///
|
||||
///
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -72,13 +72,12 @@ function Routing (req, res) {
|
|||
|
||||
console.error("trying callback #%d / %d: %s # %s", current, callbacks.length, typeof callback, callback);
|
||||
|
||||
current++;
|
||||
|
||||
if (callback == null) {
|
||||
actions.resultNotImplemented(req, res, "not implemented '" + req.suffix.join("/") + "'");
|
||||
}
|
||||
else {
|
||||
callback(req, res, next, options);
|
||||
req.prefix = callback.path;
|
||||
callback.func(req, res, next, options);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ static string JS_common_bootstrap_print =
|
|||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"/// @brief prints objects to standard output\n"
|
||||
"///\n"
|
||||
"/// @FUN{print(@FA{arg1}, @FA{arg2}, @FA{arg3}, ...)}\n"
|
||||
"/// @FUN{internal.printShell(@FA{arg1}, @FA{arg2}, @FA{arg3}, ...)}\n"
|
||||
"///\n"
|
||||
"/// Only available in shell mode.\n"
|
||||
"///\n"
|
||||
|
|
|
@ -56,12 +56,49 @@ var RoutingCache = {};
|
|||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief looks up a callback for static data
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function LookupCallbackStatic (callback) {
|
||||
var type;
|
||||
var body;
|
||||
|
||||
type = callback.type || "text/plain";
|
||||
body = callback.body || "";
|
||||
|
||||
return function (req, res) {
|
||||
res.responseCode = exports.HTTP_OK;
|
||||
res.contentType = type;
|
||||
res.body = body;
|
||||
};
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief looks up a callback
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function LookupCallback (callback) {
|
||||
if (typeof callback === "string") {
|
||||
var type;
|
||||
|
||||
if (typeof callback === 'object') {
|
||||
if ('type' in callback) {
|
||||
type = callback.type;
|
||||
|
||||
if (type === "static") {
|
||||
return LookupCallbackStatic(callback);
|
||||
}
|
||||
else {
|
||||
console.error("unknown callback type '%s'", type);
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.error("missing callback type in '%s'", JSON.stringify(callback));
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
else if (typeof callback === "string") {
|
||||
var components;
|
||||
var module;
|
||||
var fn;
|
||||
|
@ -86,7 +123,6 @@ function LookupCallback (callback) {
|
|||
}
|
||||
|
||||
if (fn in module) {
|
||||
console.error("lookup %s: %s", typeof module[fn], module[fn]);
|
||||
return module[fn];
|
||||
}
|
||||
|
||||
|
@ -540,11 +576,21 @@ function Routing (method, path) {
|
|||
result = [];
|
||||
|
||||
for (i = 0; i < topdown.length; ++i) {
|
||||
result = result.concat(topdown[i].callback);
|
||||
var td = topdown[i];
|
||||
var callback = td.callback;
|
||||
|
||||
for (j = 0; j < callback.length; ++j) {
|
||||
result.push({ func : callback[j], path : td.path });
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < bottomup.length; ++i) {
|
||||
result = result.concat(bottomup[i].callback);
|
||||
var bu = bottomup[i];
|
||||
var callback = bu.callback;
|
||||
|
||||
for (j = 0; j < callback.length; ++j) {
|
||||
result.push({ func : callback[j], path : bu.path });
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
|
@ -1,7 +1,15 @@
|
|||
var console = require("console");
|
||||
var actions = require("org/arangodb/actions");
|
||||
|
||||
exports.logRequest = function (req, res, next, options) {
|
||||
console.log("received request: %s", JSON.stringify(req));
|
||||
console.log("error: ", next);
|
||||
next();
|
||||
console.log("produced response: %s", JSON.stringify(res));
|
||||
}
|
||||
};
|
||||
|
||||
exports.echoRequest = function (req, res) {
|
||||
res.responseCode = actions.HTTP_OK;
|
||||
res.contentType = "application/json";
|
||||
res.body = JSON.stringify(req);
|
||||
};
|
Loading…
Reference in New Issue