1
0
Fork 0

Merge remote-tracking branch 'origin/issue317' into 1.1

Conflicts:
	js/common/bootstrap/modules.js
This commit is contained in:
Frank Celler 2013-01-03 18:57:18 +01:00
commit f9dba124dd
25 changed files with 1175 additions and 160 deletions

View File

@ -1748,7 +1748,8 @@ WIKI = \
jsUnity
JAVASCRIPT_JSLINT = \
@srcdir@/js/actions/system/api-collection.js
@srcdir@/js/actions/system/api-collection.js \
@srcdir@/js/actions/system/api-structure.js
@ENABLE_ALL_IN_ONE_ICU_TRUE@ICUDIR = @abs_top_srcdir@/3rdParty/icu/BUILD
all: $(BUILT_SOURCES)

View File

@ -90,11 +90,6 @@ using namespace triagens::rest;
using namespace triagens::admin;
using namespace triagens::arango;
#ifdef TRI_ENABLE_MRUBY
#include "mr/common/bootstrap/mr-error.h"
#include "mr/server/mr-server.h"
#endif
// -----------------------------------------------------------------------------
// --SECTION-- private functions
// -----------------------------------------------------------------------------

View File

@ -43,14 +43,6 @@ using namespace triagens::basics;
using namespace triagens::arango;
using namespace std;
#include "js/common/bootstrap/js-modules.h"
#include "js/common/bootstrap/js-monkeypatches.h"
#include "js/common/bootstrap/js-print.h"
#include "js/common/bootstrap/js-errors.h"
#include "js/server/js-ahuacatl.h"
#include "js/server/js-server.h"
#include "js/server/js-version-check.h"
// -----------------------------------------------------------------------------
// --SECTION-- class V8GcThread
// -----------------------------------------------------------------------------
@ -529,7 +521,6 @@ void ApplicationV8::setupOptions (map<string, basics::ProgramOptionsDescription>
bool ApplicationV8::prepare () {
LOGGER_DEBUG << "V8 version: " << v8::V8::GetVersion();
// use a minimum of 1 second for GC
if (_gcFrequency < 1) {
@ -548,17 +539,12 @@ bool ApplicationV8::prepare () {
// set up the startup loader
if (_startupPath.empty()) {
LOGGER_INFO << "using built-in JavaScript startup files";
_startupLoader.defineScript("common/bootstrap/modules.js", JS_common_bootstrap_modules);
_startupLoader.defineScript("common/bootstrap/monkeypatches.js", JS_common_bootstrap_monkeypatches);
_startupLoader.defineScript("common/bootstrap/print.js", JS_common_bootstrap_print);
_startupLoader.defineScript("common/bootstrap/errors.js", JS_common_bootstrap_errors);
_startupLoader.defineScript("server/ahuacatl.js", JS_server_ahuacatl);
_startupLoader.defineScript("server/server.js", JS_server_server);
LOGGER_FATAL << "no 'javascript.startup-directory' has been supplied, giving up";
TRI_FlushLogging();
exit(EXIT_FAILURE);
}
else {
LOGGER_INFO << "using JavaScript startup files at '" << _startupPath << "'";
_startupLoader.setDirectory(_startupPath);
}
@ -576,7 +562,7 @@ bool ApplicationV8::prepare () {
}
}
// add v8 options
if (_v8Options.size() > 0) {
LOGGER_INFO << "using V8 options '" << _v8Options << "'";
v8::V8::SetFlagsFromString(_v8Options.c_str(), _v8Options.size());
@ -659,7 +645,8 @@ bool ApplicationV8::prepareV8Instance (const size_t i) {
"common/bootstrap/print.js",
"common/bootstrap/errors.js",
"server/ahuacatl.js",
"server/server.js"
"server/server.js",
"server/ArangoStructure.js"
};
LOGGER_TRACE << "initialising V8 context #" << i;
@ -717,15 +704,11 @@ bool ApplicationV8::prepareV8Instance (const size_t i) {
if (i == 0 && ! _skipUpgrade) {
LOGGER_DEBUG << "running database version check";
const string script = _startupLoader.buildScript(JS_server_version_check);
// special check script to be run just once in first thread (not in all)
v8::HandleScope scope;
context->_context->Global()->Set(v8::String::New("UPGRADE"), _performUpgrade ? v8::True() : v8::False());
v8::Handle<v8::Value> result = TRI_ExecuteJavaScriptString(context->_context,
v8::String::New(script.c_str()),
v8::String::New("version-check.js"),
false);
v8::Handle<v8::Value> result = _startupLoader.executeGlobalScript(context->_context, "server/version-check.js");
if (! TRI_ObjectToBoolean(result)) {
if (_performUpgrade) {

View File

@ -36,7 +36,8 @@ threads = 5
threads = 3
[javascript]
action-directory= @PKGDATADIR@/js/actions/system
startup-directory = @PKGDATADIR@/js
action-directory = @PKGDATADIR@/js/actions/system
modules-path = @PKGDATADIR@/js/server/modules;@PKGDATADIR@/js/common/modules
[ruby]

View File

@ -14,6 +14,7 @@ threads = 5
threads = 3
[javascript]
startup-directory = ./js
action-directory = ./js/actions/system
modules-path = ./js/server/modules;./js/common/modules

View File

@ -9,7 +9,8 @@
################################################################################
JAVASCRIPT_JSLINT = \
@srcdir@/js/actions/system/api-collection.js
@srcdir@/js/actions/system/api-collection.js \
@srcdir@/js/actions/system/api-structure.js
################################################################################
### @brief executes jslint

View File

@ -770,7 +770,7 @@ function delete_api_collection (req, res) {
}
////////////////////////////////////////////////////////////////////////////////
/// @brief reads or creates a collection
/// @brief handles a collection request
////////////////////////////////////////////////////////////////////////////////
actions.defineHttp({

View File

@ -0,0 +1,152 @@
/*jslint indent: 2,
nomen: true,
maxlen: 100,
sloppy: true,
vars: true,
white: true,
plusplus: true,
stupid: true */
/*global require */
////////////////////////////////////////////////////////////////////////////////
/// @brief querying and managing structures
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2013 triagens GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
/// @author Copyright 2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
var arangodb = require("org/arangodb");
var actions = require("org/arangodb/actions");
var API = "_api/structures";
// -----------------------------------------------------------------------------
// --SECTION-- private functions
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ArangoAPI
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- public functions
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ArangoAPI
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief creates a collection
///
/// @RESTHEADER{POST /_api/structure,creates a structured document}
///
/// @REST{POST /_api/structure?collection=@FA{collection-identifier}}
///
/// Creates a new document in the collection identified by the
/// @FA{collection-identifier}. A JSON representation of the document must be
/// passed as the body of the POST request. The document must fullfill the
/// requirements of the structure definition, see @ref ArangoStructures.
///
/// In all other respects the function is identical to the
/// @ref triagens::arango::RestDocumentHandler::createDocument "POST /_api/structure".
////////////////////////////////////////////////////////////////////////////////
function post_api_structure (req, res) {
var body;
var collection;
var id;
var name;
var result;
var vertex;
body = actions.getJsonBody(req, res);
if (body === undefined) {
return;
}
name = decodeURIComponent(req.suffix[0]);
id = parseInt(name,10) || name;
collection = arangodb.db._structure(id);
if (collection === null) {
actions.collectionNotFound(req, res, name);
return;
}
res = collection.save(body);
actions.resultOk(req, res, actions.HTTP_OK, result);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief handles a structure request
////////////////////////////////////////////////////////////////////////////////
actions.defineHttp({
url : API,
context : "api",
callback : function (req, res) {
try {
if (req.requestType === actions.GET) {
get_api_structure(req, res);
}
else if (req.requestType === actions.DELETE) {
delete_api_structure(req, res);
}
else if (req.requestType === actions.POST) {
post_api_structure(req, res);
}
else if (req.requestType === actions.PUT) {
put_api_structure(req, res);
}
else {
actions.resultUnsupported(req, res);
}
}
catch (err) {
actions.resultException(req, res, err);
}
}
});
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------
// Local Variables:
// mode: outline-minor
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @\\}\\)"
// End:

View File

@ -5,7 +5,7 @@
vars: true,
white: true,
plusplus: true */
/*global require, arango, db, edges, ModuleCache, Module */
/*global require, arango, db, edges, Module */
////////////////////////////////////////////////////////////////////////////////
/// @brief ArangoShell client API
@ -129,11 +129,11 @@ function ArangoError (error) {
/// @{
////////////////////////////////////////////////////////////////////////////////
ModuleCache["/arangosh"] = new Module("/arangosh");
Module.prototype.ModuleCache["/arangosh"] = new Module("/arangosh");
(function () {
var internal = require("internal");
var client = ModuleCache["/arangosh"].exports;
var client = Module.prototype.ModuleCache["/arangosh"].exports;
////////////////////////////////////////////////////////////////////////////////
/// @}

View File

@ -52,6 +52,7 @@
"ERROR_ARANGO_DATAFILE_ALREADY_EXISTS" : { "code" : 1106, "message" : "cannot create/rename datafile because it already exists" },
"ERROR_ARANGO_DATABASE_LOCKED" : { "code" : 1107, "message" : "database is locked" },
"ERROR_ARANGO_COLLECTION_DIRECTORY_ALREADY_EXISTS" : { "code" : 1108, "message" : "cannot create/rename collection because directory already exists" },
"ERROR_ARANGO_MSYNC_FAILED" : { "code" : 1109, "message" : "msync failed" },
"ERROR_ARANGO_CONFLICT" : { "code" : 1200, "message" : "conflict" },
"ERROR_ARANGO_WRONG_VOCBASE_PATH" : { "code" : 1201, "message" : "wrong path for database" },
"ERROR_ARANGO_DOCUMENT_NOT_FOUND" : { "code" : 1202, "message" : "document not found" },
@ -71,6 +72,8 @@
"ERROR_ARANGO_DOCUMENT_TOO_LARGE" : { "code" : 1216, "message" : "document too large" },
"ERROR_ARANGO_COLLECTION_NOT_UNLOADED" : { "code" : 1217, "message" : "collection must be unloaded" },
"ERROR_ARANGO_COLLECTION_TYPE_INVALID" : { "code" : 1218, "message" : "collection type invalid" },
"ERROR_ARANGO_VALIDATION_FAILED" : { "code" : 1219, "message" : "validator failed" },
"ERROR_ARANGO_PARSER_FAILED" : { "code" : 1220, "message" : "parser failed" },
"ERROR_ARANGO_DATAFILE_FULL" : { "code" : 1300, "message" : "datafile full" },
"ERROR_QUERY_KILLED" : { "code" : 1500, "message" : "query killed" },
"ERROR_QUERY_PARSE" : { "code" : 1501, "message" : "%s" },

View File

@ -5,13 +5,13 @@
vars: true,
white: true,
plusplus: true */
/*global require, module, ModuleCache, SYS_EXECUTE, CONSOLE_ERROR,
FS_MOVE, FS_REMOVE, FS_EXISTS,
SYS_LOAD, SYS_LOG, SYS_LOG_LEVEL, SYS_OUTPUT,
SYS_PROCESS_STAT, SYS_READ, SYS_SPRINTF, SYS_TIME,
SYS_START_PAGER, SYS_STOP_PAGER, ARANGO_QUIET, MODULES_PATH,
COLOR_OUTPUT, COLOR_OUTPUT_RESET, COLOR_BRIGHT, PRETTY_PRINT,
SYS_SHA256, SYS_WAIT, SYS_GETLINE */
/*global
require, module,
SYS_EXECUTE, CONSOLE_ERROR, FS_MOVE, FS_REMOVE, FS_EXISTS, SYS_LOAD, SYS_LOG,
SYS_LOG_LEVEL, SYS_OUTPUT, SYS_PROCESS_STAT, SYS_READ, SYS_SPRINTF, SYS_TIME,
SYS_START_PAGER, SYS_STOP_PAGER, ARANGO_QUIET, MODULES_PATH, COLOR_OUTPUT,
COLOR_OUTPUT_RESET, COLOR_BRIGHT, PRETTY_PRINT, SYS_SHA256, SYS_WAIT, SYS_GETLINE
*/
////////////////////////////////////////////////////////////////////////////////
/// @brief JavaScript server functions
@ -49,18 +49,6 @@
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief module cache
////////////////////////////////////////////////////////////////////////////////
ModuleCache = {};
////////////////////////////////////////////////////////////////////////////////
/// @brief file exists cache
////////////////////////////////////////////////////////////////////////////////
ExistsCache = {};
////////////////////////////////////////////////////////////////////////////////
/// @brief module constructor
////////////////////////////////////////////////////////////////////////////////
@ -70,6 +58,18 @@ function Module (id) {
this.exports = {};
}
////////////////////////////////////////////////////////////////////////////////
/// @brief module cache
////////////////////////////////////////////////////////////////////////////////
Module.prototype.ModuleCache = {};
////////////////////////////////////////////////////////////////////////////////
/// @brief file exists cache
////////////////////////////////////////////////////////////////////////////////
Module.prototype.ModuleExistsCache = {};
////////////////////////////////////////////////////////////////////////////////
/// @brief loads a file and creates a new module descriptor
////////////////////////////////////////////////////////////////////////////////
@ -86,12 +86,12 @@ Module.prototype.require = function (path) {
path = this.normalise(path);
// check if you already know the module, return the exports
if (ModuleCache.hasOwnProperty(path)) {
return ModuleCache[path].exports;
if (this.ModuleCache.hasOwnProperty(path)) {
return this.ModuleCache[path].exports;
}
// locate file and read content
raw = ModuleCache["/internal"].exports.readFile(path);
raw = this.ModuleCache["/internal"].exports.readFile(path);
// test for parse errors first and fail early if a parse error detected
if (! SYS_PARSE(raw.content, path)) {
@ -99,7 +99,7 @@ Module.prototype.require = function (path) {
}
// create a new sandbox and execute
module = ModuleCache[path] = new Module(path);
module = this.ModuleCache[path] = new Module(path);
content = "(function (module, exports, require, print) {"
+ raw.content
@ -115,7 +115,7 @@ Module.prototype.require = function (path) {
f(module,
module.exports,
function(path) { return module.require(path); },
ModuleCache["/internal"].exports.print);
this.ModuleCache["/internal"].exports.print);
}
catch (err) {
throw "Javascript exception in file '" + path + "': " + err.stack;
@ -124,6 +124,14 @@ Module.prototype.require = function (path) {
return module.exports;
};
////////////////////////////////////////////////////////////////////////////////
/// @brief returns true if require found a file
////////////////////////////////////////////////////////////////////////////////
Module.prototype.exists = function (path) {
return this.ModuleExistsCache[path];
}
////////////////////////////////////////////////////////////////////////////////
/// @brief normalises a path
////////////////////////////////////////////////////////////////////////////////
@ -192,7 +200,7 @@ Module.prototype.unload = function (path) {
return;
}
delete ModuleCache[norm];
delete this.ModuleCache[norm];
};
////////////////////////////////////////////////////////////////////////////////
@ -202,8 +210,8 @@ Module.prototype.unload = function (path) {
Module.prototype.unloadAll = function () {
var path;
for (path in ModuleCache) {
if (ModuleCache.hasOwnProperty(path)) {
for (path in this.ModuleCache) {
if (this.ModuleCache.hasOwnProperty(path)) {
this.unload(path);
}
}
@ -213,7 +221,7 @@ Module.prototype.unloadAll = function () {
/// @brief top-level module
////////////////////////////////////////////////////////////////////////////////
module = ModuleCache["/"] = new Module("/");
module = Module.prototype.ModuleCache["/"] = new Module("/");
////////////////////////////////////////////////////////////////////////////////
/// @brief global require function
@ -259,10 +267,10 @@ function require (path) {
/// @brief file-system module
////////////////////////////////////////////////////////////////////////////////
ModuleCache["/fs"] = new Module("/fs");
Module.prototype.ModuleCache["/fs"] = new Module("/fs");
(function () {
var fs = ModuleCache["/fs"].exports;
var fs = Module.prototype.ModuleCache["/fs"].exports;
fs.exists = FS_EXISTS;
fs.move = FS_MOVE;
@ -286,11 +294,11 @@ ModuleCache["/fs"] = new Module("/fs");
/// @brief internal module
////////////////////////////////////////////////////////////////////////////////
ModuleCache["/internal"] = new Module("/internal");
Module.prototype.ModuleCache["/internal"] = new Module("/internal");
(function () {
var internal = ModuleCache["/internal"].exports;
var fs = ModuleCache["/fs"].exports;
var internal = Module.prototype.ModuleCache["/internal"].exports;
var fs = Module.prototype.ModuleCache["/fs"].exports;
// system functions
internal.execute = SYS_EXECUTE;
@ -386,6 +394,20 @@ ModuleCache["/internal"] = new Module("/internal");
internal.COLOR_OUTPUT_RESET = COLOR_OUTPUT_RESET;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief extends a prototype
////////////////////////////////////////////////////////////////////////////////
internal.extend = function (target, source) {
Object.getOwnPropertyNames(source)
.forEach(function(propName) {
Object.defineProperty(target, propName,
Object.getOwnPropertyDescriptor(source, propName));
});
return target;
};
////////////////////////////////////////////////////////////////////////////////
/// @brief reads a file from the module path or the database
////////////////////////////////////////////////////////////////////////////////
@ -395,8 +417,6 @@ ModuleCache["/internal"] = new Module("/internal");
var mc;
var n;
var existsCache = ExistsCache;
// try to load the file
var paths = internal.MODULES_PATH;
@ -411,7 +431,7 @@ ModuleCache["/internal"] = new Module("/internal");
}
if (fs.exists(n)) {
existsCache[path] = true;
Module.prototype.ModuleExistsCache[path] = true;
return { path : n, content : internal.read(n) };
}
}
@ -425,7 +445,7 @@ ModuleCache["/internal"] = new Module("/internal");
if (n !== null) {
if (n.hasOwnProperty('content')) {
existsCache[path] = true;
Module.prototype.ModuleExistsCache[path] = true;
return { path : "_collection/" + path, content : n.content };
}
else {
@ -435,7 +455,8 @@ ModuleCache["/internal"] = new Module("/internal");
}
}
existsCache[path] = false;
Module.prototype.ModuleExistsCache[path] = false;
throw "cannot find a file named '"
+ path
+ "' using the module path(s) '"
@ -522,11 +543,11 @@ ModuleCache["/internal"] = new Module("/internal");
/// @brief console module
////////////////////////////////////////////////////////////////////////////////
ModuleCache["/console"] = new Module("/console");
Module.prototype.ModuleCache["/console"] = new Module("/console");
(function () {
var internal = ModuleCache["/internal"].exports;
var console = ModuleCache["/console"].exports;
var internal = Module.prototype.ModuleCache["/internal"].exports;
var console = Module.prototype.ModuleCache["/console"].exports;
console.getline = SYS_GETLINE;

View File

@ -0,0 +1,466 @@
/*jslint indent: 2,
nomen: true,
maxlen: 100,
sloppy: true,
vars: true,
white: true,
plusplus: true */
/*global require */
////////////////////////////////////////////////////////////////////////////////
/// @brief ArangoStructure
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2011-2012 triagens GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
/// @author Copyright 2011-2012, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
(function () {
var internal = require("internal");
var console = require("console");
var ArangoDatabase = internal.ArangoDatabase;
var ArangoCollection = internal.ArangoCollection;
var ArangoError = internal.ArangoError;
// -----------------------------------------------------------------------------
// --SECTION-- constructors and destructors
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup V8Shell
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
function ArangoStructure (collection, lang) {
this._id = collection._id;
this._collection = collection;
this._language = lang;
};
internal.ArangoStructure = ArangoStructure;
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- public methods
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup V8Shell
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief name of a structure
////////////////////////////////////////////////////////////////////////////////
ArangoStructure.prototype.name = function () {
return this._collection.name();
}
////////////////////////////////////////////////////////////////////////////////
/// @brief status of a structure
////////////////////////////////////////////////////////////////////////////////
ArangoStructure.prototype.status = function () {
return this._collection.status();
}
////////////////////////////////////////////////////////////////////////////////
/// @brief type of a structure
////////////////////////////////////////////////////////////////////////////////
ArangoStructure.prototype.type = function () {
return this._collection.type();
}
////////////////////////////////////////////////////////////////////////////////
/// @brief saves a document
////////////////////////////////////////////////////////////////////////////////
ArangoStructure.prototype.save = function (data, waitForSync) {
data = ParseStructureInformation(this._language, this._collection.name(), data);
return this._collection.save(data, waitForSync);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief replaces a document
////////////////////////////////////////////////////////////////////////////////
ArangoStructure.prototype.replace = function (document, data, overwrite, waitForSync) {
data = ParseStructureInformation(this._language, this._collection.name(), data);
return this._collection.save(document, data, overwrite, waitForSync);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief deletes a document
////////////////////////////////////////////////////////////////////////////////
ArangoStructure.prototype.remove = function (document, overwrite, waitForSync) {
return this._collection.remove(document, overwrite, waitForSync);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief reads a document
////////////////////////////////////////////////////////////////////////////////
ArangoStructure.prototype.document = function (handle) {
var data;
data = this._collection.document(handle);
return FormatStructureInformation(this._language, this._collection.name(), data);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief database accessor
////////////////////////////////////////////////////////////////////////////////
ArangoDatabase.prototype._structure = function (name, lang) {
var collection;
collection = internal.db._collection(name);
if (collection === null) {
return null;
}
if (lang === undefined || lang === null) {
lang = "en";
}
return new ArangoStructure(collection, lang);
};
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- private methods
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup V8Shell
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief prints a collection
////////////////////////////////////////////////////////////////////////////////
ArangoStructure.prototype._PRINT = function () {
var status = type = "unknown";
switch (this.status()) {
case ArangoCollection.STATUS_NEW_BORN: status = "new born"; break;
case ArangoCollection.STATUS_UNLOADED: status = "unloaded"; break;
case ArangoCollection.STATUS_UNLOADING: status = "unloading"; break;
case ArangoCollection.STATUS_LOADED: status = "loaded"; break;
case ArangoCollection.STATUS_CORRUPTED: status = "corrupted"; break;
case ArangoCollection.STATUS_DELETED: status = "deleted"; break;
}
switch (this.type()) {
case ArangoCollection.TYPE_DOCUMENT: type = "document"; break;
case ArangoCollection.TYPE_EDGE: type = "edge"; break;
case ArangoCollection.TYPE_ATTACHMENT: type = "attachment"; break;
}
internal.output("[ArangoStructure ",
this._id,
", \"", this.name(), "\" (type ", type, ", status ", status, "lang ", this._language, ")]");
};
////////////////////////////////////////////////////////////////////////////////
/// @brief parses and validates the structure information
////////////////////////////////////////////////////////////////////////////////
function ParseStructureInformation (lang, name, data) {
var info;
var key;
var validated;
info = internal.db._collection("_structures").firstExample({ collection: name });
if (info === null) {
return data;
}
validated = {};
for (key in data) {
if (data.hasOwnProperty(key)) {
validated[key] = ParseStructureInformationRecursive(lang, info, key, key, data[key]);
}
}
return validated;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief parses and validates the structure information recursively
////////////////////////////////////////////////////////////////////////////////
function ParseStructureInformationRecursive (lang, info, path, key, value) {
var k;
var result;
if (info.attributes.hasOwnProperty(path)) {
value = ParseAndValidate(lang, info.attributes[path], value);
}
if (value instanceof Array) {
return value;
}
else if (value instanceof Object) {
result = {};
for (k in value) {
if (value.hasOwnProperty(k)) {
result[k] = ParseStructureInformationRecursive(lang, info, path + "." + k, k, value[k]);
}
}
return result;
}
else {
return value;
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief parses and validates a single attribute
////////////////////////////////////////////////////////////////////////////////
function ParseAndValidate (lang, info, value) {
var type;
// parse the input
if (info.hasOwnProperty("parser")) {
if (info.parser.hasOwnProperty(lang)) {
value = Parse(lang, info.parser[lang], value);
}
else if (info.parser.hasOwnProperty('default')) {
value = Parse(lang, info.parser['default'], value);
}
}
else if (info.hasOwnProperty("type")) {
type = info.type;
if (type === "number") {
value = parseFloat(value);
}
else if (type === "string") {
value = String(value);
}
else if (type === "boolean") {
if (value === 1 || value === "1" || (/^true$/i).test(value)) {
value = true;
}
else {
value = false;
}
}
}
// validate the input
if (info.hasOwnProperty("validator")) {
if (info.validator.hasOwnProperty(lang)) {
Validate(lang, info.validator[lang], value);
}
else if (info.validator.hasOwnProperty('default')) {
Validate(lang, info.validator['default'], value);
}
}
// and return
return value;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief parses a single attribute
////////////////////////////////////////////////////////////////////////////////
function Parse (lang, info, value) {
var error;
var module;
try {
module = require(info.module);
}
catch (err) {
error = new ArangoError();
error.errorNum = internal.errors.ERROR_NOT_IMPLEMENTED.code;
error.errorMessage = String(err);
throw error;
}
return module[info['do']](value, info, lang);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief validates a single attribute
////////////////////////////////////////////////////////////////////////////////
function Validate (lang, info, value) {
var error;
var module;
try {
module = require(info.module);
}
catch (err) {
error = new ArangoError();
error.errorNum = internal.errors.ERROR_NOT_IMPLEMENTED.code;
error.errorMessage = String(err);
throw error;
}
module[info['do']](value, info, lang);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief formats the structure information
////////////////////////////////////////////////////////////////////////////////
function FormatStructureInformation (lang, name, data) {
var info;
var key;
var formatted;
info = internal.db._collection("_structures").firstExample({ collection: name });
if (info === null) {
return data;
}
formatted = {};
for (key in data) {
if (data.hasOwnProperty(key)) {
formatted[key] = FormatStructureInformationRecursive(lang, info, key, key, data[key]);
}
}
return formatted;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief formats the structure information recursively
////////////////////////////////////////////////////////////////////////////////
function FormatStructureInformationRecursive (lang, info, path, key, value) {
var k;
var result;
if (info.attributes.hasOwnProperty(path)) {
value = FormatValue(lang, info.attributes[path], value);
}
if (value instanceof Array) {
return value;
}
else if (value instanceof Object) {
result = {};
for (k in value) {
if (value.hasOwnProperty(k)) {
result[k] = FormatStructureInformationRecursive(lang, info, path + "." + k, k, value[k]);
}
}
return result;
}
else {
return value;
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief formats a single attribute
////////////////////////////////////////////////////////////////////////////////
function FormatValue (lang, info, value) {
var type;
// parse the input
if (info.hasOwnProperty("formatter")) {
if (info.formatter.hasOwnProperty(lang)) {
value = Format(lang, info.formatter[lang], value);
}
else if (info.formatter.hasOwnProperty('default')) {
value = Format(lang, info.formatter['default'], value);
}
}
// and return
return value;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief formats a single attribute
////////////////////////////////////////////////////////////////////////////////
function Format (lang, info, value) {
var error;
var module;
try {
module = require(info.module);
}
catch (err) {
error = new ArangoError();
error.errorNum = internal.errors.ERROR_NOT_IMPLEMENTED.code;
error.errorMessage = String(err);
throw error;
}
return module[info['do']](value, info, lang);
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
}());
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------
// Local Variables:
// mode: outline-minor
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @\\}\\)"
// End:

View File

@ -5,7 +5,7 @@
vars: true,
white: true,
plusplus: true */
/*global require, exports */
/*global require, exports, module */
////////////////////////////////////////////////////////////////////////////////
/// @brief JavaScript actions module
@ -69,8 +69,8 @@ var RoutingCache;
/// @brief function that's returned for non-implemented actions
////////////////////////////////////////////////////////////////////////////////
function notImplementedFunction (triggerRoute, message) {
message += "\nThis error is triggered by the following route " + JSON.stringify(triggerRoute);
function notImplementedFunction (route, message) {
message += "\nThis error was triggered by the following route " + JSON.stringify(route);
console.error(message);
@ -85,8 +85,8 @@ function notImplementedFunction (triggerRoute, message) {
/// @brief function that's returned for actions that produce an error
////////////////////////////////////////////////////////////////////////////////
function errorFunction (triggerRoute, message) {
message += "\nThis error is triggered by the following route " + JSON.stringify(triggerRoute);
function errorFunction (route, message) {
message += "\nThis error was triggered by the following route " + JSON.stringify(route);
console.error(message);
@ -218,6 +218,7 @@ function lookupCallbackAction (route, action) {
var name;
var func;
var module;
var joined;
var httpMethods = {
'get': exports.GET,
'head': exports.HEAD,
@ -235,28 +236,35 @@ function lookupCallbackAction (route, action) {
path = action['do'].split("/");
name = path.pop();
func = null;
joined = path.join("/");
try {
module = require(path.join("/"));
module = require(joined);
if (module.hasOwnProperty(name)) {
func = module[name];
}
else {
func = notImplementedFunction(route, "Could not find action named '" + name + "' in module '" + path.join("/") + "'");
func = notImplementedFunction(route, "could not find action named '" + name + "' in module '" + joined + "'");
}
}
catch (err) {
if (! ExistsCache[path.join("/")]) {
func = notImplementedFunction(route, "An error occurred while loading action named '" + name + "' in module '" + path.join("/") + "': " + String(err));
if (! module.exists(joined)) {
func = notImplementedFunction(route,
"an error occurred while loading action named '" + name
+ "' in module '" + joined + "': " + String(err));
}
else {
func = errorFunction(route, "An error occurred while loading action named '" + name + "' in module '" + path.join("/") + "': " + String(err));
func = errorFunction(route,
"an error occurred while loading action named '" + name
+ "' in module '" + joined + "': " + String(err));
}
}
if (func === null || typeof func !== 'function') {
func = errorFunction(route, "Invalid definition for the action named '" + name + "' in module '" + path.join("/") + "'");
func = errorFunction(route,
"invalid definition for the action named '" + name
+ "' in module '" + joined + "'");
}
return {
@ -279,16 +287,20 @@ function lookupCallbackAction (route, action) {
}
if (req.requestType == httpMethods[m] && module.hasOwnProperty(m)) {
func = module[m] ||
errorFunction(route, "Invalid definition for " + m + " action in action controller module '" + action.controller + "'");
func = module[m]
|| errorFunction(route,
"invalid definition for " + m + " action in action controller module '"
+ action.controller + "'");
return func(req, res, options, next);
}
}
if (module.hasOwnProperty('do')) {
func = module['do'] ||
errorFunction(route, "Invalid definition for do action in action controller module '" + action.controller + "'");
func = module['do']
|| errorFunction(route,
"invalid definition for do action in action controller module '"
+ action.controller + "'");
return func(req, res, options, next);
}
@ -300,11 +312,15 @@ function lookupCallbackAction (route, action) {
};
}
catch (err) {
if (! ExistsCache[action.controller]) {
return notImplementedFunction(route, "cannot load/execute action controller module '" + action.controller + ": " + String(err));
if (! module.exists(action.controller)) {
return notImplementedFunction(route,
"cannot load/execute action controller module '"
+ action.controller + ": " + String(err));
}
return errorFunction(route, "cannot load/execute action controller module '" + action.controller + ": " + String(err));
return errorFunction(route,
"cannot load/execute action controller module '"
+ action.controller + ": " + String(err));
}
}
@ -315,6 +331,7 @@ function lookupCallbackAction (route, action) {
controller: function (req, res, options, next) {
var module;
var path;
var efunc;
// determine path
if (req.hasOwnProperty('suffix')) {
@ -329,11 +346,13 @@ function lookupCallbackAction (route, action) {
require(path);
}
catch (err) {
if (! ExistsCache[path]) {
return notImplementedFunction(route, "cannot load prefix controller: " + String(err))(req, res, options, next);
efunc = errorFunction;
if (! module.exists(path)) {
efunc = notImplementedFunction;
}
return errorFunction(route, "cannot load prefix controller: " + String(err))(req, res, options, next);
return efunc(route, "cannot load prefix controller: " + String(err))(req, res, options, next);
}
try {
@ -344,21 +363,28 @@ function lookupCallbackAction (route, action) {
}
if (req.requestType == httpMethods[m] && module.hasOwnProperty(m)) {
func = module[m] ||
errorFunction(route, "Invalid definition for " + m + " action in prefix controller '" + action.prefixController + "'");
func = module[m]
|| errorFunction(route,
"Invalid definition for " + m + " action in prefix controller '"
+ action.prefixController + "'");
return func(req, res, options, next);
}
}
if (module.hasOwnProperty('do')) {
func = module['do'] ||
errorFunction(route, "Invalid definition for do action in prefix controller '" + action.prefixController + "'");
func = module['do']
|| errorFunction(route,
"Invalid definition for do action in prefix controller '"
+ action.prefixController + "'");
return func(req, res, options, next);
}
}
catch (err) {
return errorFunction(route, "Cannot load/execute prefix controller '" + action.prefixController + "': " + String(err))(req, res, options, next);
return errorFunction(route,
"Cannot load/execute prefix controller '"
+ action.prefixController + "': " + String(err))(req, res, options, next);
}
next();

View File

@ -0,0 +1,85 @@
/*jslint indent: 2,
nomen: true,
maxlen: 100,
sloppy: true,
vars: true,
white: true,
plusplus: true */
/*global require, exports */
////////////////////////////////////////////////////////////////////////////////
/// @brief formatter functions
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2011-2012 triagens GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
/// @author Copyright 2011-2012, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- number parsers
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief parses a number
////////////////////////////////////////////////////////////////////////////////
exports.number = function (value, info, lang) {
var error;
var format;
var result;
if (info.hasOwnProperty('format')) {
format = info.format;
if (format === "%d") {
result = value.toFixed(0);
}
else if (format === "%f") {
result = String(value);
}
else {
error = new ArangoError();
error.errorNum = internal.errors.ERROR_NOT_IMPLEMENTED.code;
error.errorMessage = "format '" + format + "' not implemented";
throw error;
}
}
else {
result = value;
}
return result;
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------
// Local Variables:
// mode: outline-minor
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @\\}\\)"
// End:

View File

@ -1,51 +0,0 @@
/I"..\..\lib"
/I"..\"
/I"..\..\"
/I"..\..\VisualStudio"
/I"..\..\3rdParty\VisualStudio\openssl\x86\include"
/I"..\..\3rdParty\VisualStudio\mygetopt"
/I"..\..\3rdParty\VisualStudio\regex-2.7\src"
/I"..\..\3rdParty\VisualStudio\readline-5.0-1-lib\include"
/I"..\..\arangod"
/I"..\..\3rdParty\VisualStudio\V8\include"
/Zi (debug information format)
/nologo (suppress startup banner)
/W3 (warnings)
/WX- (warnings)
/O2 (optimise)
/Oi
/Oy-
/GL
/D "WIN32"
/D "NDEBUG"
/D "_CONSOLE"
/D "_WIN32"
/D "YY_NO_UNISTD_H"
/D "_UNICODE"
/D "UNICODE"
/D ")"
/Gm-
/EHsc
/MT
/GS !!!!!!!!!!!!!!
/Gy ?????????????
/fp:precise
/Zc:wchar_t ???????????????????
/Zc:forScope !!!!!!!!!!!!!!!!!!
/Gd ???????????????????
/analyze-
/errorReport:queue
/Fp"Release\arangod.pch"
/Fa"Release\"
/Fo"Release\"
/Fd"Release\vc100.pdb"

View File

@ -0,0 +1,99 @@
/*jslint indent: 2,
nomen: true,
maxlen: 100,
sloppy: true,
vars: true,
white: true,
plusplus: true */
/*global require, exports */
////////////////////////////////////////////////////////////////////////////////
/// @brief parser functions
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2011-2012 triagens GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
/// @author Copyright 2011-2012, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- number parsers
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief parses a number
////////////////////////////////////////////////////////////////////////////////
exports.number = function (value, info, lang) {
var error;
var format;
var result;
if (info.hasOwnProperty('format')) {
format = info.format;
if (format === "%d") {
result = parseInt(value);
}
else if (format === "%f") {
result = parseFloat(value);
}
else if (format === "%x") {
result = parseInt(value, 16);
}
else if (format === "%o") {
result = parseInt(value, 8);
}
else {
error = new ArangoError();
error.errorNum = internal.errors.ERROR_NOT_IMPLEMENTED.code;
error.errorMessage = "format '" + format + "' not implemented";
throw error;
}
}
else {
result = parseFloat(value);
}
if (result === null || result === undefined || isNaN(result)) {
error = new ArangoError();
error.errorNum = internal.errors.ERROR_ARANGO_PARSER_FAILED;
error.errorMessage = "format '" + format + "' not implemented";
throw error;
}
return result;
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------
// Local Variables:
// mode: outline-minor
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @\\}\\)"
// End:

View File

@ -0,0 +1,136 @@
/*jslint indent: 2,
nomen: true,
maxlen: 100,
sloppy: true,
vars: true,
white: true,
plusplus: true */
/*global require, exports */
////////////////////////////////////////////////////////////////////////////////
/// @brief validator functions
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2011-2012 triagens GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
/// @author Copyright 2011-2012, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- number validators
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief positive number
////////////////////////////////////////////////////////////////////////////////
exports.positiveNumber = function (value, info, lang) {
if (value <= 0.0) {
error = new ArangoError();
error.errorNum = internal.errors.ERROR_ARANGO_VALIDATION_FAILED.code;
error.errorMessage = "number must be positive";
throw error;
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief negative number
////////////////////////////////////////////////////////////////////////////////
exports.negativeNumber = function (value, info, lang) {
if (0.0 <= value) {
error = new ArangoError();
error.errorNum = internal.errors.ERROR_ARANGO_VALIDATION_FAILED.code;
error.errorMessage = "number must be negative";
throw error;
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief zero
////////////////////////////////////////////////////////////////////////////////
exports.zeroNumber = function (value, info, lang) {
if (value === 0.0) {
error = new ArangoError();
error.errorNum = internal.errors.ERROR_ARANGO_VALIDATION_FAILED.code;
error.errorMessage = "number must be zero";
throw error;
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief non-positive number
////////////////////////////////////////////////////////////////////////////////
exports.nonPositiveNumber = function (value, info, lang) {
if (0.0 < value) {
error = new ArangoError();
error.errorNum = internal.errors.ERROR_ARANGO_VALIDATION_FAILED.code;
error.errorMessage = "number must be non-positive";
throw error;
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief non-negative number
////////////////////////////////////////////////////////////////////////////////
exports.nonNegativeNumber = function (value, info, lang) {
if (value < 0.0) {
error = new ArangoError();
error.errorNum = internal.errors.ERROR_ARANGO_VALIDATION_FAILED.code;
error.errorMessage = "number must be non-negative";
throw error;
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief zero
////////////////////////////////////////////////////////////////////////////////
exports.nonZeroNumber = function (value, info, lang) {
if (value !== 0.0) {
error = new ArangoError();
error.errorNum = internal.errors.ERROR_ARANGO_VALIDATION_FAILED.code;
error.errorMessage = "number must be non-zero";
throw error;
}
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------
// Local Variables:
// mode: outline-minor
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @\\}\\)"
// End:

View File

@ -57,6 +57,8 @@
internal.db = db;
internal.edges = db;
internal.ArangoCollection = ArangoCollection;
internal.ArangoDatabase = ArangoDatabase;
internal.ArangoError = ArangoError;
if (typeof SYS_DEFINE_ACTION === "undefined") {
internal.defineAction = function() {

View File

@ -225,9 +225,10 @@
return createSystemCollection("_routing");
});
// create the _routing collection
// create the default route in the _routing collection
addTask("insertDefaultRoute", "insert default route for the admin interface", function () {
var routing = getCollection("_routing");
if (! routing) {
return false;
}
@ -240,6 +241,24 @@
return true;
});
// set up the collection _structures
addTask("setupStructures", "setup _structures collection", function () {
return createSystemCollection("_structures", { waitForSync : true });
});
// create a unique index on collection attribute in _structures
addTask("createStructuresIndex", "create index on collection attribute in _structures collection", function () {
var structures = getCollection("_structures");
if (! structures) {
return false;
}
structures.ensureUniqueConstraint("collection");
return true;
});
// loop through all tasks and execute them
console.log("Found " + allTasks.length + " defined task(s), " + activeTasks.length + " task(s) to run");

View File

@ -90,6 +90,8 @@ ERROR_ARANGO_CAP_CONSTRAINT_ALREADY_DEFINED,1215,"cap constraint already defined
ERROR_ARANGO_DOCUMENT_TOO_LARGE,1216,"document too large","Will be raised when the document cannot fit into any datafile because of it is too large."
ERROR_ARANGO_COLLECTION_NOT_UNLOADED,1217,"collection must be unloaded","Will be raised when a collection should be unloaded, but has a different status."
ERROR_ARANGO_COLLECTION_TYPE_INVALID,1218,"collection type invalid","Will be raised when an invalid collection type is used in a request."
ERROR_ARANGO_VALIDATION_FAILED,1219,"validator failed","Will be raised when the validation of an attribute of a structure failed."
ERROR_ARANGO_PARSER_FAILED,1220,"parser failed","Will be raised when the parsing of an attribute of a structure failed."
################################################################################
## ArangoDB storage errors

View File

@ -68,6 +68,8 @@ void TRI_InitialiseErrorMessages (void) {
REG_ERROR(ERROR_ARANGO_DOCUMENT_TOO_LARGE, "document too large");
REG_ERROR(ERROR_ARANGO_COLLECTION_NOT_UNLOADED, "collection must be unloaded");
REG_ERROR(ERROR_ARANGO_COLLECTION_TYPE_INVALID, "collection type invalid");
REG_ERROR(ERROR_ARANGO_VALIDATION_FAILED, "validator failed");
REG_ERROR(ERROR_ARANGO_PARSER_FAILED, "parser failed");
REG_ERROR(ERROR_ARANGO_DATAFILE_FULL, "datafile full");
REG_ERROR(ERROR_QUERY_KILLED, "query killed");
REG_ERROR(ERROR_QUERY_PARSE, "%s");

View File

@ -137,6 +137,10 @@ extern "C" {
/// status.
/// - 1218: @LIT{collection type invalid}
/// Will be raised when an invalid collection type is used in a request.
/// - 1219: @LIT{validator failed}
/// Will be raised when the validation of an attribute of a structure failed.
/// - 1220: @LIT{parser failed}
/// Will be raised when the parsing of an attribute of a structure failed.
/// - 1300: @LIT{datafile full}
/// Will be raised when the datafile reaches its limit.
/// - 1500: @LIT{query killed}
@ -902,6 +906,26 @@ void TRI_InitialiseErrorMessages (void);
#define TRI_ERROR_ARANGO_COLLECTION_TYPE_INVALID (1218)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1219: ERROR_ARANGO_VALIDATION_FAILED
///
/// validator failed
///
/// Will be raised when the validation of an attribute of a structure failed.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_ARANGO_VALIDATION_FAILED (1219)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1220: ERROR_ARANGO_PARSER_FAILED
///
/// parser failed
///
/// Will be raised when the parsing of an attribute of a structure failed.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_ARANGO_PARSER_FAILED (1220)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1300: ERROR_ARANGO_DATAFILE_FULL
///

View File

@ -96,12 +96,16 @@ string ScriptLoader::buildScript (const char** script) {
while (true) {
string tempStr = string(*script);
if (tempStr == "//__end__") {
break;
}
scriptString += tempStr + "\n";
++script;
}
return scriptString;
}
@ -115,6 +119,10 @@ void ScriptLoader::defineScript (string const& name, string const& script) {
_scripts[name] = script;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief defines a new named script
////////////////////////////////////////////////////////////////////////////////
void ScriptLoader::defineScript (const string& name, const char** script) {
string scriptString = buildScript(script);
@ -128,9 +136,9 @@ void ScriptLoader::defineScript (const string& name, const char** script) {
////////////////////////////////////////////////////////////////////////////////
string const& ScriptLoader::findScript (string const& name) {
MUTEX_LOCKER(_lock);
static string empty = "";
MUTEX_LOCKER(_lock);
map<string, string>::iterator i = _scripts.find(name);
@ -189,11 +197,11 @@ vector<string> ScriptLoader::getDirectoryParts () {
// implementations, otherwise we will only allow ";"
// .........................................................................
#ifdef _WIN32
#ifdef _WIN32
TRI_vector_string_t parts = TRI_Split2String(_directory.c_str(), ";");
#else
#else
TRI_vector_string_t parts = TRI_Split2String(_directory.c_str(), ":;");
#endif
#endif
for (size_t i = 0; i < parts._length; i++) {
string part = StringUtils::trim(parts._buffer[i]);

View File

@ -67,6 +67,38 @@ JSLoader::JSLoader () {
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief executes a named script in the global context
////////////////////////////////////////////////////////////////////////////////
v8::Handle<v8::Value> JSLoader::executeGlobalScript (v8::Persistent<v8::Context> context,
string const& name) {
v8::HandleScope scope;
v8::TryCatch tryCatch;
findScript(name);
map<string, string>::iterator i = _scripts.find(name);
if (i == _scripts.end()) {
// correct the path/name
LOGGER_ERROR << "unknown script '" << StringUtils::correctPath(name) << "'";
return scope.Close(v8::Undefined());
}
v8::Handle<v8::Value> result = TRI_ExecuteJavaScriptString(context,
v8::String::New(i->second.c_str()),
v8::String::New(name.c_str()),
false);
if (tryCatch.HasCaught()) {
TRI_LogV8Exception(&tryCatch);
return scope.Close(v8::Undefined());
}
return scope.Close(result);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief loads a named script
////////////////////////////////////////////////////////////////////////////////

View File

@ -86,6 +86,13 @@ namespace triagens {
public:
////////////////////////////////////////////////////////////////////////////////
/// @brief executes a named script in the global context
////////////////////////////////////////////////////////////////////////////////
v8::Handle<v8::Value> executeGlobalScript (v8::Persistent<v8::Context> context,
string const& name);
////////////////////////////////////////////////////////////////////////////////
/// @brief loads a named script
////////////////////////////////////////////////////////////////////////////////