mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'devel' of https://github.com/arangodb/arangodb into devel
This commit is contained in:
commit
7426e9908d
|
@ -5,6 +5,9 @@ The ArangoDB server can listen for incoming requests on multiple *endpoints*.
|
||||||
The endpoints are normally specified either in ArangoDB's configuration file or on
|
The endpoints are normally specified either in ArangoDB's configuration file or on
|
||||||
the command-line, using the ["--server.endpoint"](../ConfigureArango/Arangod.md) option.
|
the command-line, using the ["--server.endpoint"](../ConfigureArango/Arangod.md) option.
|
||||||
The default endpoint for ArangoDB is *tcp://127.0.0.1:8529* or *tcp://localhost:8529*.
|
The default endpoint for ArangoDB is *tcp://127.0.0.1:8529* or *tcp://localhost:8529*.
|
||||||
|
ArangoDB can also do a so called *broadcast bind* using *tcp://0.0.0.0:8529*. This way
|
||||||
|
it will be reachable on all interfaces of the host. This may be useful
|
||||||
|
on development systems that frequently change their network setup like laptops.
|
||||||
|
|
||||||
The number of endpoints can also be changed at runtime using the API described
|
The number of endpoints can also be changed at runtime using the API described
|
||||||
below. Each endpoint can optionally be restricted to a specific list of databases
|
below. Each endpoint can optionally be restricted to a specific list of databases
|
||||||
|
@ -14,6 +17,23 @@ This may be useful in multi-tenant setups.
|
||||||
A multi-endpoint setup may also be useful to turn on encrypted communication for
|
A multi-endpoint setup may also be useful to turn on encrypted communication for
|
||||||
just specific databases.
|
just specific databases.
|
||||||
|
|
||||||
|
Endpoints equal TCP ports to be bound. On one specific ethernet interface each port
|
||||||
|
can only be bound **exactly once**. You can look up your available interfaces using
|
||||||
|
the *ifconfig* command on Linux / MacOSX - the Windows equivalent is *ipconfig*
|
||||||
|
([See Wikipedia for more details](http://en.wikipedia.org/wiki/Ifconfig)).
|
||||||
|
The general names of the interfaces differ on OS's and hardwares they run on.
|
||||||
|
However, typically every host has a so called
|
||||||
|
[loopback interface](http://en.wikipedia.org/wiki/Loop_device), which is a
|
||||||
|
virtual interface. By convention it always has the address *127.0.0.1* or *::1* (ipv6),
|
||||||
|
and can only be reached from exactly the very same host.
|
||||||
|
Ethernet interfaces usually have names like *eth0*, *wlan0*, *eth1:17*, *le0* or
|
||||||
|
a plain text name in Windows.
|
||||||
|
|
||||||
|
To find out which services already use ports (so ArangoDB can't bind them anymore),
|
||||||
|
you can use the [netstat command](http://en.wikipedia.org/wiki/Netstat)
|
||||||
|
(it behaves a little different on each platform, run it with *-lnpt* on Linux, *-p tcp*
|
||||||
|
on MacOSX or with *-an* on windows for valuable information).
|
||||||
|
|
||||||
The JavaScript interface for endpoints provides operations to add new endpoints at
|
The JavaScript interface for endpoints provides operations to add new endpoints at
|
||||||
runtime, and optionally restrict them for use with specific databases. The interface
|
runtime, and optionally restrict them for use with specific databases. The interface
|
||||||
also can be used to update existing endpoints or remove them at runtime.
|
also can be used to update existing endpoints or remove them at runtime.
|
||||||
|
|
|
@ -12,5 +12,8 @@
|
||||||
"top": 35,
|
"top": 35,
|
||||||
"bottom": 35
|
"bottom": 35
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"styles": {
|
||||||
|
"website": "styles/website.css"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
div.example_show_button {
border: medium solid lightgray;
text-align: center;
position: relative;
top: -10px;
}
.book .book-body .navigation.navigation-next {
right: 10px !important;
}
.book .book-summary ul.summary li.active>a,.book .book-summary ul.summary li a:hover {
color: #000 !important;
background: #80A54D !important;
text-decoration: none;
}
.book .book-body .page-wrapper .page-inner section.normal .deprecated{
background-color: rgba(240,240,0,0.4);
}
.gsib_a {
padding: 0px !important;
}
.gsc-control-cse {
border: 0px !important;
background-color: transparent !important;
}
.gsc-input {
margin: 0px !important;
}
|
|
@ -1993,16 +1993,10 @@ int TRI_StartServer (TRI_server_t* server,
|
||||||
if (server->_appPath != nullptr &&
|
if (server->_appPath != nullptr &&
|
||||||
strlen(server->_appPath) > 0 &&
|
strlen(server->_appPath) > 0 &&
|
||||||
! TRI_IsDirectory(server->_appPath)) {
|
! TRI_IsDirectory(server->_appPath)) {
|
||||||
if (! performUpgrade) {
|
|
||||||
LOG_ERROR("specified --javascript.app-path directory '%s' does not exist. "
|
|
||||||
"Please start again with --upgrade option to create it.",
|
|
||||||
server->_appPath);
|
|
||||||
return TRI_ERROR_BAD_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
long systemError;
|
long systemError;
|
||||||
std::string errorMessage;
|
std::string errorMessage;
|
||||||
res = TRI_CreateDirectory(server->_appPath, systemError, errorMessage);
|
int res = TRI_CreateRecursiveDirectory(server->_appPath, systemError, errorMessage);
|
||||||
|
|
||||||
if (res != TRI_ERROR_NO_ERROR) {
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
LOG_ERROR("unable to create --javascript.app-path directory '%s': %s",
|
LOG_ERROR("unable to create --javascript.app-path directory '%s': %s",
|
||||||
|
@ -2010,6 +2004,10 @@ int TRI_StartServer (TRI_server_t* server,
|
||||||
errorMessage.c_str());
|
errorMessage.c_str());
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
LOG_INFO("created --javascript.app-path directory '%s'.",
|
||||||
|
server->_appPath);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// create subdirectories if not yet present
|
// create subdirectories if not yet present
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include "LogfileManager.h"
|
#include "LogfileManager.h"
|
||||||
|
#include "Basics/files.h"
|
||||||
#include "Basics/hashes.h"
|
#include "Basics/hashes.h"
|
||||||
#include "Basics/json.h"
|
#include "Basics/json.h"
|
||||||
#include "Basics/logging.h"
|
#include "Basics/logging.h"
|
||||||
|
@ -266,7 +267,18 @@ bool LogfileManager::prepare () {
|
||||||
_directory = (*_databasePath);
|
_directory = (*_databasePath);
|
||||||
|
|
||||||
if (! basics::FileUtils::isDirectory(_directory)) {
|
if (! basics::FileUtils::isDirectory(_directory)) {
|
||||||
LOG_FATAL_AND_EXIT("database directory '%s' does not exist.", _directory.c_str());
|
std::string systemErrorStr;
|
||||||
|
long errorNo;
|
||||||
|
|
||||||
|
int res = TRI_CreateRecursiveDirectory(_directory.c_str(), errorNo, systemErrorStr);
|
||||||
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
|
LOG_FATAL_AND_EXIT("unable to create database directory: %s",
|
||||||
|
systemErrorStr.c_str());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LOG_INFO("created database directory '%s'.",
|
||||||
|
_directory.c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// append "/journals"
|
// append "/journals"
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,4 @@
|
||||||
/*jslint continue:true */
|
'use strict';
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief Foxx application store
|
/// @brief Foxx application store
|
||||||
|
@ -27,26 +27,23 @@
|
||||||
/// @author Copyright 2015, triAGENS GmbH, Cologne, Germany
|
/// @author Copyright 2015, triAGENS GmbH, Cologne, Germany
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
(function() {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- global variables
|
// --SECTION-- global variables
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
var checkedFishBowl = false;
|
var checkedFishBowl = false;
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- imports
|
// --SECTION-- imports
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
var arangodb = require("org/arangodb");
|
var arangodb = require("org/arangodb");
|
||||||
var db = arangodb.db;
|
var db = arangodb.db;
|
||||||
var download = require("internal").download;
|
var download = require("internal").download;
|
||||||
var fs = require("fs");
|
var fs = require("fs");
|
||||||
var throwDownloadError = arangodb.throwDownloadError;
|
var throwDownloadError = arangodb.throwDownloadError;
|
||||||
var utils = require("org/arangodb/foxx/manager-utils");
|
var utils = require("org/arangodb/foxx/manager-utils");
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- private functions
|
// --SECTION-- private functions
|
||||||
|
@ -56,9 +53,9 @@
|
||||||
/// @brief returns the fishbowl repository
|
/// @brief returns the fishbowl repository
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
function getFishbowlUrl () {
|
function getFishbowlUrl () {
|
||||||
return "arangodb/foxx-apps";
|
return "arangodb/foxx-apps";
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief returns the fishbowl collection
|
/// @brief returns the fishbowl collection
|
||||||
|
@ -68,190 +65,190 @@
|
||||||
/// used in context of the database.
|
/// used in context of the database.
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
var getFishbowlStorage = function() {
|
var getFishbowlStorage = function() {
|
||||||
|
|
||||||
var c = db._collection('_fishbowl');
|
var c = db._collection('_fishbowl');
|
||||||
if (c === null) {
|
if (c === null) {
|
||||||
c = db._create('_fishbowl', { isSystem : true });
|
c = db._create('_fishbowl', { isSystem : true });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c !== null && ! checkedFishBowl) {
|
if (c !== null && ! checkedFishBowl) {
|
||||||
// ensure indexes
|
// ensure indexes
|
||||||
c.ensureFulltextIndex("description");
|
c.ensureFulltextIndex("description");
|
||||||
c.ensureFulltextIndex("name");
|
c.ensureFulltextIndex("name");
|
||||||
checkedFishBowl = true;
|
checkedFishBowl = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief comparator for applications
|
/// @brief comparator for applications
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
var compareApps = function(l, r) {
|
var compareApps = function(l, r) {
|
||||||
var left = l.name.toLowerCase();
|
var left = l.name.toLowerCase();
|
||||||
var right = r.name.toLowerCase();
|
var right = r.name.toLowerCase();
|
||||||
|
|
||||||
if (left < right) {
|
if (left < right) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (right < left) {
|
if (right < left) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief comparator for versions
|
/// @brief comparator for versions
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
var compareVersions = function (a, b) {
|
var compareVersions = function (a, b) {
|
||||||
var i;
|
var i;
|
||||||
|
|
||||||
if (a === b) {
|
if (a === b) {
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// error handling
|
|
||||||
if (typeof a !== "string") {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (typeof b !== "string") {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
var aComponents = a.split(".");
|
|
||||||
var bComponents = b.split(".");
|
|
||||||
var len = Math.min(aComponents.length, bComponents.length);
|
|
||||||
|
|
||||||
// loop while the components are equal
|
|
||||||
for (i = 0; i < len; i++) {
|
|
||||||
|
|
||||||
// A bigger than B
|
|
||||||
if (parseInt(aComponents[i], 10) > parseInt(bComponents[i], 10)) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// B bigger than A
|
|
||||||
if (parseInt(aComponents[i], 10) < parseInt(bComponents[i], 10)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If one's a prefix of the other, the longer one is bigger one.
|
|
||||||
if (aComponents.length > bComponents.length) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aComponents.length < bComponents.length) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise they are the same.
|
|
||||||
return 0;
|
return 0;
|
||||||
};
|
}
|
||||||
|
|
||||||
|
// error handling
|
||||||
|
if (typeof a !== "string") {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (typeof b !== "string") {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
var aComponents = a.split(".");
|
||||||
|
var bComponents = b.split(".");
|
||||||
|
var len = Math.min(aComponents.length, bComponents.length);
|
||||||
|
|
||||||
|
// loop while the components are equal
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
|
||||||
|
// A bigger than B
|
||||||
|
if (parseInt(aComponents[i], 10) > parseInt(bComponents[i], 10)) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// B bigger than A
|
||||||
|
if (parseInt(aComponents[i], 10) < parseInt(bComponents[i], 10)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If one's a prefix of the other, the longer one is bigger one.
|
||||||
|
if (aComponents.length > bComponents.length) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aComponents.length < bComponents.length) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise they are the same.
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief updates the fishbowl from a zip archive
|
/// @brief updates the fishbowl from a zip archive
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
var updateFishbowlFromZip = function(filename) {
|
var updateFishbowlFromZip = function(filename) {
|
||||||
var i;
|
var i;
|
||||||
var tempPath = fs.getTempPath();
|
var tempPath = fs.getTempPath();
|
||||||
var toSave = [ ];
|
var toSave = [ ];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
fs.makeDirectoryRecursive(tempPath);
|
fs.makeDirectoryRecursive(tempPath);
|
||||||
var root = fs.join(tempPath, "foxx-apps-master/applications");
|
var root = fs.join(tempPath, "foxx-apps-master/applications");
|
||||||
|
|
||||||
// remove any previous files in the directory
|
|
||||||
fs.listTree(root).forEach(function (file) {
|
|
||||||
if (file.match(/\.json$/)) {
|
|
||||||
try {
|
|
||||||
fs.remove(fs.join(root, file));
|
|
||||||
}
|
|
||||||
catch (ignore) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
fs.unzipFile(filename, tempPath, false, true);
|
|
||||||
|
|
||||||
if (! fs.exists(root)) {
|
|
||||||
throw new Error("'applications' directory is missing in foxx-apps-master, giving up");
|
|
||||||
}
|
|
||||||
|
|
||||||
var m = fs.listTree(root);
|
|
||||||
var reSub = /(.*)\.json$/;
|
|
||||||
var f, match, app, desc;
|
|
||||||
|
|
||||||
for (i = 0; i < m.length; ++i) {
|
|
||||||
f = m[i];
|
|
||||||
match = reSub.exec(f);
|
|
||||||
if (match === null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
app = fs.join(root, f);
|
|
||||||
|
|
||||||
|
// remove any previous files in the directory
|
||||||
|
fs.listTree(root).forEach(function (file) {
|
||||||
|
if (file.match(/\.json$/)) {
|
||||||
try {
|
try {
|
||||||
desc = JSON.parse(fs.read(app));
|
fs.remove(fs.join(root, file));
|
||||||
}
|
|
||||||
catch (err1) {
|
|
||||||
arangodb.printf("Cannot parse description for app '" + f + "': %s\n", String(err1));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
desc._key = match[1];
|
|
||||||
|
|
||||||
if (! desc.hasOwnProperty("name")) {
|
|
||||||
desc.name = match[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
toSave.push(desc);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (toSave.length > 0) {
|
|
||||||
var fishbowl = getFishbowlStorage();
|
|
||||||
|
|
||||||
db._executeTransaction({
|
|
||||||
collections: {
|
|
||||||
write: fishbowl.name()
|
|
||||||
},
|
|
||||||
action: function (params) {
|
|
||||||
var c = require("internal").db._collection(params.collection);
|
|
||||||
c.truncate();
|
|
||||||
|
|
||||||
params.apps.forEach(function(app) {
|
|
||||||
c.save(app);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
params: {
|
|
||||||
apps: toSave,
|
|
||||||
collection: fishbowl.name()
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
arangodb.printf("Updated local repository information with %d application(s)\n",
|
|
||||||
toSave.length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
if (tempPath !== undefined && tempPath !== "") {
|
|
||||||
try {
|
|
||||||
fs.removeDirectoryRecursive(tempPath);
|
|
||||||
}
|
}
|
||||||
catch (ignore) {
|
catch (ignore) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
throw err;
|
fs.unzipFile(filename, tempPath, false, true);
|
||||||
|
|
||||||
|
if (! fs.exists(root)) {
|
||||||
|
throw new Error("'applications' directory is missing in foxx-apps-master, giving up");
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
var m = fs.listTree(root);
|
||||||
|
var reSub = /(.*)\.json$/;
|
||||||
|
var f, match, app, desc;
|
||||||
|
|
||||||
|
for (i = 0; i < m.length; ++i) {
|
||||||
|
f = m[i];
|
||||||
|
match = reSub.exec(f);
|
||||||
|
if (match === null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
app = fs.join(root, f);
|
||||||
|
|
||||||
|
try {
|
||||||
|
desc = JSON.parse(fs.read(app));
|
||||||
|
}
|
||||||
|
catch (err1) {
|
||||||
|
arangodb.printf("Cannot parse description for app '" + f + "': %s\n", String(err1));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
desc._key = match[1];
|
||||||
|
|
||||||
|
if (! desc.hasOwnProperty("name")) {
|
||||||
|
desc.name = match[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
toSave.push(desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (toSave.length > 0) {
|
||||||
|
var fishbowl = getFishbowlStorage();
|
||||||
|
|
||||||
|
db._executeTransaction({
|
||||||
|
collections: {
|
||||||
|
write: fishbowl.name()
|
||||||
|
},
|
||||||
|
action: function (params) {
|
||||||
|
var c = require("internal").db._collection(params.collection);
|
||||||
|
c.truncate();
|
||||||
|
|
||||||
|
params.apps.forEach(function(app) {
|
||||||
|
c.save(app);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
params: {
|
||||||
|
apps: toSave,
|
||||||
|
collection: fishbowl.name()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
arangodb.printf("Updated local repository information with %d application(s)\n",
|
||||||
|
toSave.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
if (tempPath !== undefined && tempPath !== "") {
|
||||||
|
try {
|
||||||
|
fs.removeDirectoryRecursive(tempPath);
|
||||||
|
}
|
||||||
|
catch (ignore) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- public functions
|
// --SECTION-- public functions
|
||||||
|
@ -261,87 +258,87 @@
|
||||||
/// @brief returns the search result for FOXX applications
|
/// @brief returns the search result for FOXX applications
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
var searchJson = function (name) {
|
var searchJson = function (name) {
|
||||||
|
|
||||||
var fishbowl = getFishbowlStorage();
|
var fishbowl = getFishbowlStorage();
|
||||||
|
|
||||||
if (fishbowl.count() === 0) {
|
if (fishbowl.count() === 0) {
|
||||||
arangodb.print("Repository is empty, please use 'update'");
|
arangodb.print("Repository is empty, please use 'update'");
|
||||||
|
|
||||||
return [];
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
var docs;
|
||||||
|
|
||||||
|
if (name === undefined || (typeof name === "string" && name.length === 0)) {
|
||||||
|
docs = fishbowl.toArray();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
name = name.replace(/[^a-zA-Z0-9]/g, ' ');
|
||||||
|
|
||||||
|
// get results by looking in "description" attribute
|
||||||
|
docs = fishbowl.fulltext("description", "prefix:" + name).toArray();
|
||||||
|
|
||||||
|
// build a hash of keys
|
||||||
|
var i;
|
||||||
|
var keys = { };
|
||||||
|
|
||||||
|
for (i = 0; i < docs.length; ++i) {
|
||||||
|
keys[docs[i]._key] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
var docs;
|
// get results by looking in "name" attribute
|
||||||
|
var docs2= fishbowl.fulltext("name", "prefix:" + name).toArray();
|
||||||
|
|
||||||
if (name === undefined || (typeof name === "string" && name.length === 0)) {
|
// merge the two result sets, avoiding duplicates
|
||||||
docs = fishbowl.toArray();
|
for (i = 0; i < docs2.length; ++i) {
|
||||||
}
|
if (!keys.hasOwnProperty(docs2[i]._key)) {
|
||||||
else {
|
docs.push(docs2[i]);
|
||||||
name = name.replace(/[^a-zA-Z0-9]/g, ' ');
|
|
||||||
|
|
||||||
// get results by looking in "description" attribute
|
|
||||||
docs = fishbowl.fulltext("description", "prefix:" + name).toArray();
|
|
||||||
|
|
||||||
// build a hash of keys
|
|
||||||
var i;
|
|
||||||
var keys = { };
|
|
||||||
|
|
||||||
for (i = 0; i < docs.length; ++i) {
|
|
||||||
keys[docs[i]._key] = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// get results by looking in "name" attribute
|
|
||||||
var docs2= fishbowl.fulltext("name", "prefix:" + name).toArray();
|
|
||||||
|
|
||||||
// merge the two result sets, avoiding duplicates
|
|
||||||
for (i = 0; i < docs2.length; ++i) {
|
|
||||||
if (!keys.hasOwnProperty(docs2[i]._key)) {
|
|
||||||
docs.push(docs2[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return docs;
|
return docs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief searchs for an available FOXX applications
|
/// @brief searchs for an available FOXX applications
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
var search = function (name) {
|
var search = function (name) {
|
||||||
var docs = searchJson(name);
|
var docs = searchJson(name);
|
||||||
|
|
||||||
arangodb.printTable(
|
arangodb.printTable(
|
||||||
docs.sort(compareApps),
|
docs.sort(compareApps),
|
||||||
[ "name", "author", "description" ],
|
[ "name", "author", "description" ],
|
||||||
{
|
{
|
||||||
prettyStrings: true,
|
prettyStrings: true,
|
||||||
totalString: "%s application(s) found",
|
totalString: "%s application(s) found",
|
||||||
emptyString: "no applications found",
|
emptyString: "no applications found",
|
||||||
rename: {
|
rename: {
|
||||||
name : "Name",
|
name : "Name",
|
||||||
author : "Author",
|
author : "Author",
|
||||||
description : "Description"
|
description : "Description"
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
}
|
||||||
};
|
);
|
||||||
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief extracts the highest version number from the document
|
/// @brief extracts the highest version number from the document
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
function extractMaxVersion (versionDoc) {
|
function extractMaxVersion (versionDoc) {
|
||||||
var maxVersion = "-";
|
var maxVersion = "-";
|
||||||
var versions = Object.keys(versionDoc);
|
var versions = Object.keys(versionDoc);
|
||||||
versions.sort(compareVersions);
|
versions.sort(compareVersions);
|
||||||
if (versions.length > 0) {
|
if (versions.length > 0) {
|
||||||
versions.reverse();
|
versions.reverse();
|
||||||
maxVersion = versions[0];
|
maxVersion = versions[0];
|
||||||
}
|
}
|
||||||
return maxVersion;
|
return maxVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -349,26 +346,26 @@ function extractMaxVersion (versionDoc) {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
function availableJson() {
|
function availableJson() {
|
||||||
var fishbowl = getFishbowlStorage();
|
var fishbowl = getFishbowlStorage();
|
||||||
var cursor = fishbowl.all();
|
var cursor = fishbowl.all();
|
||||||
var result = [];
|
var result = [];
|
||||||
var doc, maxVersion, res;
|
var doc, maxVersion, res;
|
||||||
|
|
||||||
while (cursor.hasNext()) {
|
while (cursor.hasNext()) {
|
||||||
doc = cursor.next();
|
doc = cursor.next();
|
||||||
maxVersion = extractMaxVersion(doc.versions);
|
maxVersion = extractMaxVersion(doc.versions);
|
||||||
|
|
||||||
res = {
|
res = {
|
||||||
name: doc.name,
|
name: doc.name,
|
||||||
description: doc.description || "",
|
description: doc.description || "",
|
||||||
author: doc.author || "",
|
author: doc.author || "",
|
||||||
latestVersion: maxVersion
|
latestVersion: maxVersion
|
||||||
};
|
};
|
||||||
|
|
||||||
result.push(res);
|
result.push(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -379,181 +376,179 @@ function availableJson() {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
var update = function() {
|
var update = function() {
|
||||||
var url = utils.buildGithubUrl(getFishbowlUrl());
|
var url = utils.buildGithubUrl(getFishbowlUrl());
|
||||||
var filename = fs.getTempFile("downloads", false);
|
var filename = fs.getTempFile("downloads", false);
|
||||||
var path = fs.getTempFile("zip", false);
|
var path = fs.getTempFile("zip", false);
|
||||||
|
|
||||||
|
try {
|
||||||
|
var result = download(url, "", {
|
||||||
|
method: "get",
|
||||||
|
followRedirects: true,
|
||||||
|
timeout: 30
|
||||||
|
}, filename);
|
||||||
|
|
||||||
|
if (result.code < 200 || result.code > 299) {
|
||||||
|
throwDownloadError("Github download from '" + url + "' failed with error code " + result.code);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateFishbowlFromZip(filename);
|
||||||
|
|
||||||
|
filename = undefined;
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
if (filename !== undefined && fs.exists(filename)) {
|
||||||
|
fs.remove(filename);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var result = download(url, "", {
|
fs.removeDirectoryRecursive(path);
|
||||||
method: "get",
|
|
||||||
followRedirects: true,
|
|
||||||
timeout: 30
|
|
||||||
}, filename);
|
|
||||||
|
|
||||||
if (result.code < 200 || result.code > 299) {
|
|
||||||
throwDownloadError("Github download from '" + url + "' failed with error code " + result.code);
|
|
||||||
}
|
|
||||||
|
|
||||||
updateFishbowlFromZip(filename);
|
|
||||||
|
|
||||||
filename = undefined;
|
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (ignore) {
|
||||||
if (filename !== undefined && fs.exists(filename)) {
|
|
||||||
fs.remove(filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
fs.removeDirectoryRecursive(path);
|
|
||||||
}
|
|
||||||
catch (ignore) {
|
|
||||||
}
|
|
||||||
|
|
||||||
throw err;
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief prints all available FOXX applications
|
/// @brief prints all available FOXX applications
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
var available = function () {
|
var available = function () {
|
||||||
var list = availableJson();
|
var list = availableJson();
|
||||||
|
|
||||||
arangodb.printTable(
|
arangodb.printTable(
|
||||||
list.sort(compareApps),
|
list.sort(compareApps),
|
||||||
[ "name", "author", "description", "latestVersion" ],
|
[ "name", "author", "description", "latestVersion" ],
|
||||||
{
|
{
|
||||||
prettyStrings: true,
|
prettyStrings: true,
|
||||||
totalString: "%s application(s) found",
|
totalString: "%s application(s) found",
|
||||||
emptyString: "no applications found, please use 'update'",
|
emptyString: "no applications found, please use 'update'",
|
||||||
rename: {
|
rename: {
|
||||||
"name" : "Name",
|
"name" : "Name",
|
||||||
"author" : "Author",
|
"author" : "Author",
|
||||||
"description" : "Description",
|
"description" : "Description",
|
||||||
"latestVersion" : "Latest Version"
|
"latestVersion" : "Latest Version"
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
}
|
||||||
};
|
);
|
||||||
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief gets json-info for an available FOXX application
|
/// @brief gets json-info for an available FOXX application
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
var infoJson = function (name) {
|
var infoJson = function (name) {
|
||||||
utils.validateAppName(name);
|
utils.validateAppName(name);
|
||||||
|
|
||||||
var fishbowl = getFishbowlStorage();
|
var fishbowl = getFishbowlStorage();
|
||||||
|
|
||||||
if (fishbowl.count() === 0) {
|
if (fishbowl.count() === 0) {
|
||||||
arangodb.print("Repository is empty, please use 'update'");
|
arangodb.print("Repository is empty, please use 'update'");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var desc;
|
var desc;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
desc = fishbowl.document(name);
|
desc = fishbowl.document(name);
|
||||||
return desc;
|
return desc;
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
arangodb.print("No application '" + name + "' available, please try 'search'");
|
arangodb.print("No application '" + name + "' available, please try 'search'");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief create a download URL for the given app information
|
/// @brief create a download URL for the given app information
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
var buildUrl = function(appInfo) {
|
var buildUrl = function(appInfo) {
|
||||||
// TODO Validate
|
// TODO Validate
|
||||||
var infoSplit = appInfo.split(":");
|
var infoSplit = appInfo.split(":");
|
||||||
var name = infoSplit[0];
|
var name = infoSplit[0];
|
||||||
var version = infoSplit[1];
|
var version = infoSplit[1];
|
||||||
var storeInfo = infoJson(name);
|
var storeInfo = infoJson(name);
|
||||||
if (storeInfo === undefined) {
|
if (storeInfo === undefined) {
|
||||||
throw "Application not found";
|
throw "Application not found";
|
||||||
|
}
|
||||||
|
var versions = storeInfo.versions;
|
||||||
|
var versionInfo;
|
||||||
|
if (version === undefined) {
|
||||||
|
versionInfo = versions[extractMaxVersion(versions)];
|
||||||
|
} else {
|
||||||
|
if (!versions.hasOwnProperty(version)) {
|
||||||
|
throw "Unknown version";
|
||||||
}
|
}
|
||||||
var versions = storeInfo.versions;
|
versionInfo = versions[version];
|
||||||
var versionInfo;
|
}
|
||||||
if (version === undefined) {
|
return utils.buildGithubUrl(versionInfo.location, versionInfo.tag);
|
||||||
versionInfo = versions[extractMaxVersion(versions)];
|
};
|
||||||
} else {
|
|
||||||
if (!versions.hasOwnProperty(version)) {
|
|
||||||
throw "Unknown version";
|
|
||||||
}
|
|
||||||
versionInfo = versions[version];
|
|
||||||
}
|
|
||||||
return utils.buildGithubUrl(versionInfo.location, versionInfo.tag);
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief prints info for an available FOXX application
|
/// @brief prints info for an available FOXX application
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
var info = function (name) {
|
var info = function (name) {
|
||||||
var desc = infoJson(name);
|
var desc = infoJson(name);
|
||||||
arangodb.printf("Name: %s\n", desc.name);
|
arangodb.printf("Name: %s\n", desc.name);
|
||||||
|
|
||||||
if (desc.hasOwnProperty('author')) {
|
if (desc.hasOwnProperty('author')) {
|
||||||
arangodb.printf("Author: %s\n", desc.author);
|
arangodb.printf("Author: %s\n", desc.author);
|
||||||
|
}
|
||||||
|
|
||||||
|
var isSystem = desc.hasOwnProperty('isSystem') && desc.isSystem;
|
||||||
|
arangodb.printf("System: %s\n", JSON.stringify(isSystem));
|
||||||
|
|
||||||
|
if (desc.hasOwnProperty('description')) {
|
||||||
|
arangodb.printf("Description: %s\n\n", desc.description);
|
||||||
|
}
|
||||||
|
|
||||||
|
var header = false;
|
||||||
|
var versions = Object.keys(desc.versions);
|
||||||
|
versions.sort(compareVersions);
|
||||||
|
|
||||||
|
versions.forEach(function (v) {
|
||||||
|
var version = desc.versions[v];
|
||||||
|
|
||||||
|
if (! header) {
|
||||||
|
arangodb.print("Versions:");
|
||||||
|
header = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var isSystem = desc.hasOwnProperty('isSystem') && desc.isSystem;
|
if (version.type === "github") {
|
||||||
arangodb.printf("System: %s\n", JSON.stringify(isSystem));
|
if (version.hasOwnProperty("tag")) {
|
||||||
|
arangodb.printf('%s: fetch github "%s" "%s"\n', v, version.location, version.tag);
|
||||||
if (desc.hasOwnProperty('description')) {
|
}
|
||||||
arangodb.printf("Description: %s\n\n", desc.description);
|
else if (v.hasOwnProperty("branch")) {
|
||||||
|
arangodb.printf('%s: fetch github "%s" "%s"\n', v, version.location, version.branch);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
arangodb.printf('%s: fetch "github" "%s"\n', v, version.location);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
var header = false;
|
arangodb.printf("\n");
|
||||||
var versions = Object.keys(desc.versions);
|
};
|
||||||
versions.sort(compareVersions);
|
|
||||||
|
|
||||||
versions.forEach(function (v) {
|
|
||||||
var version = desc.versions[v];
|
|
||||||
|
|
||||||
if (! header) {
|
|
||||||
arangodb.print("Versions:");
|
|
||||||
header = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (version.type === "github") {
|
|
||||||
if (version.hasOwnProperty("tag")) {
|
|
||||||
arangodb.printf('%s: fetch github "%s" "%s"\n', v, version.location, version.tag);
|
|
||||||
}
|
|
||||||
else if (v.hasOwnProperty("branch")) {
|
|
||||||
arangodb.printf('%s: fetch github "%s" "%s"\n', v, version.location, version.branch);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
arangodb.printf('%s: fetch "github" "%s"\n', v, version.location);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
arangodb.printf("\n");
|
|
||||||
};
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- export public API
|
// --SECTION-- export public API
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
exports.available = available;
|
exports.available = available;
|
||||||
exports.availableJson = availableJson;
|
exports.availableJson = availableJson;
|
||||||
exports.buildUrl = buildUrl;
|
exports.buildUrl = buildUrl;
|
||||||
exports.getFishbowlStorage = getFishbowlStorage;
|
exports.getFishbowlStorage = getFishbowlStorage;
|
||||||
exports.info = info;
|
exports.info = info;
|
||||||
exports.search = search;
|
exports.search = search;
|
||||||
exports.searchJson = searchJson;
|
exports.searchJson = searchJson;
|
||||||
exports.update = update;
|
exports.update = update;
|
||||||
|
|
||||||
// Temporary export to avoid breaking the client
|
// Temporary export to avoid breaking the client
|
||||||
exports.compareVersions = compareVersions;
|
exports.compareVersions = compareVersions;
|
||||||
|
|
||||||
}());
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- END-OF-FILE
|
// --SECTION-- END-OF-FILE
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*jshint strict: false */
|
'use strict';
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief Graph Data for Example
|
/// @brief Graph Data for Example
|
||||||
|
@ -26,92 +26,90 @@
|
||||||
/// @author Michael Hackstein
|
/// @author Michael Hackstein
|
||||||
/// @author Copyright 2011-2014, triAGENS GmbH, Cologne, Germany
|
/// @author Copyright 2011-2014, triAGENS GmbH, Cologne, Germany
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
(function() {
|
|
||||||
|
|
||||||
var Graph = require("org/arangodb/general-graph");
|
var Graph = require("org/arangodb/general-graph");
|
||||||
|
|
||||||
var createTraversalExample = function() {
|
var createTraversalExample = function() {
|
||||||
var g = Graph._create("knows_graph",
|
var g = Graph._create("knows_graph",
|
||||||
[Graph._relation("knows", "persons", "persons")]
|
[Graph._relation("knows", "persons", "persons")]
|
||||||
);
|
);
|
||||||
var a = g.persons.save({name: "Alice", _key: "alice"})._id;
|
var a = g.persons.save({name: "Alice", _key: "alice"})._id;
|
||||||
var b = g.persons.save({name: "Bob", _key: "bob"})._id;
|
var b = g.persons.save({name: "Bob", _key: "bob"})._id;
|
||||||
var c = g.persons.save({name: "Charlie", _key: "charlie"})._id;
|
var c = g.persons.save({name: "Charlie", _key: "charlie"})._id;
|
||||||
var d = g.persons.save({name: "Dave", _key: "dave"})._id;
|
var d = g.persons.save({name: "Dave", _key: "dave"})._id;
|
||||||
var e = g.persons.save({name: "Eve", _key: "eve"})._id;
|
var e = g.persons.save({name: "Eve", _key: "eve"})._id;
|
||||||
g.knows.save(a, b, {});
|
g.knows.save(a, b, {});
|
||||||
g.knows.save(b, c, {});
|
g.knows.save(b, c, {});
|
||||||
g.knows.save(b, d, {});
|
g.knows.save(b, d, {});
|
||||||
g.knows.save(e, a, {});
|
g.knows.save(e, a, {});
|
||||||
g.knows.save(e, b, {});
|
g.knows.save(e, b, {});
|
||||||
return g;
|
return g;
|
||||||
};
|
};
|
||||||
|
|
||||||
var createSocialGraph = function() {
|
var createSocialGraph = function() {
|
||||||
var edgeDefinition = [];
|
var edgeDefinition = [];
|
||||||
edgeDefinition.push(Graph._relation("relation", ["female", "male"], ["female", "male"]));
|
edgeDefinition.push(Graph._relation("relation", ["female", "male"], ["female", "male"]));
|
||||||
var g = Graph._create("social", edgeDefinition);
|
var g = Graph._create("social", edgeDefinition);
|
||||||
var a = g.female.save({name: "Alice", _key: "alice"});
|
var a = g.female.save({name: "Alice", _key: "alice"});
|
||||||
var b = g.male.save({name: "Bob", _key: "bob"});
|
var b = g.male.save({name: "Bob", _key: "bob"});
|
||||||
var c = g.male.save({name: "Charly", _key: "charly"});
|
var c = g.male.save({name: "Charly", _key: "charly"});
|
||||||
var d = g.female.save({name: "Diana", _key: "diana"});
|
var d = g.female.save({name: "Diana", _key: "diana"});
|
||||||
g.relation.save(a._id, b._id, {type: "married", _key: "aliceAndBob"});
|
g.relation.save(a._id, b._id, {type: "married", _key: "aliceAndBob"});
|
||||||
g.relation.save(a._id, c._id, {type: "friend", _key: "aliceAndCharly"});
|
g.relation.save(a._id, c._id, {type: "friend", _key: "aliceAndCharly"});
|
||||||
g.relation.save(c._id, d._id, {type: "married", _key: "charlyAndDiana"});
|
g.relation.save(c._id, d._id, {type: "married", _key: "charlyAndDiana"});
|
||||||
g.relation.save(b._id, d._id, {type: "friend", _key: "bobAndDiana"});
|
g.relation.save(b._id, d._id, {type: "friend", _key: "bobAndDiana"});
|
||||||
return g;
|
return g;
|
||||||
};
|
};
|
||||||
|
|
||||||
var createRoutePlannerGraph = function() {
|
var createRoutePlannerGraph = function() {
|
||||||
var edgeDefinition = [];
|
var edgeDefinition = [];
|
||||||
edgeDefinition.push(Graph._relation(
|
edgeDefinition.push(Graph._relation(
|
||||||
"germanHighway", ["germanCity"], ["germanCity"])
|
"germanHighway", ["germanCity"], ["germanCity"])
|
||||||
);
|
);
|
||||||
edgeDefinition.push(
|
edgeDefinition.push(
|
||||||
Graph._relation("frenchHighway", ["frenchCity"], ["frenchCity"])
|
Graph._relation("frenchHighway", ["frenchCity"], ["frenchCity"])
|
||||||
);
|
);
|
||||||
edgeDefinition.push(Graph._relation(
|
edgeDefinition.push(Graph._relation(
|
||||||
"internationalHighway", ["frenchCity", "germanCity"], ["frenchCity", "germanCity"])
|
"internationalHighway", ["frenchCity", "germanCity"], ["frenchCity", "germanCity"])
|
||||||
);
|
);
|
||||||
var g = Graph._create("routeplanner", edgeDefinition);
|
var g = Graph._create("routeplanner", edgeDefinition);
|
||||||
var berlin = g.germanCity.save({_key: "Berlin", population : 3000000, isCapital : true});
|
var berlin = g.germanCity.save({_key: "Berlin", population : 3000000, isCapital : true});
|
||||||
var cologne = g.germanCity.save({_key: "Cologne", population : 1000000, isCapital : false});
|
var cologne = g.germanCity.save({_key: "Cologne", population : 1000000, isCapital : false});
|
||||||
var hamburg = g.germanCity.save({_key: "Hamburg", population : 1000000, isCapital : false});
|
var hamburg = g.germanCity.save({_key: "Hamburg", population : 1000000, isCapital : false});
|
||||||
var lyon = g.frenchCity.save({_key: "Lyon", population : 80000, isCapital : false});
|
var lyon = g.frenchCity.save({_key: "Lyon", population : 80000, isCapital : false});
|
||||||
var paris = g.frenchCity.save({_key: "Paris", population : 4000000, isCapital : true});
|
var paris = g.frenchCity.save({_key: "Paris", population : 4000000, isCapital : true});
|
||||||
g.germanHighway.save(berlin._id, cologne._id, {distance: 850});
|
g.germanHighway.save(berlin._id, cologne._id, {distance: 850});
|
||||||
g.germanHighway.save(berlin._id, hamburg._id, {distance: 400});
|
g.germanHighway.save(berlin._id, hamburg._id, {distance: 400});
|
||||||
g.germanHighway.save(hamburg._id, cologne._id, {distance: 500});
|
g.germanHighway.save(hamburg._id, cologne._id, {distance: 500});
|
||||||
g.frenchHighway.save(paris._id, lyon._id, {distance: 550});
|
g.frenchHighway.save(paris._id, lyon._id, {distance: 550});
|
||||||
g.internationalHighway.save(berlin._id, lyon._id, {distance: 1100});
|
g.internationalHighway.save(berlin._id, lyon._id, {distance: 1100});
|
||||||
g.internationalHighway.save(berlin._id, paris._id, {distance: 1200});
|
g.internationalHighway.save(berlin._id, paris._id, {distance: 1200});
|
||||||
g.internationalHighway.save(hamburg._id, paris._id, {distance: 900});
|
g.internationalHighway.save(hamburg._id, paris._id, {distance: 900});
|
||||||
g.internationalHighway.save(hamburg._id, lyon._id, {distance: 1300});
|
g.internationalHighway.save(hamburg._id, lyon._id, {distance: 1300});
|
||||||
g.internationalHighway.save(cologne._id, lyon._id, {distance: 700});
|
g.internationalHighway.save(cologne._id, lyon._id, {distance: 700});
|
||||||
g.internationalHighway.save(cologne._id, paris._id, {distance: 550});
|
g.internationalHighway.save(cologne._id, paris._id, {distance: 550});
|
||||||
return g;
|
return g;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
var dropGraph = function(name) {
|
var dropGraph = function(name) {
|
||||||
if (Graph._exists(name)) {
|
if (Graph._exists(name)) {
|
||||||
return Graph._drop(name, true);
|
return Graph._drop(name, true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var loadGraph = function(name) {
|
var loadGraph = function(name) {
|
||||||
dropGraph(name);
|
dropGraph(name);
|
||||||
switch (name) {
|
switch (name) {
|
||||||
case "knows_graph":
|
case "knows_graph":
|
||||||
return createTraversalExample();
|
return createTraversalExample();
|
||||||
case "routeplanner":
|
case "routeplanner":
|
||||||
return createRoutePlannerGraph();
|
return createRoutePlannerGraph();
|
||||||
case "social":
|
case "social":
|
||||||
return createSocialGraph();
|
return createSocialGraph();
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.loadGraph = loadGraph;
|
exports.loadGraph = loadGraph;
|
||||||
exports.dropGraph = dropGraph;
|
exports.dropGraph = dropGraph;
|
||||||
}());
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*jshint strict: false */
|
'use strict';
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief Foxx application module
|
/// @brief Foxx application module
|
||||||
|
@ -28,40 +28,37 @@
|
||||||
/// @author Copyright 2013, triAGENS GmbH, Cologne, Germany
|
/// @author Copyright 2013, triAGENS GmbH, Cologne, Germany
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
(function() {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- imports
|
// --SECTION-- imports
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
var fs = require("fs");
|
var fs = require("fs");
|
||||||
var internal = require("internal");
|
var internal = require("internal");
|
||||||
var db = internal.db;
|
var db = internal.db;
|
||||||
var _= require("underscore");
|
var _= require("underscore");
|
||||||
var utils = require("org/arangodb/foxx/manager-utils");
|
var utils = require("org/arangodb/foxx/manager-utils");
|
||||||
var console = require("console");
|
var console = require("console");
|
||||||
var arangodb = require("org/arangodb");
|
var arangodb = require("org/arangodb");
|
||||||
var ArangoError = arangodb.ArangoError;
|
var ArangoError = arangodb.ArangoError;
|
||||||
var errors = arangodb.errors;
|
var errors = arangodb.errors;
|
||||||
var throwFileNotFound = arangodb.throwFileNotFound;
|
var throwFileNotFound = arangodb.throwFileNotFound;
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- private functions
|
// --SECTION-- private functions
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
function applyDefaultConfig(config) {
|
function applyDefaultConfig(config) {
|
||||||
var res = {};
|
var res = {};
|
||||||
if (config !== undefined) {
|
if (config !== undefined) {
|
||||||
Object.keys(config).forEach(function (attr) {
|
Object.keys(config).forEach(function (attr) {
|
||||||
if (config[attr].default !== undefined) {
|
if (config[attr].default !== undefined) {
|
||||||
res[attr] = config[attr].default;
|
res[attr] = config[attr].default;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- constructors and destructors
|
// --SECTION-- constructors and destructors
|
||||||
|
@ -71,56 +68,56 @@
|
||||||
// --SECTION-- AppContext
|
// --SECTION-- AppContext
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
function AppContext(app) {
|
function AppContext(app) {
|
||||||
var prefix = fs.safeJoin(app._root, app._path);
|
var prefix = fs.safeJoin(app._root, app._path);
|
||||||
|
|
||||||
this._prefix = prefix;
|
this._prefix = prefix;
|
||||||
this.comments = [];
|
this.comments = [];
|
||||||
this.name = app._name;
|
this.name = app._name;
|
||||||
this.version = app._version;
|
this.version = app._version;
|
||||||
this.mount = app._mount;
|
this.mount = app._mount;
|
||||||
this.collectionPrefix = app._collectionPrefix;
|
this.collectionPrefix = app._collectionPrefix;
|
||||||
this.options = app._options;
|
this.options = app._options;
|
||||||
this.configuration = app._options.configuration;
|
this.configuration = app._options.configuration;
|
||||||
this.dependencies = app._dependencies;
|
this.dependencies = app._dependencies;
|
||||||
this.basePath = prefix;
|
this.basePath = prefix;
|
||||||
this.baseUrl = '/_db/' + encodeURIComponent(db._name()) + app._mount;
|
this.baseUrl = '/_db/' + encodeURIComponent(db._name()) + app._mount;
|
||||||
this.isDevelopment = app._isDevelopment;
|
this.isDevelopment = app._isDevelopment;
|
||||||
this.isProduction = ! app._isDevelopment;
|
this.isProduction = ! app._isDevelopment;
|
||||||
this.manifest = app._manifest;
|
this.manifest = app._manifest;
|
||||||
|
}
|
||||||
|
|
||||||
|
AppContext.prototype.foxxFilename = function (path) {
|
||||||
|
return fs.safeJoin(this._prefix, path);
|
||||||
|
};
|
||||||
|
|
||||||
|
AppContext.prototype.collectionName = function (name) {
|
||||||
|
var replaced = this.collectionPrefix.replace(/[:\.]+/g, '_') +
|
||||||
|
name.replace(/[^a-zA-Z0-9]/g, '_').replace(/(^_+|_+$)/g, '').substr(0, 64);
|
||||||
|
|
||||||
|
if (replaced.length === 0) {
|
||||||
|
throw new Error("Cannot derive collection name from '" + name + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
AppContext.prototype.foxxFilename = function (path) {
|
return replaced;
|
||||||
return fs.safeJoin(this._prefix, path);
|
};
|
||||||
};
|
|
||||||
|
|
||||||
AppContext.prototype.collectionName = function (name) {
|
AppContext.prototype.collection = function (name) {
|
||||||
var replaced = this.collectionPrefix.replace(/[:\.]+/g, '_') +
|
return db._collection(this.collectionName(name));
|
||||||
name.replace(/[^a-zA-Z0-9]/g, '_').replace(/(^_+|_+$)/g, '').substr(0, 64);
|
};
|
||||||
|
|
||||||
if (replaced.length === 0) {
|
AppContext.prototype.path = function (name) {
|
||||||
throw new Error("Cannot derive collection name from '" + name + "'");
|
return fs.join(this._prefix, name);
|
||||||
}
|
};
|
||||||
|
|
||||||
return replaced;
|
|
||||||
};
|
|
||||||
|
|
||||||
AppContext.prototype.collection = function (name) {
|
|
||||||
return db._collection(this.collectionName(name));
|
|
||||||
};
|
|
||||||
|
|
||||||
AppContext.prototype.path = function (name) {
|
|
||||||
return fs.join(this._prefix, name);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
AppContext.prototype.comment = function (str) {
|
AppContext.prototype.comment = function (str) {
|
||||||
this.comments.push(str);
|
this.comments.push(str);
|
||||||
};
|
};
|
||||||
|
|
||||||
AppContext.prototype.clearComments = function () {
|
AppContext.prototype.clearComments = function () {
|
||||||
this.comments = [];
|
this.comments = [];
|
||||||
};
|
};
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- ArangoApp
|
// --SECTION-- ArangoApp
|
||||||
|
@ -131,7 +128,7 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
function isSystemMount(mount) {
|
function isSystemMount(mount) {
|
||||||
return (/^\/_/).test(mount);
|
return (/^\/_/).test(mount);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -139,72 +136,72 @@ function isSystemMount(mount) {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
function computeRootAppPath(mount, isValidation) {
|
function computeRootAppPath(mount, isValidation) {
|
||||||
if (isValidation) {
|
if (isValidation) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
if (isSystemMount(mount)) {
|
if (isSystemMount(mount)) {
|
||||||
return module.systemAppPath();
|
return module.systemAppPath();
|
||||||
}
|
}
|
||||||
return module.appPath();
|
return module.appPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief ArangoApp constructor
|
/// @brief ArangoApp constructor
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
function ArangoApp(config) {
|
function ArangoApp(config) {
|
||||||
if (config.error) {
|
if (config.error) {
|
||||||
this._error = config.error;
|
this._error = config.error;
|
||||||
this._isBroken = true;
|
this._isBroken = true;
|
||||||
}
|
}
|
||||||
this._manifest = config.manifest || {
|
this._manifest = config.manifest || {
|
||||||
name: "unknown",
|
name: "unknown",
|
||||||
version: "error"
|
version: "error"
|
||||||
};
|
};
|
||||||
if (!this._manifest.configuration) {
|
if (!this._manifest.configuration) {
|
||||||
this._manifest.configuration = {};
|
this._manifest.configuration = {};
|
||||||
}
|
}
|
||||||
if (!this._manifest.dependencies) {
|
if (!this._manifest.dependencies) {
|
||||||
this._manifest.dependencies = {};
|
this._manifest.dependencies = {};
|
||||||
}
|
}
|
||||||
this._name = this._manifest.name;
|
this._name = this._manifest.name;
|
||||||
this._version = this._manifest.version;
|
this._version = this._manifest.version;
|
||||||
this._root = computeRootAppPath(config.mount, config.id === "__internal");
|
this._root = computeRootAppPath(config.mount, config.id === "__internal");
|
||||||
this._path = config.path;
|
this._path = config.path;
|
||||||
this._options = config.options;
|
this._options = config.options;
|
||||||
this._mount = config.mount;
|
this._mount = config.mount;
|
||||||
this._isSystem = config.isSystem || false;
|
this._isSystem = config.isSystem || false;
|
||||||
this._isDevelopment = config.isDevelopment || false;
|
this._isDevelopment = config.isDevelopment || false;
|
||||||
this._exports = {};
|
this._exports = {};
|
||||||
this._collectionPrefix = this._mount.substr(1).replace(/-/g, "_").replace(/\//g, "_") + "_";
|
this._collectionPrefix = this._mount.substr(1).replace(/-/g, "_").replace(/\//g, "_") + "_";
|
||||||
|
|
||||||
// Apply the default configuration and ignore all missing options
|
// Apply the default configuration and ignore all missing options
|
||||||
var cfg = config.options.configuration;
|
var cfg = config.options.configuration;
|
||||||
this._options.configuration = applyDefaultConfig(this._manifest.configuration);
|
this._options.configuration = applyDefaultConfig(this._manifest.configuration);
|
||||||
this.configure(cfg);
|
this.configure(cfg);
|
||||||
|
|
||||||
var deps = config.options.dependencies;
|
var deps = config.options.dependencies;
|
||||||
this._options.dependencies = {};
|
this._options.dependencies = {};
|
||||||
this._dependencies = {};
|
this._dependencies = {};
|
||||||
this.updateDeps(deps);
|
this.updateDeps(deps);
|
||||||
|
|
||||||
this._context = new AppContext(this);
|
this._context = new AppContext(this);
|
||||||
this._context.appPackage = module.createAppPackage(this);
|
this._context.appPackage = module.createAppPackage(this);
|
||||||
this._context.appModule = this._context.appPackage.createAppModule(this);
|
this._context.appModule = this._context.appPackage.createAppModule(this);
|
||||||
|
|
||||||
if (! this._manifest.hasOwnProperty("defaultDocument")) {
|
if (! this._manifest.hasOwnProperty("defaultDocument")) {
|
||||||
this._manifest.defaultDocument = "index.html";
|
this._manifest.defaultDocument = "index.html";
|
||||||
}
|
}
|
||||||
if (this._manifest.hasOwnProperty("thumbnail")) {
|
if (this._manifest.hasOwnProperty("thumbnail")) {
|
||||||
var thumbfile = fs.join(this._root, this._path, this._manifest.thumbnail);
|
var thumbfile = fs.join(this._root, this._path, this._manifest.thumbnail);
|
||||||
try {
|
try {
|
||||||
this._thumbnail = fs.read64(thumbfile);
|
this._thumbnail = fs.read64(thumbfile);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.warnLines(
|
console.warnLines(
|
||||||
"Cannot read thumbnail '%s' : %s", thumbfile, err);
|
"Cannot read thumbnail '%s' : %s", thumbfile, err);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- private methods
|
// --SECTION-- private methods
|
||||||
|
@ -214,9 +211,9 @@ function computeRootAppPath(mount, isValidation) {
|
||||||
/// @brief prints a package
|
/// @brief prints a package
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ArangoApp.prototype._PRINT = function (context) {
|
ArangoApp.prototype._PRINT = function (context) {
|
||||||
context.output += '[app "' + this._name + '" (' + this._version + ')]';
|
context.output += '[app "' + this._name + '" (' + this._version + ')]';
|
||||||
};
|
};
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- public methods
|
// --SECTION-- public methods
|
||||||
|
@ -226,216 +223,215 @@ function computeRootAppPath(mount, isValidation) {
|
||||||
/// @brief creates a Json representation of itself to be persisted
|
/// @brief creates a Json representation of itself to be persisted
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ArangoApp.prototype.toJSON = function () {
|
ArangoApp.prototype.toJSON = function () {
|
||||||
var json = {
|
var json = {
|
||||||
manifest: this._manifest,
|
manifest: this._manifest,
|
||||||
name: this._name,
|
name: this._name,
|
||||||
version: this._version,
|
version: this._version,
|
||||||
path: this._path,
|
path: this._path,
|
||||||
options: this._options,
|
options: this._options,
|
||||||
mount: this._mount,
|
mount: this._mount,
|
||||||
root: this._root,
|
root: this._root,
|
||||||
isSystem: this._isSystem,
|
isSystem: this._isSystem,
|
||||||
isDevelopment: this._isDevelopment
|
isDevelopment: this._isDevelopment
|
||||||
};
|
|
||||||
if (this.hasOwnProperty("_error")) {
|
|
||||||
json.error = this._error;
|
|
||||||
}
|
|
||||||
if (this._manifest.hasOwnProperty("author")) {
|
|
||||||
json.author = this._manifest.author;
|
|
||||||
}
|
|
||||||
if (this._manifest.hasOwnProperty("description")) {
|
|
||||||
json.description = this._manifest.description;
|
|
||||||
}
|
|
||||||
if (this.hasOwnProperty("_thumbnail")) {
|
|
||||||
json.thumbnail = this._thumbnail;
|
|
||||||
}
|
|
||||||
|
|
||||||
return json;
|
|
||||||
};
|
};
|
||||||
|
if (this.hasOwnProperty("_error")) {
|
||||||
|
json.error = this._error;
|
||||||
|
}
|
||||||
|
if (this._manifest.hasOwnProperty("author")) {
|
||||||
|
json.author = this._manifest.author;
|
||||||
|
}
|
||||||
|
if (this._manifest.hasOwnProperty("description")) {
|
||||||
|
json.description = this._manifest.description;
|
||||||
|
}
|
||||||
|
if (this.hasOwnProperty("_thumbnail")) {
|
||||||
|
json.thumbnail = this._thumbnail;
|
||||||
|
}
|
||||||
|
|
||||||
|
return json;
|
||||||
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief creates a reduced Json representation of itself for output
|
/// @brief creates a reduced Json representation of itself for output
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ArangoApp.prototype.simpleJSON = function () {
|
ArangoApp.prototype.simpleJSON = function () {
|
||||||
var json = {
|
var json = {
|
||||||
name: this._name,
|
name: this._name,
|
||||||
version: this._version,
|
version: this._version,
|
||||||
mount: this._mount
|
mount: this._mount
|
||||||
};
|
|
||||||
return json;
|
|
||||||
};
|
};
|
||||||
|
return json;
|
||||||
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief toggles development mode
|
/// @brief toggles development mode
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ArangoApp.prototype.development = function(activate) {
|
ArangoApp.prototype.development = function(activate) {
|
||||||
this._isDevelopment = activate;
|
this._isDevelopment = activate;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief set app dependencies
|
/// @brief set app dependencies
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ArangoApp.prototype.updateDeps = function (deps) {
|
ArangoApp.prototype.updateDeps = function (deps) {
|
||||||
var expected = this._manifest.dependencies;
|
var expected = this._manifest.dependencies;
|
||||||
var invalid = [];
|
var invalid = [];
|
||||||
|
|
||||||
_.each(deps, function (mount, name) {
|
_.each(deps, function (mount, name) {
|
||||||
if (!expected[name]) {
|
if (!expected[name]) {
|
||||||
invalid.push("Unexpected dependency " + name);
|
invalid.push("Unexpected dependency " + name);
|
||||||
|
}
|
||||||
|
this._options.dependencies[name] = mount;
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
_.each(this._options.dependencies, function (mount, name) {
|
||||||
|
Object.defineProperty(this._dependencies, name, {
|
||||||
|
configurable: true,
|
||||||
|
enumerable: true,
|
||||||
|
get: function () {
|
||||||
|
return require("org/arangodb/foxx").requireApp(mount);
|
||||||
}
|
}
|
||||||
this._options.dependencies[name] = mount;
|
});
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
_.each(this._options.dependencies, function (mount, name) {
|
return invalid;
|
||||||
Object.defineProperty(this._dependencies, name, {
|
};
|
||||||
configurable: true,
|
|
||||||
enumerable: true,
|
|
||||||
get: function () {
|
|
||||||
return require("org/arangodb/foxx").requireApp(mount);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
return invalid;
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief set app configuration
|
/// @brief set app configuration
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ArangoApp.prototype.configure = function(config) {
|
ArangoApp.prototype.configure = function(config) {
|
||||||
var expected = this._manifest.configuration;
|
var expected = this._manifest.configuration;
|
||||||
var invalid = [];
|
var invalid = [];
|
||||||
this._options.configuration = this._options.configuration || {};
|
this._options.configuration = this._options.configuration || {};
|
||||||
|
|
||||||
_.each(config, function (value, name) {
|
_.each(config, function (value, name) {
|
||||||
if (!expected[name]) {
|
if (!expected[name]) {
|
||||||
invalid.push("Unexpected Option " + name);
|
invalid.push("Unexpected Option " + name);
|
||||||
|
} else {
|
||||||
|
var type = expected[name].type;
|
||||||
|
var result = utils.parameterTypes[type].validate(value);
|
||||||
|
if (result.error) {
|
||||||
|
invalid.push(result.error.message.replace(/^"value"/, '"' + name + '"'));
|
||||||
} else {
|
} else {
|
||||||
var type = expected[name].type;
|
this._options.configuration[name] = result.value;
|
||||||
var result = utils.parameterTypes[type].validate(value);
|
|
||||||
if (result.error) {
|
|
||||||
invalid.push(result.error.message.replace(/^"value"/, '"' + name + '"'));
|
|
||||||
} else {
|
|
||||||
this._options.configuration[name] = result.value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}, this);
|
}
|
||||||
|
}, this);
|
||||||
|
|
||||||
return invalid;
|
return invalid;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief get app configuration
|
/// @brief get app configuration
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ArangoApp.prototype.getConfiguration = function (simple) {
|
ArangoApp.prototype.getConfiguration = function (simple) {
|
||||||
var config = {};
|
var config = {};
|
||||||
var definitions = this._manifest.configuration;
|
var definitions = this._manifest.configuration;
|
||||||
var options = this._options.configuration;
|
var options = this._options.configuration;
|
||||||
_.each(definitions, function (dfn, name) {
|
_.each(definitions, function (dfn, name) {
|
||||||
var value = options[name] === undefined ? dfn.default : options[name];
|
var value = options[name] === undefined ? dfn.default : options[name];
|
||||||
config[name] = simple ? value : _.extend(_.clone(dfn), {
|
config[name] = simple ? value : _.extend(_.clone(dfn), {
|
||||||
title: utils.getReadableName(name),
|
title: utils.getReadableName(name),
|
||||||
current: value
|
current: value
|
||||||
});
|
|
||||||
});
|
});
|
||||||
return config;
|
});
|
||||||
};
|
return config;
|
||||||
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief get app dependencies
|
/// @brief get app dependencies
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ArangoApp.prototype.getDependencies = function(simple) {
|
ArangoApp.prototype.getDependencies = function(simple) {
|
||||||
var deps = {};
|
var deps = {};
|
||||||
var definitions = this._manifest.dependencies;
|
var definitions = this._manifest.dependencies;
|
||||||
var options = this._options.dependencies;
|
var options = this._options.dependencies;
|
||||||
_.each(definitions, function (dfn, name) {
|
_.each(definitions, function (dfn, name) {
|
||||||
deps[name] = simple ? options[name] : {
|
deps[name] = simple ? options[name] : {
|
||||||
definition: dfn,
|
definition: dfn,
|
||||||
title: utils.getReadableName(name),
|
title: utils.getReadableName(name),
|
||||||
current: options[name]
|
current: options[name]
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
return deps;
|
return deps;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief App needs to be configured
|
/// @brief App needs to be configured
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ArangoApp.prototype.needsConfiguration = function() {
|
ArangoApp.prototype.needsConfiguration = function() {
|
||||||
var config = this.getConfiguration();
|
var config = this.getConfiguration();
|
||||||
var deps = this.getDependencies();
|
var deps = this.getDependencies();
|
||||||
return _.any(config, function (cfg) {
|
return _.any(config, function (cfg) {
|
||||||
return cfg.current === undefined;
|
return cfg.current === undefined;
|
||||||
}) || _.any(deps, function (dep) {
|
}) || _.any(deps, function (dep) {
|
||||||
return dep.current === undefined;
|
return dep.current === undefined;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief loadAppScript
|
/// @brief loadAppScript
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ArangoApp.prototype.loadAppScript = function (filename, options) {
|
ArangoApp.prototype.loadAppScript = function (filename, options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
var appContext = _.extend({}, options.appContext, this._context);
|
var appContext = _.extend({}, options.appContext, this._context);
|
||||||
var full = fs.join(this._root, this._path, filename);
|
var full = fs.join(this._root, this._path, filename);
|
||||||
|
|
||||||
if (!fs.exists(full)) {
|
if (!fs.exists(full)) {
|
||||||
throwFileNotFound(full);
|
throwFileNotFound(full);
|
||||||
|
}
|
||||||
|
|
||||||
|
var fileContent = fs.read(full);
|
||||||
|
|
||||||
|
if (options.transform) {
|
||||||
|
fileContent = options.transform(fileContent);
|
||||||
|
} else if (/\.coffee$/.test(filename)) {
|
||||||
|
var cs = require("coffee-script");
|
||||||
|
fileContent = cs.compile(fileContent, {bare: true});
|
||||||
|
}
|
||||||
|
|
||||||
|
var context = {};
|
||||||
|
|
||||||
|
if (options.context) {
|
||||||
|
Object.keys(options.context).forEach(function (key) {
|
||||||
|
context[key] = options.context[key];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var localModule = appContext.appPackage.createAppModule(this, filename);
|
||||||
|
|
||||||
|
context.__filename = full;
|
||||||
|
context.__dirname = module.normalizeModuleName(full + "/..");
|
||||||
|
context.console = require("org/arangodb/foxx/console")(this._mount);
|
||||||
|
context.applicationContext = appContext;
|
||||||
|
|
||||||
|
try {
|
||||||
|
return localModule.run(fileContent, context);
|
||||||
|
} catch(e) {
|
||||||
|
if (e instanceof ArangoError) {
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
|
var err = new ArangoError({
|
||||||
|
errorNum: errors.ERROR_FAILED_TO_EXECUTE_SCRIPT.code,
|
||||||
|
errorMessage: errors.ERROR_FAILED_TO_EXECUTE_SCRIPT.message
|
||||||
|
+ "\nFile: " + filename
|
||||||
|
});
|
||||||
|
err.stack = e.stack;
|
||||||
|
err.cause = e;
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var fileContent = fs.read(full);
|
exports.ArangoApp = ArangoApp;
|
||||||
|
|
||||||
if (options.transform) {
|
|
||||||
fileContent = options.transform(fileContent);
|
|
||||||
} else if (/\.coffee$/.test(filename)) {
|
|
||||||
var cs = require("coffee-script");
|
|
||||||
fileContent = cs.compile(fileContent, {bare: true});
|
|
||||||
}
|
|
||||||
|
|
||||||
var context = {};
|
|
||||||
|
|
||||||
if (options.context) {
|
|
||||||
Object.keys(options.context).forEach(function (key) {
|
|
||||||
context[key] = options.context[key];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var localModule = appContext.appPackage.createAppModule(this, filename);
|
|
||||||
|
|
||||||
context.__filename = full;
|
|
||||||
context.__dirname = module.normalizeModuleName(full + "/..");
|
|
||||||
context.console = require("org/arangodb/foxx/console")(this._mount);
|
|
||||||
context.applicationContext = appContext;
|
|
||||||
|
|
||||||
try {
|
|
||||||
return localModule.run(fileContent, context);
|
|
||||||
} catch(e) {
|
|
||||||
if (e instanceof ArangoError) {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
var err = new ArangoError({
|
|
||||||
errorNum: errors.ERROR_FAILED_TO_EXECUTE_SCRIPT.code,
|
|
||||||
errorMessage: errors.ERROR_FAILED_TO_EXECUTE_SCRIPT.message
|
|
||||||
+ "\nFile: " + filename
|
|
||||||
});
|
|
||||||
err.stack = e.stack;
|
|
||||||
err.cause = e;
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.ArangoApp = ArangoApp;
|
|
||||||
}());
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- END-OF-FILE
|
// --SECTION-- END-OF-FILE
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -174,9 +174,6 @@ function Sessions(opts) {
|
||||||
if (opts.cookie.secret && typeof opts.cookie.secret !== 'string') {
|
if (opts.cookie.secret && typeof opts.cookie.secret !== 'string') {
|
||||||
throw new Error('Cookie secret must be a string or empty.');
|
throw new Error('Cookie secret must be a string or empty.');
|
||||||
}
|
}
|
||||||
if (!opts.cookie.name) {
|
|
||||||
opts.cookie.name = 'sid';
|
|
||||||
}
|
|
||||||
} else if (opts.type === 'header') {
|
} else if (opts.type === 'header') {
|
||||||
if (opts.header && typeof opts.header !== 'string') {
|
if (opts.header && typeof opts.header !== 'string') {
|
||||||
throw new Error('Header name must be a string or empty.');
|
throw new Error('Header name must be a string or empty.');
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief Foxx Swagger documentation
|
/// @brief Foxx Swagger documentation
|
||||||
|
@ -26,67 +27,63 @@
|
||||||
/// @author Copyright 2015, ArangoDB GmbH, Cologne, Germany
|
/// @author Copyright 2015, ArangoDB GmbH, Cologne, Germany
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
(function() {
|
var foxxInternal = require("org/arangodb/foxx/internals");
|
||||||
'use strict';
|
var _ = require("underscore");
|
||||||
|
var internal = require("internal");
|
||||||
|
|
||||||
var foxxInternal = require("org/arangodb/foxx/internals");
|
// Wraps the docs object of a route to add swagger compatible documentation
|
||||||
var _ = require("underscore");
|
var SwaggerDocs = function (docs, models) {
|
||||||
var internal = require("internal");
|
this.docs = docs;
|
||||||
|
this.models = models;
|
||||||
|
};
|
||||||
|
|
||||||
// Wraps the docs object of a route to add swagger compatible documentation
|
SwaggerDocs.prototype.addNickname = function (httpMethod, match) {
|
||||||
var SwaggerDocs = function (docs, models) {
|
this.docs.nickname = foxxInternal.constructNickname(httpMethod, match);
|
||||||
this.docs = docs;
|
};
|
||||||
this.models = models;
|
|
||||||
};
|
|
||||||
|
|
||||||
SwaggerDocs.prototype.addNickname = function (httpMethod, match) {
|
SwaggerDocs.prototype.addPathParam = function (paramName, description, dataType, required) {
|
||||||
this.docs.nickname = foxxInternal.constructNickname(httpMethod, match);
|
this.docs.parameters.push(foxxInternal.constructPathParamDoc(paramName, description, dataType, required));
|
||||||
};
|
};
|
||||||
|
|
||||||
SwaggerDocs.prototype.addPathParam = function (paramName, description, dataType, required) {
|
SwaggerDocs.prototype.addQueryParam = function (paramName, description, dataType, required, allowMultiple) {
|
||||||
this.docs.parameters.push(foxxInternal.constructPathParamDoc(paramName, description, dataType, required));
|
this.docs.parameters.push(foxxInternal.constructQueryParamDoc(
|
||||||
};
|
paramName,
|
||||||
|
description,
|
||||||
|
dataType,
|
||||||
|
required,
|
||||||
|
allowMultiple
|
||||||
|
));
|
||||||
|
};
|
||||||
|
|
||||||
SwaggerDocs.prototype.addQueryParam = function (paramName, description, dataType, required, allowMultiple) {
|
SwaggerDocs.prototype.addBodyParam = function (paramName, description, jsonSchema) {
|
||||||
this.docs.parameters.push(foxxInternal.constructQueryParamDoc(
|
|
||||||
paramName,
|
|
||||||
description,
|
|
||||||
dataType,
|
|
||||||
required,
|
|
||||||
allowMultiple
|
|
||||||
));
|
|
||||||
};
|
|
||||||
|
|
||||||
SwaggerDocs.prototype.addBodyParam = function (paramName, description, jsonSchema) {
|
var token = internal.genRandomAlphaNumbers(32);
|
||||||
|
this.models[token] = jsonSchema;
|
||||||
|
|
||||||
var token = internal.genRandomAlphaNumbers(32);
|
var param = _.find(this.docs.parameters, function (parameter) {
|
||||||
this.models[token] = jsonSchema;
|
return parameter.name === 'undocumented body';
|
||||||
|
});
|
||||||
|
|
||||||
var param = _.find(this.docs.parameters, function (parameter) {
|
if (_.isUndefined(param)) {
|
||||||
return parameter.name === 'undocumented body';
|
this.docs.parameters.push({
|
||||||
|
name: paramName,
|
||||||
|
paramType: "body",
|
||||||
|
description: description,
|
||||||
|
dataType: token
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
param.name = paramName;
|
||||||
|
param.description = description;
|
||||||
|
param.dataType = token;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if (_.isUndefined(param)) {
|
SwaggerDocs.prototype.addSummary = function (summary) {
|
||||||
this.docs.parameters.push({
|
this.docs.summary = summary;
|
||||||
name: paramName,
|
};
|
||||||
paramType: "body",
|
|
||||||
description: description,
|
|
||||||
dataType: token
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
param.name = paramName;
|
|
||||||
param.description = description;
|
|
||||||
param.dataType = token;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
SwaggerDocs.prototype.addSummary = function (summary) {
|
SwaggerDocs.prototype.addNotes = function (notes) {
|
||||||
this.docs.summary = summary;
|
this.docs.notes = notes;
|
||||||
};
|
};
|
||||||
|
|
||||||
SwaggerDocs.prototype.addNotes = function (notes) {
|
|
||||||
this.docs.notes = notes;
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.Docs = SwaggerDocs;
|
exports.Docs = SwaggerDocs;
|
||||||
}());
|
|
||||||
|
|
Loading…
Reference in New Issue