1
0
Fork 0

Merge branch '1.1' of github.com:triAGENS/ArangoDB into devel

Conflicts:
	CHANGELOG
	Makefile.in
	arangod/V8Server/ApplicationV8.cpp
	arangod/V8Server/v8-vocbase.cpp
	html/admin/js/master.js
	js/actions/system/api-collection.js
	js/common/bootstrap/errors.js
	js/server/version-check.js
	lib/BasicsC/errors.dat
	lib/BasicsC/logging.c
	lib/BasicsC/voc-errors.c
	lib/BasicsC/voc-errors.h
This commit is contained in:
Frank Celler 2013-01-05 11:16:50 +01:00
commit 0549528325
30 changed files with 1604 additions and 538 deletions

View File

@ -144,9 +144,13 @@ v1.1.2 (XXXX-XX-XX)
* reduce memory usage for the case when there are lots of small collections with few
documents each
* started with issue #317: Feature Request (from Google Groups): DATE handling
* backported issue #300: Extend arangoImp to Allow importing resultset-like
(list of documents) formatted files
* fixed issue #337: "WaitForSync" on new collection does not work on Win/X64
* fixed issue #332: arangoimp --use-ids parameter seems to have no impact
* fixed issue #337: "WaitForSync" on new collection does not work on Win/X64

View File

@ -281,7 +281,7 @@ endif
### @brief unit tests
################################################################################
include UnitTests/Makefile.files
include UnitTests/Makefile.unittests
################################################################################
### @brief error code file

View File

@ -19,7 +19,7 @@ PROTO = http
## -----------------------------------------------------------------------------
################################################################################
## unittests target
### @brief unittests target
################################################################################
.PHONY: unittests unittests-brief unittests-verbose
@ -56,7 +56,7 @@ unittests-verbose:
@sleep 1
################################################################################
## start the arango server
### @brief start the arango server
################################################################################
PID := $(shell echo $$PPID)
@ -121,7 +121,7 @@ start-server:
@echo
################################################################################
## COMMON MAKE-RELATED TESTS
### @brief COMMON MAKE-RELATED TESTS
################################################################################
.PHONY: unittests-make
@ -130,7 +130,7 @@ unittests-make:
@(ctags --version > /dev/null 2> /dev/null && make tags > /dev/null || test "x$(FORCE)" == "x1") || true
################################################################################
## BOOST TESTS
### @brief BOOST TESTS
################################################################################
.PHONY: unittests-boost
@ -198,7 +198,7 @@ unittests-boost:
endif
################################################################################
## SHELL SERVER TESTS (BASICS)
### @brief SHELL SERVER TESTS (BASICS)
################################################################################
SHELL_COMMON = @top_srcdir@/js/common/tests/shell-document.js \
@ -241,7 +241,7 @@ unittests-shell-server:
@echo
################################################################################
## SHELL SERVER TESTS (AHUACATL)
### @brief SHELL SERVER TESTS (AHUACATL)
################################################################################
SHELL_SERVER_AHUACATL = @top_srcdir@/js/server/tests/ahuacatl-ranges.js \
@ -313,7 +313,7 @@ unittests-shell-server-ahuacatl:
@echo
################################################################################
## SHELL CLIENT TESTS
### @brief SHELL CLIENT TESTS
################################################################################
SHELL_CLIENT = $(SHELL_COMMON) @top_srcdir@/js/client/tests/client.js
@ -342,7 +342,7 @@ unittests-shell-client:
@echo
################################################################################
## HTTP SERVER TESTS
### @brief HTTP SERVER TESTS
################################################################################
.PHONY: unittests-http-server
@ -368,7 +368,7 @@ unittests-http-server:
################################################################################
## SSL SERVER TESTS (same as HTTP SERVER TESTS but using SSL)
### @brief SSL SERVER TESTS (same as HTTP SERVER TESTS but using SSL)
################################################################################
.PHONY: unittests-ssl-server
@ -393,7 +393,7 @@ unittests-ssl-server:
@echo
################################################################################
## IMPORT TESTS
### @brief IMPORT TESTS
################################################################################
.PHONY: unittests-import
@ -423,7 +423,7 @@ unittests-import:
@echo
################################################################################
## BITARRAY INDEXES TESTS
### @brief BITARRAY INDEXES TESTS
################################################################################
BITARRAY_COMMON = @top_srcdir@/js/common/tests/shell-bitarray-index.js
@ -448,7 +448,7 @@ unittests-bitarray-index:
@echo
################################################################################
## ARANGOB TESTS
### @brief ARANGOB TESTS
################################################################################
.PHONY: unittests-arangob
@ -482,3 +482,12 @@ unittests-arangob:
@echo
endif
## -----------------------------------------------------------------------------
## --SECTION-- END-OF-FILE
## -----------------------------------------------------------------------------
## Local Variables:
## mode: outline-minor
## outline-regexp: "^\\(### @brief\\|## --SECTION--\\|# -\\*- \\)"
## End:

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
// -----------------------------------------------------------------------------
@ -702,7 +697,7 @@ int ArangoServer::executeConsole (OperationMode::server_operation_mode_e mode) {
// run the shell
if (mode != OperationMode::MODE_SCRIPT) {
printf("ArangoDB JavaScript shell [V8 version %s, DB version %s]\n", v8::V8::GetVersion(), TRIAGENS_VERSION);
printf("ArangoDB JavaScript emergency console [V8 version %s, DB version %s]\n", v8::V8::GetVersion(), TRIAGENS_VERSION);
}
else {
LOGGER_INFO << "V8 version " << v8::V8::GetVersion() << ", DB version " << TRIAGENS_VERSION;
@ -1019,7 +1014,7 @@ int ArangoServer::executeRubyConsole () {
ApplicationMR::MRContext* context = _applicationMR->enterContext();
// create a line editor
printf("ArangoDB MRuby shell [DB version %s]\n", TRIAGENS_VERSION);
printf("ArangoDB MRuby emergency console [DB version %s]\n", TRIAGENS_VERSION);
MRLineEditor console(context->_mrb, ".arango-mrb");

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,16 +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(TRI_V8_SYMBOL("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);
context->_context->Global()->Set(v8::String::New("UPGRADE"), _performUpgrade ? v8::True() : v8::False());
v8::Handle<v8::Value> result = _startupLoader.executeGlobalScript(context->_context, "server/version-check.js");
if (! TRI_ObjectToBoolean(result)) {
if (_performUpgrade) {

View File

@ -1207,14 +1207,14 @@ static v8::Handle<v8::Value> UpdateVocbaseCol (const bool useCollection,
/// @brief deletes a document
////////////////////////////////////////////////////////////////////////////////
static v8::Handle<v8::Value> DeleteVocbaseCol (const bool useCollection,
static v8::Handle<v8::Value> RemoveVocbaseCol (const bool useCollection,
v8::Arguments const& argv) {
v8::HandleScope scope;
// check the arguments
if (argv.Length() < 1 || argv.Length() > 3) {
return scope.Close(v8::ThrowException(TRI_CreateErrorObject(TRI_ERROR_BAD_PARAMETER,
"usage: delete(<document>, <overwrite>, <waitForSync>)")));
"usage: remove(<document>, <overwrite>, <waitForSync>)")));
}
const TRI_doc_update_policy_e policy = ExtractUpdatePolicy(argv, 2);
@ -4648,7 +4648,7 @@ static v8::Handle<v8::Value> JS_PropertiesVocbaseCol (v8::Arguments const& argv)
////////////////////////////////////////////////////////////////////////////////
static v8::Handle<v8::Value> JS_RemoveVocbaseCol (v8::Arguments const& argv) {
return DeleteVocbaseCol(true, argv);
return RemoveVocbaseCol(true, argv);
}
////////////////////////////////////////////////////////////////////////////////
@ -5450,7 +5450,7 @@ static v8::Handle<v8::Value> JS_CreateEdgeCollectionVocbase (v8::Arguments const
////////////////////////////////////////////////////////////////////////////////
static v8::Handle<v8::Value> JS_RemoveVocbase (v8::Arguments const& argv) {
return DeleteVocbaseCol(false, argv);
return RemoveVocbaseCol(false, argv);
}
////////////////////////////////////////////////////////////////////////////////

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

@ -4,6 +4,31 @@
## --SECTION-- JAVASCRIPT
## -----------------------------------------------------------------------------
################################################################################
### @brief files for jslint
################################################################################
JAVASCRIPT_JSLINT = \
@srcdir@/js/actions/system/api-collection.js \
@srcdir@/js/actions/system/api-structure.js
################################################################################
### @brief executes jslint
################################################################################
.PHONY: jslint
jslint:
@for file in $(JAVASCRIPT_JSLINT); do \
@builddir@/bin/arangosh \
-c none \
--log.level error \
--server.password "" \
--javascript.startup-directory @srcdir@/js \
--javascript.modules-path "@srcdir@/js/client/modules;@srcdir@/js/common/modules" \
--jslint $$file; \
done
################################################################################
### @brief sets up the directories
################################################################################
@ -14,7 +39,6 @@ BUILT_SOURCES += @builddir@/.setup-js-directories
@test -d html/admin/js/modules || mkdir -p html/admin/js/modules
@test -d js/common/bootstrap || mkdir -p js/common/bootstrap
@test -d js/client || mkdir -p js/client
@test -d js/server || mkdir -p js/server
@touch $@
################################################################################
@ -36,9 +60,6 @@ js/client/js-%.h: @srcdir@/js/client/%.js .setup-js-directories
js/common/bootstrap/js-%.h: @srcdir@/js/common/bootstrap/%.js .setup-js-directories
@top_srcdir@/config/js2c.sh $< > $@
js/server/js-%.h: @srcdir@/js/server/%.js .setup-js-directories
@top_srcdir@/config/js2c.sh $< > $@
################################################################################
### @brief cleanup
################################################################################

View File

@ -1,3 +1,13 @@
/*jslint indent: 2,
nomen: true,
maxlen: 100,
sloppy: true,
vars: true,
white: true,
plusplus: true,
stupid: true */
/*global require */
////////////////////////////////////////////////////////////////////////////////
/// @brief querying and managing collections
///
@ -25,9 +35,10 @@
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
(function() {
var actions = require("org/arangodb/actions");
var API = "_api/collection";
var arangodb = require("org/arangodb");
var actions = require("org/arangodb/actions");
var API = "_api/collection";
// -----------------------------------------------------------------------------
// --SECTION-- private functions
@ -42,38 +53,38 @@
/// @brief collection representation
////////////////////////////////////////////////////////////////////////////////
function CollectionRepresentation (collection, showProperties, showCount, showFigures) {
var result = {};
function collectionRepresentation (collection, showProperties, showCount, showFigures) {
var result = {};
result.id = collection._id;
result.name = collection.name();
result.id = collection._id;
result.name = collection.name();
if (showProperties) {
var properties = collection.properties();
if (showProperties) {
var properties = collection.properties();
result.waitForSync = properties.waitForSync;
result.journalSize = properties.journalSize;
result.createOptions = properties.createOptions;
}
if (showCount) {
result.count = collection.count();
}
if (showFigures) {
var figures = collection.figures();
if (figures) {
result.figures = figures;
}
}
result.status = collection.status();
result.type = collection.type();
return result;
result.waitForSync = properties.waitForSync;
result.journalSize = properties.journalSize;
result.createOptions = properties.createOptions;
}
if (showCount) {
result.count = collection.count();
}
if (showFigures) {
var figures = collection.figures();
if (figures) {
result.figures = figures;
}
}
result.status = collection.status();
result.type = collection.type();
return result;
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
@ -126,74 +137,74 @@
/// @verbinclude api-collection-create-collection
////////////////////////////////////////////////////////////////////////////////
function POST_api_collection (req, res) {
var body = actions.getJsonBody(req, res);
function post_api_collection (req, res) {
var body = actions.getJsonBody(req, res);
if (body === undefined) {
return;
}
if (! body.hasOwnProperty("name")) {
actions.resultBad(req, res, actions.ERROR_ARANGO_ILLEGAL_NAME,
"name must be non-empty");
return;
}
var name = body.name;
var parameter = { waitForSync : false };
var cid = undefined;
var type = ArangoCollection.TYPE_DOCUMENT;
if (body.hasOwnProperty("waitForSync")) {
parameter.waitForSync = body.waitForSync;
}
if (body.hasOwnProperty("journalSize")) {
parameter.journalSize = body.journalSize;
}
if (body.hasOwnProperty("isSystem")) {
parameter.isSystem = body.isSystem;
}
if (body.hasOwnProperty("_id")) {
cid = body._id;
}
if (body.hasOwnProperty("type")) {
type = body.type;
}
if (body.hasOwnProperty("createOptions")) {
parameter.createOptions = body.createOptions;
}
try {
var collection;
if (type == ArangoCollection.TYPE_EDGE) {
collection = internal.db._createEdgeCollection(name, parameter, cid);
}
else {
collection = internal.db._createDocumentCollection(name, parameter, cid);
}
var result = {};
var headers = {};
result.id = collection._id;
result.name = collection.name();
result.waitForSync = parameter.waitForSync;
result.status = collection.status();
result.type = collection.type();
result.createOptions = collection.createOptions;
actions.resultOk(req, res, actions.HTTP_OK, result);
}
catch (err) {
actions.resultException(req, res, err);
}
if (body === undefined) {
return;
}
if (! body.hasOwnProperty("name")) {
actions.resultBad(req, res, actions.ERROR_ARANGO_ILLEGAL_NAME,
"name must be non-empty");
return;
}
var name = body.name;
var parameter = { waitForSync : false };
var type = arangodb.ArangoCollection.TYPE_DOCUMENT;
var cid;
if (body.hasOwnProperty("waitForSync")) {
parameter.waitForSync = body.waitForSync;
}
if (body.hasOwnProperty("journalSize")) {
parameter.journalSize = body.journalSize;
}
if (body.hasOwnProperty("isSystem")) {
parameter.isSystem = body.isSystem;
}
if (body.hasOwnProperty("_id")) {
cid = body._id;
}
if (body.hasOwnProperty("type")) {
type = body.type;
}
if (body.hasOwnProperty("createOptions")) {
parameter.createOptions = body.createOptions;
}
try {
var collection;
if (type === arangodb.ArangoCollection.TYPE_EDGE) {
collection = arangodb.db._createEdgeCollection(name, parameter, cid);
}
else {
collection = arangodb.db._createDocumentCollection(name, parameter, cid);
}
var result = {};
result.id = collection._id;
result.name = collection.name();
result.waitForSync = parameter.waitForSync;
result.status = collection.status();
result.type = collection.type();
result.createOptions = collection.createOptions;
actions.resultOk(req, res, actions.HTTP_OK, result);
}
catch (err) {
actions.resultException(req, res, err);
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief returns all collections
///
@ -213,24 +224,25 @@
/// @verbinclude api-collection-all-collections
////////////////////////////////////////////////////////////////////////////////
function GET_api_collections (req, res) {
var list = [];
var names = {};
var collections = internal.db._collections();
function get_api_collections (req, res) {
var i;
var list = [];
var names = {};
var collections = arangodb.db._collections();
for (var i = 0; i < collections.length; ++i) {
var collection = collections[i];
var rep = CollectionRepresentation(collection);
for (i = 0; i < collections.length; ++i) {
var collection = collections[i];
var rep = collectionRepresentation(collection);
list.push(rep);
names[rep.name] = rep;
}
var result = { collections : list, names : names };
actions.resultOk(req, res, actions.HTTP_OK, result);
list.push(rep);
names[rep.name] = rep;
}
var result = { collections : list, names : names };
actions.resultOk(req, res, actions.HTTP_OK, result);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief returns a collection
///
@ -333,95 +345,98 @@
/// @verbinclude api-collection-get-collection-figures
////////////////////////////////////////////////////////////////////////////////
function GET_api_collection (req, res) {
// .............................................................................
// /_api/collection
// .............................................................................
if (req.suffix.length === 0 && req.parameters.id == undefined) {
GET_api_collections(req, res);
return;
}
// .............................................................................
// /_api/collection/<name>
// /_api/collection/<identifier>?useId
// .............................................................................
function get_api_collection (req, res) {
var name;
var result;
var sub;
var name;
if (req.parameters.useId || parseInt(req.suffix[0])) {
name = parseInt(req.suffix[0]);
}
else {
name = decodeURIComponent(req.suffix[0]);
}
// .............................................................................
// /_api/collection
// .............................................................................
var collection = internal.db._collection(name);
if (req.suffix.length === 0 && req.parameters.id == undefined) {
get_api_collections(req, res);
return;
}
// .............................................................................
// /_api/collection/<name>
// /_api/collection/<identifier>?useId
// .............................................................................
if (collection === null) {
actions.collectionNotFound(req, res, name);
return;
}
if (req.parameters.useId || parseInt(req.suffix[0],10)) {
name = parseInt(req.suffix[0],10);
}
else {
name = decodeURIComponent(req.suffix[0]);
}
var collection = internal.db._collection(name);
if (collection === null) {
actions.collectionNotFound(req, res, name);
return;
}
// .............................................................................
// /_api/collection/<name>
// .............................................................................
if (req.suffix.length === 1) {
var result = collectionRepresentation(collection, false, false, false);
actions.resultOk(req, res, actions.HTTP_OK, result);
}
else if (req.suffix.length === 2) {
sub = decodeURIComponent(req.suffix[1]);
// .............................................................................
// /_api/collection/<name>
// /_api/collection/<identifier>/figures
// .............................................................................
if (req.suffix.length === 1) {
var result = CollectionRepresentation(collection, false, false, false);
if (sub === "figures") {
result = collectionRepresentation(collection, true, true, true);
actions.resultOk(req, res, actions.HTTP_OK, result);
}
else if (req.suffix.length === 2) {
var sub = decodeURIComponent(req.suffix[1]);
// .............................................................................
// /_api/collection/<identifier>/count
// .............................................................................
// .............................................................................
// /_api/collection/<identifier>/figures
// .............................................................................
if (sub === "figures") {
var result = CollectionRepresentation(collection, true, true, true);
actions.resultOk(req, res, actions.HTTP_OK, result);
}
// .............................................................................
// /_api/collection/<identifier>/count
// .............................................................................
else if (sub === "count") {
var result = CollectionRepresentation(collection, true, true, false);
actions.resultOk(req, res, actions.HTTP_OK, result);
}
// .............................................................................
// /_api/collection/<identifier>/properties
// .............................................................................
else if (sub === "properties") {
var result = CollectionRepresentation(collection, true, false, false);
actions.resultOk(req, res, actions.HTTP_OK, result);
}
// .............................................................................
// /_api/collection/<identifier>/parameter (DEPRECATED)
// .............................................................................
else if (sub === "parameter") {
var result = CollectionRepresentation(collection, true, false, false);
actions.resultOk(req, res, actions.HTTP_OK, result);
}
else {
actions.resultNotFound(req, res, internal.errors.ERROR_HTTP_NOT_FOUND.code, "expecting one of the resources 'count', 'figures', 'properties', 'parameter'");
}
else if (sub === "count") {
result = collectionRepresentation(collection, true, true, false);
actions.resultOk(req, res, actions.HTTP_OK, result);
}
// .............................................................................
// /_api/collection/<identifier>/properties
// .............................................................................
else if (sub === "properties") {
result = collectionRepresentation(collection, true, false, false);
actions.resultOk(req, res, actions.HTTP_OK, result);
}
// .............................................................................
// /_api/collection/<identifier>/parameter (DEPRECATED)
// .............................................................................
else if (sub === "parameter") {
result = collectionRepresentation(collection, true, false, false);
actions.resultOk(req, res, actions.HTTP_OK, result);
}
else {
actions.resultBad(req, res, actions.ERROR_HTTP_BAD_PARAMETER,
"expect GET /" + API + "/<collection-name>/<method>");
actions.resultNotFound(req, res, actions.ERROR_HTTP_NOT_FOUND,
"expecting one of the resources 'count', 'figures', 'properties', 'parameter'");
}
}
else {
actions.resultBad(req, res, actions.ERROR_HTTP_BAD_PARAMETER,
"expect GET /" + API + "/<collection-name>/<method>");
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief loads a collection
@ -454,18 +469,18 @@
/// @verbinclude api-collection-identifier-load
////////////////////////////////////////////////////////////////////////////////
function PUT_api_collection_load (req, res, collection) {
try {
collection.load();
function put_api_collection_load (req, res, collection) {
try {
collection.load();
var result = CollectionRepresentation(collection, false, true, false);
var result = collectionRepresentation(collection, false, true, false);
actions.resultOk(req, res, actions.HTTP_OK, result);
}
catch (err) {
actions.resultException(req, res, err);
}
actions.resultOk(req, res, actions.HTTP_OK, result);
}
catch (err) {
actions.resultException(req, res, err);
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief unloads a collection
@ -498,18 +513,18 @@
/// @verbinclude api-collection-identifier-unload
////////////////////////////////////////////////////////////////////////////////
function PUT_api_collection_unload (req, res, collection) {
try {
collection.unload();
function put_api_collection_unload (req, res, collection) {
try {
collection.unload();
var result = CollectionRepresentation(collection);
var result = collectionRepresentation(collection);
actions.resultOk(req, res, actions.HTTP_OK, result);
}
catch (err) {
actions.resultException(req, res, err);
}
actions.resultOk(req, res, actions.HTTP_OK, result);
}
catch (err) {
actions.resultException(req, res, err);
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief truncates a collection
@ -525,18 +540,18 @@
/// @verbinclude api-collection-identifier-truncate
////////////////////////////////////////////////////////////////////////////////
function PUT_api_collection_truncate (req, res, collection) {
try {
collection.truncate();
function put_api_collection_truncate (req, res, collection) {
try {
collection.truncate();
var result = CollectionRepresentation(collection);
var result = collectionRepresentation(collection);
actions.resultOk(req, res, actions.HTTP_OK, result);
}
catch (err) {
actions.resultException(req, res, err);
}
actions.resultOk(req, res, actions.HTTP_OK, result);
}
catch (err) {
actions.resultException(req, res, err);
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief changes a collection
@ -575,25 +590,25 @@
/// @verbinclude api-collection-identifier-properties-sync
////////////////////////////////////////////////////////////////////////////////
function PUT_api_collection_properties (req, res, collection) {
var body = actions.getJsonBody(req, res);
function put_api_collection_properties (req, res, collection) {
var body = actions.getJsonBody(req, res);
if (body === undefined) {
return;
}
try {
collection.properties(body);
var result = CollectionRepresentation(collection, true);
actions.resultOk(req, res, actions.HTTP_OK, result);
}
catch (err) {
actions.resultException(req, res, err);
}
if (body === undefined) {
return;
}
try {
collection.properties(body);
var result = collectionRepresentation(collection, true);
actions.resultOk(req, res, actions.HTTP_OK, result);
}
catch (err) {
actions.resultException(req, res, err);
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief renames a collection
///
@ -622,74 +637,77 @@
/// @verbinclude api-collection-identifier-rename
////////////////////////////////////////////////////////////////////////////////
function PUT_api_collection_rename (req, res, collection) {
var body = actions.getJsonBody(req, res);
function put_api_collection_rename (req, res, collection) {
var body = actions.getJsonBody(req, res);
if (body === undefined) {
return;
}
if (! body.hasOwnProperty("name")) {
actions.resultBad(req, res, actions.ERROR_ARANGO_ILLEGAL_NAME,
"name must be non-empty");
return;
}
var name = body.name;
try {
collection.rename(name);
var result = CollectionRepresentation(collection);
actions.resultOk(req, res, actions.HTTP_OK, result);
}
catch (err) {
actions.resultException(req, res, err);
}
if (body === undefined) {
return;
}
if (! body.hasOwnProperty("name")) {
actions.resultBad(req, res, actions.ERROR_ARANGO_ILLEGAL_NAME,
"name must be non-empty");
return;
}
var name = body.name;
try {
collection.rename(name);
var result = collectionRepresentation(collection);
actions.resultOk(req, res, actions.HTTP_OK, result);
}
catch (err) {
actions.resultException(req, res, err);
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief changes a collection
////////////////////////////////////////////////////////////////////////////////
function PUT_api_collection (req, res) {
if (req.suffix.length != 2) {
actions.resultBad(req, res, actions.ERROR_HTTP_BAD_PARAMETER,
"expected PUT /" + API + "/<collection-name>/<action>");
return;
}
var name = decodeURIComponent(req.suffix[0]);
var collection = internal.db._collection(name);
if (collection === null) {
actions.collectionNotFound(req, res, name);
return;
}
var sub = decodeURIComponent(req.suffix[1]);
if (sub === "load") {
PUT_api_collection_load(req, res, collection);
}
else if (sub === "unload") {
PUT_api_collection_unload(req, res, collection);
}
else if (sub === "truncate") {
PUT_api_collection_truncate(req, res, collection);
}
else if (sub === "properties") {
PUT_api_collection_properties(req, res, collection);
}
else if (sub === "rename") {
PUT_api_collection_rename(req, res, collection);
}
else {
actions.resultNotFound(req, res, internal.errors.ERROR_HTTP_NOT_FOUND.code, "expecting one of the actions 'load', 'unload', 'truncate', 'properties', 'rename'");
}
function put_api_collection (req, res) {
if (req.suffix.length !== 2) {
actions.resultBad(req, res, actions.ERROR_HTTP_BAD_PARAMETER,
"expected PUT /" + API + "/<collection-name>/<action>");
return;
}
var name = decodeURIComponent(req.suffix[0]);
var collection = internal.db._collection(name);
if (collection === null) {
actions.collectionNotFound(req, res, name);
return;
}
var sub = decodeURIComponent(req.suffix[1]);
if (sub === "load") {
put_api_collection_load(req, res, collection);
}
else if (sub === "unload") {
put_api_collection_unload(req, res, collection);
}
else if (sub === "truncate") {
put_api_collection_truncate(req, res, collection);
}
else if (sub === "properties") {
put_api_collection_properties(req, res, collection);
}
else if (sub === "rename") {
put_api_collection_rename(req, res, collection);
}
else {
actions.resultNotFound(req,
res,
actions.errors.ERROR_HTTP_NOT_FOUND,
"expecting one of the actions 'load', 'unload', 'truncate', 'properties', 'rename'");
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief deletes a collection
///
@ -721,73 +739,71 @@
/// @verbinclude api-collection-delete-collection-name
////////////////////////////////////////////////////////////////////////////////
function DELETE_api_collection (req, res) {
if (req.suffix.length != 1) {
actions.resultBad(req, res, actions.ERROR_HTTP_BAD_PARAMETER,
"expected DELETE /" + API + "/<collection-name>");
function delete_api_collection (req, res) {
if (req.suffix.length !== 1) {
actions.resultBad(req, res, actions.ERROR_HTTP_BAD_PARAMETER,
"expected DELETE /" + API + "/<collection-name>");
}
else {
var name = decodeURIComponent(req.suffix[0]);
var collection = internal.db._collection(name);
if (collection === null) {
actions.collectionNotFound(req, res, name);
}
else {
var name = decodeURIComponent(req.suffix[0]);
var collection = internal.db._collection(name);
try {
var result = {
id : collection._id
};
if (collection === null) {
actions.collectionNotFound(req, res, name);
collection.drop();
actions.resultOk(req, res, actions.HTTP_OK, result);
}
else {
try {
var result = {
id : collection._id
};
collection.drop();
actions.resultOk(req, res, actions.HTTP_OK, result);
}
catch (err) {
actions.resultException(req, res, err);
}
catch (err) {
actions.resultException(req, res, err);
}
}
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief reads or creates a collection
/// @brief handles a collection request
////////////////////////////////////////////////////////////////////////////////
actions.defineHttp({
url : API,
context : "api",
actions.defineHttp({
url : API,
context : "api",
callback : function (req, res) {
try {
if (req.requestType === actions.GET) {
GET_api_collection(req, res);
}
else if (req.requestType === actions.DELETE) {
DELETE_api_collection(req, res);
}
else if (req.requestType === actions.POST) {
POST_api_collection(req, res);
}
else if (req.requestType === actions.PUT) {
PUT_api_collection(req, res);
}
else {
actions.resultUnsupported(req, res);
}
callback : function (req, res) {
try {
if (req.requestType === actions.GET) {
get_api_collection(req, res);
}
catch (err) {
actions.resultException(req, res, err);
else if (req.requestType === actions.DELETE) {
delete_api_collection(req, res);
}
else if (req.requestType === actions.POST) {
post_api_collection(req, res);
}
else if (req.requestType === actions.PUT) {
put_api_collection(req, res);
}
else {
actions.resultUnsupported(req, res);
}
}
});
catch (err) {
actions.resultException(req, res, err);
}
}
});
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
})();
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------

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

@ -72,9 +72,11 @@
"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_DOCUMENT_KEY_BAD" : { "code" : 1219, "message" : "illegal document key" },
"ERROR_ARANGO_DOCUMENT_KEY_UNEXPECTED" : { "code" : 1220, "message" : "unexpected document key" },
"ERROR_ARANGO_INDEX_NEEDS_RESIZE" : { "code" : 1221, "message" : "index needs resizing" },
"ERROR_ARANGO_VALIDATION_FAILED" : { "code" : 1219, "message" : "validator failed" },
"ERROR_ARANGO_PARSER_FAILED" : { "code" : 1220, "message" : "parser failed" },
"ERROR_ARANGO_DOCUMENT_KEY_BAD" : { "code" : 1221, "message" : "illegal document key" },
"ERROR_ARANGO_DOCUMENT_KEY_UNEXPECTED" : { "code" : 1222, "message" : "unexpected document key" },
"ERROR_ARANGO_INDEX_NEEDS_RESIZE" : { "code" : 1223, "message" : "index needs resizing" },
"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;
@ -385,6 +393,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
////////////////////////////////////////////////////////////////////////////////
@ -394,8 +416,6 @@ ModuleCache["/internal"] = new Module("/internal");
var mc;
var n;
var existsCache = ExistsCache;
// try to load the file
var paths = internal.MODULES_PATH;
@ -410,29 +430,32 @@ ModuleCache["/internal"] = new Module("/internal");
}
if (fs.exists(n)) {
existsCache[path] = true;
Module.prototype.ModuleExistsCache[path] = true;
return { path : n, content : internal.read(n) };
}
}
// try to load the module from the database
mc = internal.db._collection("_modules");
if (internal.db !== undefined) {
mc = internal.db._collection("_modules");
if (mc !== null && ("firstExample" in mc)) {
n = mc.firstExample({ path: path });
if (mc !== null && ("firstExample" in mc)) {
n = mc.firstExample({ path: path });
if (n !== null) {
if (n.hasOwnProperty('content')) {
existsCache[path] = true;
return { path : "_collection/" + path, content : n.content };
}
else {
require("console").error("found empty content in '%s'", JSON.stringify(n));
}
if (n !== null) {
if (n.hasOwnProperty('content')) {
Module.prototype.ModuleExistsCache[path] = true;
return { path : "_collection/" + path, content : n.content };
}
else {
require("console").error("found empty content in '%s'", JSON.stringify(n));
}
}
}
}
existsCache[path] = false;
Module.prototype.ModuleExistsCache[path] = false;
throw "cannot find a file named '"
+ path
+ "' using the module path(s) '"
@ -519,11 +542,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

@ -46,6 +46,8 @@ var internal = require("internal");
////////////////////////////////////////////////////////////////////////////////
exports.db = internal.db;
exports.ArangoCollection = internal.ArangoCollection;
exports.errors = internal.errors;
////////////////////////////////////////////////////////////////////////////////
/// @}

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

@ -59,6 +59,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;
}
@ -271,6 +272,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,9 +90,11 @@ 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_DOCUMENT_KEY_BAD,1219,"illegal document key","Will be raised when a document key is corrupt."
ERROR_ARANGO_DOCUMENT_KEY_UNEXPECTED,1220,"unexpected document key","Will be raised when a user-defined document key is supplied for collections with auto key generation."
ERROR_ARANGO_INDEX_NEEDS_RESIZE,1221,"index needs resizing","Will be raised when an index is full and should be resized to contain more data."
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."
ERROR_ARANGO_DOCUMENT_KEY_BAD,1221,"illegal document key","Will be raised when a document key is corrupt."
ERROR_ARANGO_DOCUMENT_KEY_UNEXPECTED,1222,"unexpected document key","Will be raised when a user-defined document key is supplied for collections with auto key generation."
ERROR_ARANGO_INDEX_NEEDS_RESIZE,1223,"index needs resizing","Will be raised when an index is full and should be resized to contain more data."
################################################################################
## ArangoDB storage errors

View File

@ -745,6 +745,7 @@ static void LogThread (char const* func,
if (m + len - 1 > 0) {
OutputMessage(level, severity, p, (size_t) (m + len), false);
}
return;
}
}

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_DOCUMENT_KEY_BAD, "illegal document key");
REG_ERROR(ERROR_ARANGO_DOCUMENT_KEY_UNEXPECTED, "unexpected document key");
REG_ERROR(ERROR_ARANGO_INDEX_NEEDS_RESIZE, "index needs resizing");

View File

@ -137,12 +137,16 @@ extern "C" {
/// status.
/// - 1218: @LIT{collection type invalid}
/// Will be raised when an invalid collection type is used in a request.
/// - 1219: @LIT{illegal document key}
/// - 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.
/// - 1221: @LIT{illegal document key}
/// Will be raised when a document key is corrupt.
/// - 1220: @LIT{unexpected document key}
/// - 1222: @LIT{unexpected document key}
/// Will be raised when a user-defined document key is supplied for
/// collections with auto key generation.
/// - 1221: @LIT{index needs resizing}
/// - 1223: @LIT{index needs resizing}
/// Will be raised when an index is full and should be resized to contain
/// more data.
/// - 1300: @LIT{datafile full}
@ -928,17 +932,37 @@ void TRI_InitialiseErrorMessages (void);
#define TRI_ERROR_ARANGO_COLLECTION_TYPE_INVALID (1218)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1219: ERROR_ARANGO_DOCUMENT_KEY_BAD
/// @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 1221: ERROR_ARANGO_DOCUMENT_KEY_BAD
///
/// illegal document key
///
/// Will be raised when a document key is corrupt.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_ARANGO_DOCUMENT_KEY_BAD (1219)
#define TRI_ERROR_ARANGO_DOCUMENT_KEY_BAD (1221)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1220: ERROR_ARANGO_DOCUMENT_KEY_UNEXPECTED
/// @brief 1222: ERROR_ARANGO_DOCUMENT_KEY_UNEXPECTED
///
/// unexpected document key
///
@ -946,10 +970,10 @@ void TRI_InitialiseErrorMessages (void);
/// with auto key generation.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_ARANGO_DOCUMENT_KEY_UNEXPECTED (1220)
#define TRI_ERROR_ARANGO_DOCUMENT_KEY_UNEXPECTED (1222)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1221: ERROR_ARANGO_INDEX_NEEDS_RESIZE
/// @brief 1223: ERROR_ARANGO_INDEX_NEEDS_RESIZE
///
/// index needs resizing
///
@ -957,7 +981,7 @@ void TRI_InitialiseErrorMessages (void);
/// data.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_ARANGO_INDEX_NEEDS_RESIZE (1221)
#define TRI_ERROR_ARANGO_INDEX_NEEDS_RESIZE (1223)
////////////////////////////////////////////////////////////////////////////////
/// @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
////////////////////////////////////////////////////////////////////////////////