mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'aql2' of github.com:triAGENS/ArangoDB into aql2
This commit is contained in:
commit
a5c031505b
10
CHANGELOG
10
CHANGELOG
|
@ -1,4 +1,12 @@
|
|||
v2.2.2-rc1 (XXXX-XX-XX)
|
||||
v2.3.0 (XXXX-XX-XX)
|
||||
-------------------
|
||||
|
||||
* automatically call `toJSON` function of JavaScript objects (if present)
|
||||
when serializing them into database documents. This change allows
|
||||
storing JavaScript date objects in the database in a sensible manner.
|
||||
|
||||
|
||||
v2.2.2 (2014-08-08)
|
||||
-------------------
|
||||
|
||||
* allow storing non-reserved attribute names starting with an underscore
|
||||
|
|
|
@ -125,7 +125,7 @@ will produce the following result:
|
|||
|
||||
!SUBSUBSECTION Operator precedence
|
||||
|
||||
The operator precedence in AQL is similar as in other familliar languages (lowest precedence first):
|
||||
The operator precedence in AQL is similar as in other familiar languages (lowest precedence first):
|
||||
|
||||
- *? :* ternary operator
|
||||
- *||* logical or
|
||||
|
@ -135,9 +135,9 @@ The operator precedence in AQL is similar as in other familliar languages (lowes
|
|||
- *<*, *<=*, *>=*, *>* less than, less equal,
|
||||
greater equal, greater than
|
||||
- *+*, *-* addition, subtraction
|
||||
- ***, */*, *%* multiplication, division, modulus
|
||||
- \*, */*, *%* multiplication, division, modulus
|
||||
- *!*, *+*, *-* logical negation, unary plus, unary minus
|
||||
- *[*]* expansion
|
||||
- *[\]* expansion
|
||||
- *()* function call
|
||||
- *.* member access
|
||||
- *[]* indexed value access
|
||||
|
|
|
@ -18,7 +18,7 @@ opaque strings when they store or use it locally.
|
|||
|
||||
!SUBSECTION Collection Name
|
||||
|
||||
A collection name identifies a collection in a database. It is a string and is unique within the database. Unlike the collection identifier it is supplied by the creator of the collection. The collection name must consist of letters, digits, and the _ (underscore) and - (dash) characters only. Please refer to @ref NamingConventions for more information on valid collection names.
|
||||
A collection name identifies a collection in a database. It is a string and is unique within the database. Unlike the collection identifier it is supplied by the creator of the collection. The collection name must consist of letters, digits, and the _ (underscore) and - (dash) characters only. Please refer to [NamingConventions](../NamingConventions/CollectionNames.html) for more information on valid collection names.
|
||||
|
||||
!SUBSECTION Database
|
||||
|
||||
|
@ -28,7 +28,7 @@ A database contains its own collections (which cannot be accessed from other dat
|
|||
|
||||
There will always be at least one database in ArangoDB. This is the default database, named _system. This database cannot be dropped, and provides special operations for creating, dropping, and enumerating databases. Users can create additional databases and give them unique names to access them later. Database management operations cannot be initiated from out of user-defined databases.
|
||||
|
||||
When ArangoDB is accessed via its HTTP REST API, the database name is read from the first part of the request URI path (e.g. /_db/_system/...). If the request URI does not contain a database name, the database name is automatically determined by the algorithm described in @ref HttpDatabaseMapping.
|
||||
When ArangoDB is accessed via its HTTP REST API, the database name is read from the first part of the request URI path (e.g. /_db/_system/...). If the request URI does not contain a database name, the database name is automatically.
|
||||
|
||||
!SUBSECTION Database Name
|
||||
|
||||
|
|
|
@ -51,26 +51,11 @@ RestActionHandler::RestActionHandler (HttpRequest* request,
|
|||
: RestVocbaseBaseHandler(request),
|
||||
_action(0),
|
||||
_queue(),
|
||||
_allowed(false),
|
||||
_dataLock(),
|
||||
_data(0) {
|
||||
|
||||
_action = TRI_LookupActionVocBase(request);
|
||||
|
||||
// check if the action is allowed
|
||||
if (_action != 0) {
|
||||
for (set<string>::const_iterator i = data->_contexts.begin(); i != data->_contexts.end(); ++i) {
|
||||
if (_action->_contexts.find(*i) != _action->_contexts.end()) {
|
||||
_allowed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (! _allowed) {
|
||||
_action = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// use the queue from options if an action is known
|
||||
if (_action != 0) {
|
||||
_queue = data->_queue;
|
||||
|
@ -121,11 +106,6 @@ HttpHandler::status_t RestActionHandler::execute () {
|
|||
generateNotImplemented(_request->requestPath());
|
||||
}
|
||||
|
||||
// need permission
|
||||
else if (! _allowed) {
|
||||
generateForbidden();
|
||||
}
|
||||
|
||||
// execute
|
||||
else {
|
||||
|
||||
|
|
|
@ -68,7 +68,6 @@ namespace triagens {
|
|||
struct action_options_t {
|
||||
TRI_vocbase_t* _vocbase;
|
||||
std::string _queue;
|
||||
std::set<std::string> _contexts;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -145,12 +144,6 @@ namespace triagens {
|
|||
|
||||
std::string _queue;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief action allowed in this context
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool _allowed;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief data lock
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -84,8 +84,12 @@ class TRI_action_result_t {
|
|||
|
||||
class TRI_action_t {
|
||||
public:
|
||||
TRI_action_t (std::set<std::string> const& context)
|
||||
: _type(), _url(), _isPrefix(false), _urlParts(0), _contexts(context) {
|
||||
TRI_action_t ()
|
||||
: _type(),
|
||||
_url(),
|
||||
_urlParts(0),
|
||||
_isPrefix(false),
|
||||
_allowUseDatabase(false) {
|
||||
}
|
||||
|
||||
virtual ~TRI_action_t () {}
|
||||
|
@ -100,10 +104,11 @@ class TRI_action_t {
|
|||
|
||||
std::string _type;
|
||||
std::string _url;
|
||||
bool _isPrefix;
|
||||
|
||||
size_t _urlParts;
|
||||
std::set<std::string> _contexts;
|
||||
|
||||
bool _isPrefix;
|
||||
bool _allowUseDatabase;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -110,14 +110,14 @@ extern int Ahuacatldebug;
|
|||
typedef union YYSTYPE YYSTYPE;
|
||||
union YYSTYPE
|
||||
{
|
||||
#line 26 "arangod/Ahuacatl/ahuacatl-grammar.y" /* yacc.c:1909 */
|
||||
#line 26 "arangod/Ahuacatl/ahuacatl-grammar.y" /* yacc.c:1915 */
|
||||
|
||||
TRI_aql_node_t* node;
|
||||
char* strval;
|
||||
bool boolval;
|
||||
int64_t intval;
|
||||
|
||||
#line 121 "arangod/Ahuacatl/ahuacatl-grammar.hpp" /* yacc.c:1909 */
|
||||
#line 121 "arangod/Ahuacatl/ahuacatl-grammar.hpp" /* yacc.c:1915 */
|
||||
};
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
|
|
|
@ -215,7 +215,8 @@ v8::Handle<v8::Value> AqlValue::toV8 (AQL_TRANSACTION_V8* trx,
|
|||
/// @brief toString method
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::string AqlValue::toString (TRI_document_collection_t const* document) const {
|
||||
std::string AqlValue::toString (AQL_TRANSACTION_V8* trx,
|
||||
TRI_document_collection_t const* document) const {
|
||||
switch (_type) {
|
||||
case JSON: {
|
||||
return _json->toString();
|
||||
|
@ -224,7 +225,7 @@ std::string AqlValue::toString (TRI_document_collection_t const* document) const
|
|||
case SHAPED: {
|
||||
// we're lazy and just stringify the json representation
|
||||
// this does not matter as this code is not performance-sensitive
|
||||
return toJson(document).toString();
|
||||
return toJson(trx, document).toString();
|
||||
}
|
||||
|
||||
case DOCVEC: {
|
||||
|
@ -252,7 +253,8 @@ std::string AqlValue::toString (TRI_document_collection_t const* document) const
|
|||
/// @brief toJson method
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Json AqlValue::toJson (TRI_document_collection_t const* document) const {
|
||||
Json AqlValue::toJson (AQL_TRANSACTION_V8* trx,
|
||||
TRI_document_collection_t const* document) const {
|
||||
switch (_type) {
|
||||
case JSON: {
|
||||
return _json->copy();
|
||||
|
@ -265,16 +267,32 @@ Json AqlValue::toJson (TRI_document_collection_t const* document) const {
|
|||
TRI_shaper_t* shaper = document->getShaper();
|
||||
TRI_shaped_json_t shaped;
|
||||
TRI_EXTRACT_SHAPED_JSON_MARKER(shaped, _marker);
|
||||
triagens::basics::Json json(shaper->_memoryZone, TRI_JsonShapedJson(shaper, &shaped));
|
||||
Json json(shaper->_memoryZone, TRI_JsonShapedJson(shaper, &shaped));
|
||||
|
||||
// append the internal attributes
|
||||
|
||||
// _id, _key, _rev
|
||||
char const* key = TRI_EXTRACT_MARKER_KEY(_marker);
|
||||
// TODO: use CollectionNameResolver
|
||||
std::string id(document->_info._name);
|
||||
std::string id(trx->resolver()->getCollectionName(document->_info._cid));
|
||||
id.push_back('/');
|
||||
id += std::string(key);
|
||||
json("_id", triagens::basics::Json(id));
|
||||
json("_rev", triagens::basics::Json(std::to_string(TRI_EXTRACT_MARKER_RID(_marker) )));
|
||||
json("_key", triagens::basics::Json(key));
|
||||
id.append(key);
|
||||
json("_id", Json(id));
|
||||
json("_rev", Json(std::to_string(TRI_EXTRACT_MARKER_RID(_marker))));
|
||||
json("_key", Json(key));
|
||||
|
||||
if (TRI_IS_EDGE_MARKER(_marker)) {
|
||||
// _from
|
||||
std::string from(trx->resolver()->getCollectionName(TRI_EXTRACT_MARKER_FROM_CID(_marker)));
|
||||
from.push_back('/');
|
||||
from.append(TRI_EXTRACT_MARKER_FROM_KEY(_marker));
|
||||
json("_from", Json(from));
|
||||
|
||||
// _to
|
||||
std::string to(trx->resolver()->getCollectionName(TRI_EXTRACT_MARKER_TO_CID(_marker)));
|
||||
to.push_back('/');
|
||||
to.append(TRI_EXTRACT_MARKER_TO_KEY(_marker));
|
||||
json("_to", Json(to));
|
||||
}
|
||||
|
||||
// TODO: return _from and _to, and fix order of attributes!
|
||||
return json;
|
||||
|
@ -297,7 +315,7 @@ Json AqlValue::toJson (TRI_document_collection_t const* document) const {
|
|||
size_t const n = current->size();
|
||||
auto vecCollection = current->getDocumentCollection(0);
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
json.add(current->getValue(i, 0).toJson(vecCollection));
|
||||
json.add(current->getValue(i, 0).toJson(trx, vecCollection));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -331,7 +349,8 @@ Json AqlValue::toJson (TRI_document_collection_t const* document) const {
|
|||
/// @brief create an AqlValue from a vector of AqlItemBlock*s
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlValue AqlValue::CreateFromBlocks (std::vector<AqlItemBlock*> const& src,
|
||||
AqlValue AqlValue::CreateFromBlocks (AQL_TRANSACTION_V8* trx,
|
||||
std::vector<AqlItemBlock*> const& src,
|
||||
std::vector<std::string> const& variableNames) {
|
||||
size_t totalSize = 0;
|
||||
|
||||
|
@ -352,7 +371,7 @@ AqlValue AqlValue::CreateFromBlocks (std::vector<AqlItemBlock*> const& src,
|
|||
for (RegisterId j = 0; j < n; ++j) {
|
||||
if (variableNames[j][0] != '\0') {
|
||||
// temporaries don't have a name and won't be included
|
||||
values.set(variableNames[j].c_str(), current->getValue(i, j).toJson(current->getDocumentCollection(j)));
|
||||
values.set(variableNames[j].c_str(), current->getValue(i, j).toJson(trx, current->getDocumentCollection(j)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -372,7 +391,8 @@ AqlValue AqlValue::CreateFromBlocks (std::vector<AqlItemBlock*> const& src,
|
|||
/// @brief 3-way comparison for AqlValue objects
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int AqlValue::Compare (AqlValue const& left,
|
||||
int AqlValue::Compare (AQL_TRANSACTION_V8* trx,
|
||||
AqlValue const& left,
|
||||
TRI_document_collection_t const* leftcoll,
|
||||
AqlValue const& right,
|
||||
TRI_document_collection_t const* rightcoll) {
|
||||
|
@ -386,12 +406,12 @@ int AqlValue::Compare (AqlValue const& left,
|
|||
}
|
||||
|
||||
if (left._type == AqlValue::JSON && right._type == AqlValue::SHAPED) {
|
||||
triagens::basics::Json rjson = right.toJson(rightcoll);
|
||||
triagens::basics::Json rjson = right.toJson(trx, rightcoll);
|
||||
return TRI_CompareValuesJson(left._json->json(), rjson.json(), true);
|
||||
}
|
||||
|
||||
if (left._type == AqlValue::SHAPED && right._type == AqlValue::JSON) {
|
||||
triagens::basics::Json ljson = left.toJson(leftcoll);
|
||||
triagens::basics::Json ljson = left.toJson(trx, leftcoll);
|
||||
return TRI_CompareValuesJson(ljson.json(), right._json->json(), true);
|
||||
}
|
||||
|
||||
|
@ -432,7 +452,8 @@ int AqlValue::Compare (AqlValue const& left,
|
|||
rblock < right._vector->size()) {
|
||||
AqlValue lval = left._vector->at(lblock)->getValue(litem, 0);
|
||||
AqlValue rval = right._vector->at(rblock)->getValue(ritem, 0);
|
||||
int cmp = Compare(lval,
|
||||
int cmp = Compare(trx,
|
||||
lval,
|
||||
left._vector->at(lblock)->getDocumentCollection(0),
|
||||
rval,
|
||||
right._vector->at(rblock)->getDocumentCollection(0));
|
||||
|
|
|
@ -154,36 +154,40 @@ namespace triagens {
|
|||
/// @brief construct a V8 value as input for the expression execution in V8
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
v8::Handle<v8::Value> toV8 (AQL_TRANSACTION_V8* trx,
|
||||
v8::Handle<v8::Value> toV8 (AQL_TRANSACTION_V8*,
|
||||
TRI_document_collection_t const*) const;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief toString method
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::string toString (TRI_document_collection_t const*) const;
|
||||
std::string toString (AQL_TRANSACTION_V8*,
|
||||
TRI_document_collection_t const*) const;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief toJson method
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
triagens::basics::Json toJson (TRI_document_collection_t const*) const;
|
||||
triagens::basics::Json toJson (AQL_TRANSACTION_V8*,
|
||||
TRI_document_collection_t const*) const;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AqlValue from a vector of AqlItemBlock*s
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static AqlValue CreateFromBlocks (std::vector<AqlItemBlock*> const&,
|
||||
static AqlValue CreateFromBlocks (AQL_TRANSACTION_V8*,
|
||||
std::vector<AqlItemBlock*> const&,
|
||||
std::vector<std::string> const&);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief 3-way comparison for AqlValue objects
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int Compare (AqlValue const& left,
|
||||
TRI_document_collection_t const* leftcoll,
|
||||
AqlValue const& right,
|
||||
TRI_document_collection_t const* rightcoll);
|
||||
static int Compare (AQL_TRANSACTION_V8*,
|
||||
AqlValue const&,
|
||||
TRI_document_collection_t const*,
|
||||
AqlValue const&,
|
||||
TRI_document_collection_t const*);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public variables
|
||||
|
|
|
@ -60,14 +60,18 @@ ExecutionBlock::~ExecutionBlock () {
|
|||
// --SECTION-- public methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
int ExecutionBlock::bind (AqlItemBlock* items, size_t pos) {
|
||||
int res;
|
||||
int ExecutionBlock::initCursor (AqlItemBlock* items, size_t pos) {
|
||||
for (auto d : _dependencies) {
|
||||
res = d->bind(items, pos);
|
||||
int res = d->initCursor(items, pos);
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
for (auto x : _buffer) {
|
||||
delete x;
|
||||
}
|
||||
_buffer.clear();
|
||||
_done = false;
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
|
|
|
@ -392,26 +392,28 @@ namespace triagens {
|
|||
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Methods for execution
|
||||
/// Lifecycle is:
|
||||
/// CONSTRUCTOR
|
||||
/// then the ExecutionEngine automatically calls
|
||||
/// staticAnalysis() once, including subqueries
|
||||
/// then the ExecutionEngine automatically calls
|
||||
/// initialize() once, including subqueries
|
||||
/// possibly repeat many times:
|
||||
/// initCursor(...) (optionally with bind parameters)
|
||||
/// // use cursor functionality
|
||||
/// then the ExecutionEngine automatically calls
|
||||
/// shutdown()
|
||||
/// DESTRUCTOR
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief static analysis
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void staticAnalysis (ExecutionBlock* super = nullptr);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Methods for execution
|
||||
/// Lifecycle is:
|
||||
/// staticAnalysis()
|
||||
/// initialize()
|
||||
/// possibly repeat many times:
|
||||
/// bind(...)
|
||||
/// execute(...)
|
||||
/// // use cursor functionality
|
||||
/// shutdown()
|
||||
/// It should be possible to perform the sequence from initialize to shutdown
|
||||
/// multiple times.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief initialize
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -428,28 +430,13 @@ namespace triagens {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief bind
|
||||
/// @brief initCursor, could be called multiple times
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
virtual int bind (AqlItemBlock* items, size_t pos);
|
||||
virtual int initCursor (AqlItemBlock* items, size_t pos);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief execute
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
virtual int execute () {
|
||||
for (auto it = _dependencies.begin(); it != _dependencies.end(); ++it) {
|
||||
int res = (*it)->execute();
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
_done = false;
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief shutdown
|
||||
/// @brief shutdown, will be called exactly once for the whole query
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
virtual int shutdown () {
|
||||
|
@ -468,13 +455,13 @@ namespace triagens {
|
|||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief copy register data from one block (src) into another (dst)
|
||||
/// register values are cloned
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
protected:
|
||||
|
||||
void inheritRegisters (AqlItemBlock const* src,
|
||||
AqlItemBlock* dst,
|
||||
size_t row) {
|
||||
|
@ -816,15 +803,18 @@ namespace triagens {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief bind, store a copy of the register values coming from above
|
||||
/// @brief initCursor, store a copy of the register values coming from above
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int bind (AqlItemBlock* items, size_t pos) {
|
||||
int initCursor (AqlItemBlock* items, size_t pos) {
|
||||
// Create a deep copy of the register values given to us:
|
||||
if (_inputRegisterValues != nullptr) {
|
||||
delete _inputRegisterValues;
|
||||
}
|
||||
_inputRegisterValues = items->slice(pos, pos+1);
|
||||
if (items != nullptr) {
|
||||
_inputRegisterValues = items->slice(pos, pos+1);
|
||||
}
|
||||
_done = false;
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
|
@ -1027,22 +1017,21 @@ namespace triagens {
|
|||
std::string collectionName(p->_collname);
|
||||
collectionName.push_back('/');
|
||||
|
||||
initDocuments();
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief execute, here we release our docs from this collection
|
||||
/// @brief initCursor, here we release our docs from this collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int execute () {
|
||||
int res = ExecutionBlock::execute();
|
||||
|
||||
int initCursor (AqlItemBlock* items, size_t pos) {
|
||||
int res = ExecutionBlock::initCursor(items, pos);
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
return res;
|
||||
}
|
||||
|
||||
initDocuments();
|
||||
|
||||
if (_totalCount == 0) {
|
||||
_done = true;
|
||||
}
|
||||
|
@ -1050,16 +1039,6 @@ namespace triagens {
|
|||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief shutdown, here we release our docs from this collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int shutdown () {
|
||||
int res = ExecutionBlock::shutdown(); // Tell all dependencies
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief getSome
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1274,8 +1253,8 @@ namespace triagens {
|
|||
/// @brief execute, here we release our docs from this collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int execute () {
|
||||
int res = ExecutionBlock::execute();
|
||||
int initCursor (AqlItemBlock* items, size_t pos) {
|
||||
int res = ExecutionBlock::initCursor(items, pos);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
return res;
|
||||
|
@ -1786,7 +1765,7 @@ namespace triagens {
|
|||
TRI_ASSERT(it3 != _varOverview->varInfo.end());
|
||||
_outReg = it3->second.registerId;
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
return getSubquery()->initialize();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1802,14 +1781,7 @@ namespace triagens {
|
|||
}
|
||||
|
||||
for (size_t i = 0; i < res->size(); i++) {
|
||||
int ret;
|
||||
ret = _subquery->initialize();
|
||||
if (ret == TRI_ERROR_NO_ERROR) {
|
||||
ret = _subquery->bind(res.get(), i);
|
||||
}
|
||||
if (ret == TRI_ERROR_NO_ERROR) {
|
||||
ret = _subquery->execute();
|
||||
}
|
||||
int ret = _subquery->initCursor(res.get(), i);
|
||||
if (ret != TRI_ERROR_NO_ERROR) {
|
||||
THROW_ARANGO_EXCEPTION(ret);
|
||||
}
|
||||
|
@ -1834,12 +1806,6 @@ namespace triagens {
|
|||
delete results;
|
||||
throw;
|
||||
}
|
||||
|
||||
ret = _subquery->shutdown();
|
||||
if (ret != TRI_ERROR_NO_ERROR) {
|
||||
THROW_ARANGO_EXCEPTION(ret);
|
||||
}
|
||||
|
||||
}
|
||||
return res.release();
|
||||
}
|
||||
|
@ -2241,7 +2207,8 @@ namespace triagens {
|
|||
size_t i = 0;
|
||||
|
||||
for (auto it = _aggregateRegisters.begin(); it != _aggregateRegisters.end(); ++it) {
|
||||
int cmp = AqlValue::Compare(_currentGroup.groupValues[i],
|
||||
int cmp = AqlValue::Compare(_trx,
|
||||
_currentGroup.groupValues[i],
|
||||
_currentGroup.collections[i],
|
||||
cur->getValue(_pos, (*it).second),
|
||||
cur->getDocumentCollection((*it).second));
|
||||
|
@ -2363,7 +2330,7 @@ namespace triagens {
|
|||
_currentGroup.addValues(cur, _groupRegister);
|
||||
|
||||
res->setValue(row, _groupRegister,
|
||||
AqlValue::CreateFromBlocks(_currentGroup.groupBlocks, _variableNames));
|
||||
AqlValue::CreateFromBlocks(_trx, _currentGroup.groupBlocks, _variableNames));
|
||||
// FIXME: can throw:
|
||||
}
|
||||
|
||||
|
@ -2450,11 +2417,11 @@ namespace triagens {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief execute
|
||||
/// @brief initCursor
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
virtual int execute () {
|
||||
int res = ExecutionBlock::execute();
|
||||
virtual int initCursor (AqlItemBlock* items, size_t pos) {
|
||||
int res = ExecutionBlock::initCursor(items, pos);
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
return res;
|
||||
}
|
||||
|
@ -2467,6 +2434,21 @@ namespace triagens {
|
|||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
doSorting();
|
||||
|
||||
_done = false;
|
||||
_pos = 0;
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief dosorting
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private:
|
||||
|
||||
void doSorting () {
|
||||
// coords[i][j] is the <j>th row of the <i>th block
|
||||
std::vector<std::pair<size_t, size_t>> coords;
|
||||
|
||||
|
@ -2493,7 +2475,7 @@ namespace triagens {
|
|||
}
|
||||
|
||||
// comparison function
|
||||
OurLessThan ourLessThan(_buffer, _sortRegisters, colls);
|
||||
OurLessThan ourLessThan(_trx, _buffer, _sortRegisters, colls);
|
||||
|
||||
// sort coords
|
||||
if (_stable) {
|
||||
|
@ -2612,25 +2594,21 @@ namespace triagens {
|
|||
for (auto x : newbuffer) {
|
||||
delete x;
|
||||
}
|
||||
|
||||
_done = false;
|
||||
_pos = 0;
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief OurLessThan
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class OurLessThan {
|
||||
public:
|
||||
OurLessThan (std::deque<AqlItemBlock*>& buffer,
|
||||
OurLessThan (AQL_TRANSACTION_V8* trx,
|
||||
std::deque<AqlItemBlock*>& buffer,
|
||||
std::vector<std::pair<RegisterId, bool>>& sortRegisters,
|
||||
std::vector<TRI_document_collection_t const*>& colls)
|
||||
: _buffer(buffer),
|
||||
: _trx(trx),
|
||||
_buffer(buffer),
|
||||
_sortRegisters(sortRegisters),
|
||||
_colls(colls) {
|
||||
}
|
||||
|
@ -2640,7 +2618,8 @@ namespace triagens {
|
|||
|
||||
size_t i = 0;
|
||||
for (auto reg : _sortRegisters) {
|
||||
int cmp = AqlValue::Compare(_buffer[a.first]->getValue(a.second, reg.first),
|
||||
int cmp = AqlValue::Compare(_trx,
|
||||
_buffer[a.first]->getValue(a.second, reg.first),
|
||||
_colls[i],
|
||||
_buffer[b.first]->getValue(b.second, reg.first),
|
||||
_colls[i]);
|
||||
|
@ -2657,6 +2636,7 @@ namespace triagens {
|
|||
}
|
||||
|
||||
private:
|
||||
AQL_TRANSACTION_V8* _trx;
|
||||
std::deque<AqlItemBlock*>& _buffer;
|
||||
std::vector<std::pair<RegisterId, bool>>& _sortRegisters;
|
||||
std::vector<TRI_document_collection_t const*>& _colls;
|
||||
|
@ -2710,18 +2690,33 @@ namespace triagens {
|
|||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
return res;
|
||||
}
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief initCursor
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int initCursor (AqlItemBlock* items, size_t pos) {
|
||||
int res = ExecutionBlock::initCursor(items, pos);
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
return res;
|
||||
}
|
||||
_state = 0;
|
||||
_count = 0;
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief getSome
|
||||
/// @brief getOrSkipSome
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
virtual size_t skipSome (size_t atLeast, size_t atMost) {
|
||||
virtual int getOrSkipSome (size_t atLeast, size_t atMost, bool skipping,
|
||||
AqlItemBlock*& result, size_t& skipped) {
|
||||
TRI_ASSERT(result == nullptr && skipped == 0);
|
||||
|
||||
if (_state == 2) {
|
||||
return 0;
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
if (_state == 0) {
|
||||
|
@ -2732,7 +2727,7 @@ namespace triagens {
|
|||
_count = 0;
|
||||
if (_limit == 0) {
|
||||
_state = 2;
|
||||
return 0;
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2745,55 +2740,16 @@ namespace triagens {
|
|||
}
|
||||
}
|
||||
|
||||
size_t skipped = ExecutionBlock::skipSome(atLeast, atMost);
|
||||
ExecutionBlock::getOrSkipSome(atLeast, atMost, skipping, result, skipped);
|
||||
if (skipped == 0) {
|
||||
return 0;
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
_count += skipped;
|
||||
if (_count >= _limit) {
|
||||
_state = 2;
|
||||
}
|
||||
|
||||
return skipped;
|
||||
}
|
||||
|
||||
virtual AqlItemBlock* getSome (size_t atLeast,
|
||||
size_t atMost) {
|
||||
if (_state == 2) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (_state == 0) {
|
||||
if (_offset > 0) {
|
||||
ExecutionBlock::_dependencies[0]->skip(_offset);
|
||||
}
|
||||
_state = 1;
|
||||
_count = 0;
|
||||
if (_limit == 0) {
|
||||
_state = 2;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// If we get to here, _state == 1 and _count < _limit
|
||||
|
||||
if (atMost > _limit - _count) {
|
||||
atMost = _limit - _count;
|
||||
if (atLeast > atMost) {
|
||||
atLeast = atMost;
|
||||
}
|
||||
}
|
||||
|
||||
auto res = ExecutionBlock::getSome(atLeast, atMost);
|
||||
if (res == nullptr) {
|
||||
return res;
|
||||
}
|
||||
_count += res->size();
|
||||
if (_count >= _limit) {
|
||||
_state = 2;
|
||||
}
|
||||
|
||||
return res;
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -172,17 +172,18 @@ struct Instanciator : public WalkerWorker {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExecutionEngine* ExecutionEngine::instanciateFromPlan (AQL_TRANSACTION_V8* trx,
|
||||
ExecutionNode* plan) {
|
||||
ExecutionPlan* plan) {
|
||||
auto engine = new ExecutionEngine(trx);
|
||||
|
||||
try {
|
||||
auto inst = new Instanciator(engine);
|
||||
plan->walk(inst);
|
||||
plan->root()->walk(inst);
|
||||
auto root = inst->root;
|
||||
delete inst;
|
||||
|
||||
root->staticAnalysis();
|
||||
root->initialize();
|
||||
root->initCursor(nullptr, 0);
|
||||
|
||||
engine->_root = root;
|
||||
|
||||
|
|
|
@ -32,14 +32,14 @@
|
|||
|
||||
#include "Basics/Common.h"
|
||||
|
||||
#include "arangod/Aql/AqlItemBlock.h"
|
||||
#include "arangod/Aql/ExecutionBlock.h"
|
||||
#include "arangod/Aql/ExecutionPlan.h"
|
||||
#include "Utils/AqlTransaction.h"
|
||||
|
||||
namespace triagens {
|
||||
namespace aql {
|
||||
|
||||
class ExecutionBlock;
|
||||
class ExecutionNode;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- class ExecutionEngine
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -73,11 +73,11 @@ namespace triagens {
|
|||
public:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an execution engine from a plan
|
||||
// @brief create an execution engine from a plan
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static ExecutionEngine* instanciateFromPlan (AQL_TRANSACTION_V8*,
|
||||
ExecutionNode*);
|
||||
ExecutionPlan*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief get the root block
|
||||
|
@ -96,6 +96,54 @@ namespace triagens {
|
|||
return _trx;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief getSome
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlItemBlock* getSome (size_t atLeast, size_t atMost) {
|
||||
return _root->getSome(atLeast, atMost);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief getOne
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlItemBlock* getOne () {
|
||||
return _root->getSome(1, 1);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief skip
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool skip (size_t number) {
|
||||
return _root->skip(number);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief hasMore
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool hasMore () {
|
||||
return _root->hasMore();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief count
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int64_t count () {
|
||||
return _root->count();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief remaining
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int64_t remaining () {
|
||||
return _root->remaining();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief add a block to the engine
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -188,18 +188,33 @@ AqlValue Expression::executeSimpleExpression (AstNode const* node,
|
|||
auto shaper = myCollection->getShaper();
|
||||
|
||||
// look for the attribute name in the shape
|
||||
if (strcmp(name, "_key") == 0) {
|
||||
return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, TRI_EXTRACT_MARKER_KEY(result._marker)));
|
||||
}
|
||||
else if (strcmp(name, "_id") == 0) {
|
||||
std::string id(myCollection->_info._name);
|
||||
id.push_back('/');
|
||||
id.append(TRI_EXTRACT_MARKER_KEY(result._marker));
|
||||
return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, id));
|
||||
}
|
||||
else if (strcmp(name, "_rev") == 0) {
|
||||
TRI_voc_rid_t rid = TRI_EXTRACT_MARKER_RID(result._marker);
|
||||
return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, JsonHelper::uint64String(TRI_UNKNOWN_MEM_ZONE, rid)));
|
||||
if (*name == '_') {
|
||||
if (strcmp(name, "_key") == 0) {
|
||||
// _key value is copied into JSON
|
||||
return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, TRI_EXTRACT_MARKER_KEY(result._marker)));
|
||||
}
|
||||
else if (strcmp(name, "_id") == 0) {
|
||||
std::string id(trx->resolver()->getCollectionName(myCollection->_info._cid));
|
||||
id.push_back('/');
|
||||
id.append(TRI_EXTRACT_MARKER_KEY(result._marker));
|
||||
return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, id));
|
||||
}
|
||||
else if (strcmp(name, "_rev") == 0) {
|
||||
TRI_voc_rid_t rid = TRI_EXTRACT_MARKER_RID(result._marker);
|
||||
return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, JsonHelper::uint64String(TRI_UNKNOWN_MEM_ZONE, rid)));
|
||||
}
|
||||
else if (strcmp(name, "_from") == 0) {
|
||||
std::string from(trx->resolver()->getCollectionName(TRI_EXTRACT_MARKER_FROM_CID(result._marker)));
|
||||
from.push_back('/');
|
||||
from.append(TRI_EXTRACT_MARKER_FROM_KEY(result._marker));
|
||||
return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, from));
|
||||
}
|
||||
else if (strcmp(name, "_to") == 0) {
|
||||
std::string to(trx->resolver()->getCollectionName(TRI_EXTRACT_MARKER_TO_CID(result._marker)));
|
||||
to.push_back('/');
|
||||
to.append(TRI_EXTRACT_MARKER_TO_KEY(result._marker));
|
||||
return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, to));
|
||||
}
|
||||
}
|
||||
|
||||
TRI_shape_pid_t pid = shaper->lookupAttributePathByName(shaper, name);
|
||||
|
@ -247,7 +262,7 @@ AqlValue Expression::executeSimpleExpression (AstNode const* node,
|
|||
TRI_document_collection_t const* myCollection = nullptr;
|
||||
|
||||
AqlValue result = executeSimpleExpression(member, &myCollection, trx, docColls, argv, startPos, vars, regs);
|
||||
list->add(result.toJson(myCollection));
|
||||
list->add(result.toJson(trx, myCollection));
|
||||
}
|
||||
return AqlValue(list);
|
||||
}
|
||||
|
@ -257,7 +272,6 @@ AqlValue Expression::executeSimpleExpression (AstNode const* node,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
else if (node->type == NODE_TYPE_REFERENCE) {
|
||||
auto v = static_cast<Variable*>(node->getData());
|
||||
|
||||
|
|
|
@ -195,22 +195,19 @@ QueryResult Query::execute () {
|
|||
triagens::basics::Json json(triagens::basics::Json::List);
|
||||
|
||||
try {
|
||||
auto engine = ExecutionEngine::instanciateFromPlan(&trx, plan->root());
|
||||
auto engine = ExecutionEngine::instanciateFromPlan(&trx, plan);
|
||||
|
||||
try {
|
||||
auto root = engine->root();
|
||||
root->execute();
|
||||
|
||||
AqlItemBlock* value;
|
||||
|
||||
while (nullptr != (value = root->getSome(1, ExecutionBlock::DefaultBatchSize))) {
|
||||
while (nullptr != (value = engine->getSome(1, ExecutionBlock::DefaultBatchSize))) {
|
||||
auto doc = value->getDocumentCollection(0);
|
||||
size_t const n = value->size();
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
AqlValue val = value->getValue(i, 0);
|
||||
|
||||
if (! val.isEmpty()) {
|
||||
json.add(val.toJson(doc));
|
||||
json.add(val.toJson(&trx, doc));
|
||||
}
|
||||
}
|
||||
delete value;
|
||||
|
|
|
@ -132,9 +132,26 @@ void ApplicationCluster::setupOptions (map<string, basics::ProgramOptionsDescrip
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool ApplicationCluster::prepare () {
|
||||
|
||||
// initialise ServerState library
|
||||
ServerState::initialise();
|
||||
|
||||
// set authentication data
|
||||
ServerState::instance()->setAuthentication(_username, _password);
|
||||
|
||||
// overwrite memory area
|
||||
_username = _password = "someotherusername";
|
||||
|
||||
ServerState::instance()->setDataPath(_dataPath);
|
||||
ServerState::instance()->setLogPath(_logPath);
|
||||
ServerState::instance()->setAgentPath(_agentPath);
|
||||
ServerState::instance()->setArangodPath(_arangodPath);
|
||||
ServerState::instance()->setDBserverConfig(_dbserverConfig);
|
||||
ServerState::instance()->setCoordinatorConfig(_coordinatorConfig);
|
||||
ServerState::instance()->setDisableDispatcherFrontend(_disableDispatcherFrontend);
|
||||
ServerState::instance()->setDisableDispatcherKickstarter(_disableDispatcherKickstarter);
|
||||
|
||||
// check the cluster state
|
||||
_enableCluster = (! _agencyEndpoints.empty() || ! _agencyPrefix.empty());
|
||||
|
||||
if (! enabled()) {
|
||||
|
@ -196,22 +213,6 @@ bool ApplicationCluster::prepare () {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool ApplicationCluster::start () {
|
||||
|
||||
// set authentication data
|
||||
ServerState::instance()->setAuthentication(_username, _password);
|
||||
|
||||
// overwrite memory area
|
||||
_username = _password = "someotherusername";
|
||||
|
||||
ServerState::instance()->setDataPath(_dataPath);
|
||||
ServerState::instance()->setLogPath(_logPath);
|
||||
ServerState::instance()->setAgentPath(_agentPath);
|
||||
ServerState::instance()->setArangodPath(_arangodPath);
|
||||
ServerState::instance()->setDBserverConfig(_dbserverConfig);
|
||||
ServerState::instance()->setCoordinatorConfig(_coordinatorConfig);
|
||||
ServerState::instance()->setDisableDispatcherFrontend(_disableDispatcherFrontend);
|
||||
ServerState::instance()->setDisableDispatcherKickstarter(_disableDispatcherKickstarter);
|
||||
|
||||
if (! enabled()) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -48,6 +48,14 @@ using namespace triagens::arango;
|
|||
|
||||
ServerState::ServerState ()
|
||||
: _id(),
|
||||
_dataPath(),
|
||||
_logPath(),
|
||||
_agentPath(),
|
||||
_arangodPath(),
|
||||
_dbserverConfig(),
|
||||
_coordinatorConfig(),
|
||||
_disableDispatcherFrontend(),
|
||||
_disableDispatcherKickstarter(),
|
||||
_address(),
|
||||
_authentication(),
|
||||
_lock(),
|
||||
|
|
|
@ -83,7 +83,7 @@ using namespace triagens::rest;
|
|||
using namespace triagens::admin;
|
||||
using namespace triagens::arango;
|
||||
|
||||
bool allowUseDatabaseInRESTActions;
|
||||
bool ALLOW_USE_DATABASE_IN_REST_ACTIONS;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private functions
|
||||
|
@ -532,7 +532,7 @@ void ArangoServer::buildApplicationServer () {
|
|||
("server.disable-authentication-unix-sockets", &_disableAuthenticationUnixSockets, "disable authentication for requests via UNIX domain sockets")
|
||||
#endif
|
||||
("server.disable-replication-applier", &_disableReplicationApplier, "start with replication applier turned off")
|
||||
("server.allow-use-database", &allowUseDatabaseInRESTActions, "allow change of database in REST actions, only needed for unittests")
|
||||
("server.allow-use-database", &ALLOW_USE_DATABASE_IN_REST_ACTIONS, "allow change of database in REST actions, only needed for unittests")
|
||||
;
|
||||
|
||||
bool disableStatistics = false;
|
||||
|
@ -799,7 +799,6 @@ int ArangoServer::startupServer () {
|
|||
_applicationV8->setVocbase(vocbase);
|
||||
_applicationV8->setConcurrency(concurrency);
|
||||
|
||||
|
||||
// .............................................................................
|
||||
// prepare everything
|
||||
// .............................................................................
|
||||
|
@ -809,7 +808,6 @@ int ArangoServer::startupServer () {
|
|||
_applicationDispatcher->disable();
|
||||
_applicationEndpointServer->disable();
|
||||
_applicationV8->disableActions();
|
||||
_applicationV8->setStartupFile("");
|
||||
}
|
||||
|
||||
// prepare scheduler and dispatcher
|
||||
|
@ -823,20 +821,16 @@ int ArangoServer::startupServer () {
|
|||
// and finish prepare
|
||||
_applicationServer->prepare2();
|
||||
|
||||
// run version check
|
||||
// run version check (will exit!)
|
||||
if (checkVersion) {
|
||||
_applicationV8->runUpgradeCheck();
|
||||
_applicationV8->versionCheck();
|
||||
}
|
||||
|
||||
_applicationV8->runVersionCheck(skipUpgrade, performUpgrade);
|
||||
|
||||
// finally flush the write-ahead log so all data in the WAL goes into the collections
|
||||
|
||||
// WAL recovery done after here
|
||||
_applicationV8->upgradeDatabase(skipUpgrade, performUpgrade);
|
||||
|
||||
// setup the V8 actions
|
||||
if (startServer) {
|
||||
_applicationV8->prepareActions();
|
||||
_applicationV8->prepareServer();
|
||||
}
|
||||
|
||||
// .............................................................................
|
||||
|
@ -850,11 +844,6 @@ int ArangoServer::startupServer () {
|
|||
|
||||
if (startServer) {
|
||||
|
||||
// create the handlers
|
||||
httpOptions._contexts.insert("user");
|
||||
httpOptions._contexts.insert("api");
|
||||
httpOptions._contexts.insert("admin");
|
||||
|
||||
// create the server
|
||||
_applicationEndpointServer->buildServers();
|
||||
|
||||
|
@ -876,10 +865,15 @@ int ArangoServer::startupServer () {
|
|||
|
||||
_applicationServer->start();
|
||||
|
||||
// if the authentication info could not be loaded, but authentication is turned on,
|
||||
// then we refuse to start
|
||||
if (! vocbase->_authInfoLoaded && ! _disableAuthentication) {
|
||||
LOG_FATAL_AND_EXIT("could not load required authentication information");
|
||||
// for a cluster coordinator, the users are loaded at a later stage;
|
||||
// the kickstarter will trigger a bootstrap process
|
||||
if (ServerState::instance()->getRole() != ServerState::ROLE_COORDINATOR) {
|
||||
|
||||
// if the authentication info could not be loaded, but authentication is turned on,
|
||||
// then we refuse to start
|
||||
if (! vocbase->_authInfoLoaded && ! _disableAuthentication) {
|
||||
LOG_FATAL_AND_EXIT("could not load required authentication information");
|
||||
}
|
||||
}
|
||||
|
||||
if (_disableAuthentication) {
|
||||
|
|
|
@ -36,20 +36,20 @@
|
|||
#include "Rest/HttpResponse.h"
|
||||
#include "Rest/RequestContext.h"
|
||||
|
||||
struct TRI_server_s;
|
||||
struct TRI_vocbase_s;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- forward declarations
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
namespace triagens {
|
||||
namespace arango {
|
||||
struct TRI_server_s;
|
||||
struct TRI_vocbase_s;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- class VocbaseContext
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
namespace triagens {
|
||||
namespace arango {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief ArangoDB VocbaseContext
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -76,6 +76,7 @@ namespace triagens {
|
|||
|
||||
~VocbaseContext ();
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -73,19 +73,30 @@ using namespace std;
|
|||
/// @brief reload the routing cache
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::string const GlobalContextMethods::CodeReloadRouting = "require(\"org/arangodb/actions\").reloadRouting()";
|
||||
std::string const GlobalContextMethods::CodeReloadRouting
|
||||
= "require(\"org/arangodb/actions\").reloadRouting()";
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief flush the modules cache
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::string const GlobalContextMethods::CodeFlushModuleCache = "require(\"internal\").flushModuleCache()";
|
||||
std::string const GlobalContextMethods::CodeFlushModuleCache
|
||||
= "require(\"internal\").flushModuleCache()";
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief reload AQL functions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::string const GlobalContextMethods::CodeReloadAql = "try { require(\"org/arangodb/ahuacatl\").reload(); } catch (err) { }";
|
||||
std::string const GlobalContextMethods::CodeReloadAql
|
||||
= "try { require(\"org/arangodb/ahuacatl\").reload(); } catch (err) { }";
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief bootstrap coordinator
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::string const GlobalContextMethods::CodeBootstrapCoordinator
|
||||
= "require('internal').loadStartup('server/bootstrap/autoload.js').startup();"
|
||||
"require('internal').loadStartup('server/bootstrap/routing.js').startup();";
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief we'll store deprecated config option values in here
|
||||
|
@ -194,6 +205,7 @@ void ApplicationV8::V8Context::handleGlobalContextMethods () {
|
|||
// lock while we execute them
|
||||
// this avoids potential deadlocks when one of the executed functions itself
|
||||
// registers a context method
|
||||
|
||||
MUTEX_LOCKER(_globalMethodsLock);
|
||||
copy = _globalMethods;
|
||||
_globalMethods.clear();
|
||||
|
@ -205,10 +217,16 @@ void ApplicationV8::V8Context::handleGlobalContextMethods () {
|
|||
|
||||
LOG_DEBUG("executing global context methods '%s' for context %d", func.c_str(), (int) _id);
|
||||
|
||||
TRI_v8_global_t* v8g = (TRI_v8_global_t*) v8::Isolate::GetCurrent()->GetData();
|
||||
bool allowUseDatabase = v8g->_allowUseDatabase;
|
||||
v8g->_allowUseDatabase = true;
|
||||
|
||||
TRI_ExecuteJavaScriptString(_context,
|
||||
v8::String::New(func.c_str(), (int) func.size()),
|
||||
v8::String::New("global context method"),
|
||||
false);
|
||||
|
||||
v8g->_allowUseDatabase = allowUseDatabase;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -245,8 +263,6 @@ ApplicationV8::ApplicationV8 (TRI_server_t* server,
|
|||
: ApplicationFeature("V8"),
|
||||
_server(server),
|
||||
_startupPath(),
|
||||
_modulesPath(),
|
||||
_actionPath(),
|
||||
_appPath(),
|
||||
_devAppPath(),
|
||||
_useActions(true),
|
||||
|
@ -256,7 +272,6 @@ ApplicationV8::ApplicationV8 (TRI_server_t* server,
|
|||
_gcFrequency(10.0),
|
||||
_v8Options(""),
|
||||
_startupLoader(),
|
||||
_actionLoader(),
|
||||
_vocbase(0),
|
||||
_nrInstances(0),
|
||||
_contexts(0),
|
||||
|
@ -417,7 +432,6 @@ void ApplicationV8::exitContext (V8Context* context) {
|
|||
|
||||
delete context->_locker;
|
||||
|
||||
|
||||
// default is false
|
||||
bool performGarbageCollection = false;
|
||||
|
||||
|
@ -635,11 +649,11 @@ void ApplicationV8::enableDevelopmentMode () {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief runs the version check
|
||||
/// @brief upgrades the database
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ApplicationV8::runVersionCheck (bool skip, bool perform) {
|
||||
LOG_TRACE("starting version check");
|
||||
void ApplicationV8::upgradeDatabase (bool skip, bool perform) {
|
||||
LOG_TRACE("starting database init/upgrade");
|
||||
|
||||
// enter context and isolate
|
||||
V8Context* context = _contexts[0];
|
||||
|
@ -650,7 +664,7 @@ void ApplicationV8::runVersionCheck (bool skip, bool perform) {
|
|||
|
||||
// run upgrade script
|
||||
if (! skip) {
|
||||
LOG_DEBUG("running database version check");
|
||||
LOG_DEBUG("running database init/upgrade");
|
||||
|
||||
// can do this without a lock as this is the startup
|
||||
for (size_t j = 0; j < _server->_databases._nrAlloc; ++j) {
|
||||
|
@ -666,18 +680,18 @@ void ApplicationV8::runVersionCheck (bool skip, bool perform) {
|
|||
|
||||
context->_context->Global()->Set(v8::String::New("UPGRADE_ARGS"), args);
|
||||
|
||||
bool ok = TRI_V8RunVersionCheck(vocbase, &_startupLoader, context->_context);
|
||||
bool ok = TRI_UpgradeDatabase(vocbase, &_startupLoader, context->_context);
|
||||
|
||||
if (! ok) {
|
||||
if (context->_context->Global()->Has(v8::String::New("UPGRADE_STARTED"))) {
|
||||
if (perform) {
|
||||
LOG_FATAL_AND_EXIT(
|
||||
"Database upgrade failed for '%s'. Please inspect the logs from the upgrade procedure",
|
||||
"Database '%s' upgrade failed. Please inspect the logs from the upgrade procedure",
|
||||
vocbase->_name);
|
||||
}
|
||||
else {
|
||||
LOG_FATAL_AND_EXIT(
|
||||
"Database version check failed for '%s'. Please start the server with the --upgrade option",
|
||||
"Database '%s' needs upgrade. Please start the server with the --upgrade option",
|
||||
vocbase->_name);
|
||||
}
|
||||
}
|
||||
|
@ -686,7 +700,7 @@ void ApplicationV8::runVersionCheck (bool skip, bool perform) {
|
|||
}
|
||||
}
|
||||
|
||||
LOG_DEBUG("database version check passed for '%s'", vocbase->_name);
|
||||
LOG_DEBUG("database '%s' init/upgrade done", vocbase->_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -729,15 +743,15 @@ void ApplicationV8::runVersionCheck (bool skip, bool perform) {
|
|||
context->_isolate->Exit();
|
||||
delete context->_locker;
|
||||
|
||||
LOG_TRACE("finished version check");
|
||||
LOG_TRACE("finished database init/upgrade");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief runs the upgrade check
|
||||
/// @brief runs the version check
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ApplicationV8::runUpgradeCheck () {
|
||||
LOG_TRACE("starting upgrade check");
|
||||
void ApplicationV8::versionCheck () {
|
||||
LOG_TRACE("starting version check");
|
||||
|
||||
// enter context and isolate
|
||||
V8Context* context = _contexts[0];
|
||||
|
@ -747,7 +761,7 @@ void ApplicationV8::runUpgradeCheck () {
|
|||
context->_context->Enter();
|
||||
|
||||
// run upgrade script
|
||||
LOG_DEBUG("running database upgrade check");
|
||||
LOG_DEBUG("running database version check");
|
||||
|
||||
// can do this without a lock as this is the startup
|
||||
int result = 1;
|
||||
|
@ -760,11 +774,11 @@ void ApplicationV8::runUpgradeCheck () {
|
|||
// but for all databases
|
||||
v8::HandleScope scope;
|
||||
|
||||
int status = TRI_V8RunUpgradeCheck(vocbase, &_startupLoader, context->_context);
|
||||
int status = TRI_CheckDatabaseVersion(vocbase, &_startupLoader, context->_context);
|
||||
|
||||
if (status < 0) {
|
||||
LOG_FATAL_AND_EXIT(
|
||||
"Database upgrade check failed for '%s'. Please inspect the logs from any errors",
|
||||
"Database version check failed for '%s'. Please inspect the logs from any errors",
|
||||
vocbase->_name);
|
||||
}
|
||||
else if (status == 3) {
|
||||
|
@ -811,23 +825,15 @@ void ApplicationV8::runUpgradeCheck () {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief prepares the actions
|
||||
/// @brief prepares the server
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ApplicationV8::prepareActions () {
|
||||
void ApplicationV8::prepareServer () {
|
||||
for (size_t i = 0; i < _nrInstances; ++i) {
|
||||
prepareV8Actions(i);
|
||||
prepareV8Server(i);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief sets an alternate init file
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ApplicationV8::setStartupFile (const string& file) {
|
||||
_startupFile = file;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- ApplicationFeature methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -844,16 +850,16 @@ void ApplicationV8::setupOptions (map<string, basics::ProgramOptionsDescription>
|
|||
("javascript.dev-app-path", &_devAppPath, "directory for Foxx applications (development mode)")
|
||||
("javascript.startup-directory", &_startupPath, "path to the directory containing JavaScript startup scripts")
|
||||
("javascript.v8-options", &_v8Options, "options to pass to v8")
|
||||
;
|
||||
|
||||
options[ApplicationServer::OPTIONS_HIDDEN]
|
||||
("javascript.frontend-development", &_frontendDevelopmentMode, "allows rebuild frontend assets")
|
||||
|
||||
// deprecated options
|
||||
("javascript.action-directory", &DeprecatedPath, "path to the JavaScript action directory (deprecated)")
|
||||
("javascript.modules-path", &DeprecatedPath, "one or more directories separated by semi-colons (deprecated)")
|
||||
("javascript.package-path", &DeprecatedPath, "one or more directories separated by semi-colons (deprecated)")
|
||||
;
|
||||
|
||||
options[ApplicationServer::OPTIONS_HIDDEN]
|
||||
("javascript.frontend-development", &_frontendDevelopmentMode, "allows rebuild frontend assets")
|
||||
;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -869,23 +875,11 @@ bool ApplicationV8::prepare () {
|
|||
// remove trailing / from path
|
||||
_startupPath = StringUtils::rTrim(_startupPath, TRI_DIR_SEPARATOR_STR);
|
||||
|
||||
// derive all other options from --javascript.startup-directory
|
||||
_actionPath = _startupPath + TRI_DIR_SEPARATOR_STR + "actions";
|
||||
|
||||
_modulesPath = _startupPath + TRI_DIR_SEPARATOR_STR + "server" + TRI_DIR_SEPARATOR_STR + "modules;" +
|
||||
_startupPath + TRI_DIR_SEPARATOR_STR + "common" + TRI_DIR_SEPARATOR_STR + "modules;" +
|
||||
_startupPath + TRI_DIR_SEPARATOR_STR + "node";
|
||||
|
||||
// dump paths
|
||||
{
|
||||
vector<string> paths;
|
||||
|
||||
paths.push_back(string("startup '" + _startupPath + "'"));
|
||||
paths.push_back(string("modules '" + _modulesPath + "'"));
|
||||
|
||||
if (_useActions) {
|
||||
paths.push_back(string("actions '" + _actionPath + "'"));
|
||||
}
|
||||
|
||||
if (! _appPath.empty()) {
|
||||
paths.push_back(string("application '" + _appPath + "'"));
|
||||
|
@ -911,11 +905,6 @@ bool ApplicationV8::prepare () {
|
|||
_developmentMode = true;
|
||||
}
|
||||
|
||||
// set up action loader
|
||||
if (_useActions) {
|
||||
_actionLoader.setDirectory(_actionPath);
|
||||
}
|
||||
|
||||
// add v8 options
|
||||
if (_v8Options.size() > 0) {
|
||||
LOG_INFO("using V8 options '%s'", _v8Options.c_str());
|
||||
|
@ -1047,18 +1036,7 @@ void ApplicationV8::stop () {
|
|||
bool ApplicationV8::prepareV8Instance (const size_t i) {
|
||||
vector<string> files;
|
||||
|
||||
files.push_back("common/bootstrap/modules.js");
|
||||
files.push_back("common/bootstrap/module-internal.js");
|
||||
files.push_back("common/bootstrap/module-fs.js");
|
||||
files.push_back("common/bootstrap/module-console.js"); // needs internal
|
||||
files.push_back("common/bootstrap/errors.js");
|
||||
files.push_back("common/bootstrap/monkeypatches.js");
|
||||
|
||||
files.push_back("server/bootstrap/module-internal.js");
|
||||
|
||||
if (! _startupFile.empty()) {
|
||||
files.push_back(_startupFile); // needs internal
|
||||
}
|
||||
files.push_back("server/initialise.js");
|
||||
|
||||
LOG_TRACE("initialising V8 context #%d", (int) i);
|
||||
|
||||
|
@ -1092,9 +1070,13 @@ bool ApplicationV8::prepareV8Instance (const size_t i) {
|
|||
TRI_InitV8Actions(context->_context, _vocbase, _scheduler, _dispatcher, this);
|
||||
}
|
||||
|
||||
string modulesPath = _startupPath + TRI_DIR_SEPARATOR_STR + "server" + TRI_DIR_SEPARATOR_STR + "modules;" +
|
||||
_startupPath + TRI_DIR_SEPARATOR_STR + "common" + TRI_DIR_SEPARATOR_STR + "modules;" +
|
||||
_startupPath + TRI_DIR_SEPARATOR_STR + "node";
|
||||
|
||||
TRI_InitV8Buffer(context->_context);
|
||||
TRI_InitV8Conversions(context->_context);
|
||||
TRI_InitV8Utils(context->_context, _startupPath, _modulesPath);
|
||||
TRI_InitV8Utils(context->_context, _startupPath, modulesPath);
|
||||
TRI_InitV8Shell(context->_context);
|
||||
|
||||
{
|
||||
|
@ -1139,11 +1121,11 @@ bool ApplicationV8::prepareV8Instance (const size_t i) {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief prepares the V8 actions
|
||||
/// @brief prepares the V8 server
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ApplicationV8::prepareV8Actions (const size_t i) {
|
||||
LOG_TRACE("initialising V8 actions #%d", (int) i);
|
||||
void ApplicationV8::prepareV8Server (const size_t i) {
|
||||
LOG_TRACE("initialising V8 server #%d", (int) i);
|
||||
|
||||
// enter context and isolate
|
||||
V8Context* context = _contexts[i];
|
||||
|
@ -1152,37 +1134,11 @@ void ApplicationV8::prepareV8Actions (const size_t i) {
|
|||
context->_isolate->Enter();
|
||||
context->_context->Enter();
|
||||
|
||||
// scan for foxx applications
|
||||
if (i == 0) {
|
||||
|
||||
// once again, we don't need the lock as this is the startup
|
||||
for (size_t j = 0; j < _server->_databases._nrAlloc; ++j) {
|
||||
TRI_vocbase_t* vocbase = (TRI_vocbase_t*) _server->_databases._table[j];
|
||||
|
||||
if (vocbase != 0) {
|
||||
TRI_V8InitialiseFoxx(vocbase, context->_context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// load all actions
|
||||
if (_useActions) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
bool ok = _actionLoader.executeAllScripts(context->_context);
|
||||
|
||||
if (! ok) {
|
||||
LOG_FATAL_AND_EXIT("cannot load JavaScript actions from directory '%s'", _actionLoader.getDirectory().c_str());
|
||||
}
|
||||
|
||||
{
|
||||
v8::HandleScope scope;
|
||||
TRI_ExecuteJavaScriptString(context->_context,
|
||||
v8::String::New("require(\"internal\").actionLoaded()"),
|
||||
v8::String::New("action loaded"),
|
||||
false);
|
||||
}
|
||||
// load server startup file
|
||||
bool ok = _startupLoader.loadScript(context->_context, _startupFile);
|
||||
|
||||
if (! ok) {
|
||||
LOG_FATAL_AND_EXIT("cannot load JavaScript utilities from file '%s'", _startupFile.c_str());
|
||||
}
|
||||
|
||||
// and return from the context
|
||||
|
@ -1191,7 +1147,7 @@ void ApplicationV8::prepareV8Actions (const size_t i) {
|
|||
delete context->_locker;
|
||||
|
||||
// initialise garbage collection for context
|
||||
LOG_TRACE("initialised V8 actions #%d", (int) i);
|
||||
LOG_TRACE("initialised V8 server #%d", (int) i);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -75,7 +75,8 @@ namespace triagens {
|
|||
TYPE_UNKNOWN = 0,
|
||||
TYPE_RELOAD_ROUTING,
|
||||
TYPE_FLUSH_MODULE_CACHE,
|
||||
TYPE_RELOAD_AQL
|
||||
TYPE_RELOAD_AQL,
|
||||
TYPE_BOOTSTRAP_COORDINATOR
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -92,6 +93,9 @@ namespace triagens {
|
|||
if (type == "reloadAql") {
|
||||
return TYPE_RELOAD_AQL;
|
||||
}
|
||||
if (type == "bootstrapCoordinator") {
|
||||
return TYPE_BOOTSTRAP_COORDINATOR;
|
||||
}
|
||||
|
||||
return TYPE_UNKNOWN;
|
||||
}
|
||||
|
@ -108,6 +112,8 @@ namespace triagens {
|
|||
return CodeFlushModuleCache;
|
||||
case TYPE_RELOAD_AQL:
|
||||
return CodeReloadAql;
|
||||
case TYPE_BOOTSTRAP_COORDINATOR:
|
||||
return CodeBootstrapCoordinator;
|
||||
case TYPE_UNKNOWN:
|
||||
default:
|
||||
return "";
|
||||
|
@ -121,6 +127,7 @@ namespace triagens {
|
|||
static std::string const CodeReloadRouting;
|
||||
static std::string const CodeFlushModuleCache;
|
||||
static std::string const CodeReloadAql;
|
||||
static std::string const CodeBootstrapCoordinator;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -324,31 +331,23 @@ namespace triagens {
|
|||
_definedBooleans[name] = value;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief upgrades the database
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void upgradeDatabase (bool skip, bool perform);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief runs the version check
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void runVersionCheck (bool skip, bool perform);
|
||||
void versionCheck ();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief runs the upgrade check
|
||||
/// @brief prepares the server
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void runUpgradeCheck ();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief prepares the actions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void prepareActions ();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief sets an alternate init file
|
||||
///
|
||||
/// Normally "server.js" will be used. Pass empty string to disable.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void setStartupFile (const string&);
|
||||
void prepareServer ();
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- ApplicationFeature methods
|
||||
|
@ -411,10 +410,10 @@ namespace triagens {
|
|||
bool prepareV8Instance (size_t);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief prepares the V8 actions
|
||||
/// @brief prepares the V8 server
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void prepareV8Actions (size_t);
|
||||
void prepareV8Server (size_t);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief shut downs a V8 instances
|
||||
|
@ -443,24 +442,6 @@ namespace triagens {
|
|||
|
||||
string _startupPath;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief semicolon separated list of module directories
|
||||
///
|
||||
/// This variable is automatically set based on the value of
|
||||
/// `--javascript.startup-directory`.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
string _modulesPath;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief path to the system action directory
|
||||
///
|
||||
/// This variable is automatically set based on the value of
|
||||
/// `--javascript.startup-directory`.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
string _actionPath;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief semicolon separated list of application directories
|
||||
/// `--javascript.app-path directory`
|
||||
|
@ -566,12 +547,6 @@ namespace triagens {
|
|||
|
||||
JSLoader _startupLoader;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief V8 action loader
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
JSLoader _actionLoader;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief system database
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -111,8 +111,8 @@ class v8_action_t : public TRI_action_t {
|
|||
/// @brief constructor
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
v8_action_t (set<string> const& contexts)
|
||||
: TRI_action_t(contexts),
|
||||
v8_action_t ()
|
||||
: TRI_action_t(),
|
||||
_callbacks(),
|
||||
_callbacksLock() {
|
||||
_type = "JAVASCRIPT";
|
||||
|
@ -146,14 +146,19 @@ class v8_action_t : public TRI_action_t {
|
|||
TRI_action_result_t result;
|
||||
|
||||
// determine whether we should force a re-initialistion of the engine in development mode
|
||||
bool allowEngineReset;
|
||||
extern bool allowUseDatabaseInRESTActions;
|
||||
bool allowEngineReset = false;
|
||||
|
||||
allowEngineReset = false;
|
||||
// allow use datase execution in rest calls
|
||||
extern bool ALLOW_USE_DATABASE_IN_REST_ACTIONS;
|
||||
bool allowUseDatabaseInRestActions = ALLOW_USE_DATABASE_IN_REST_ACTIONS;
|
||||
|
||||
string const& fullUrl = request->fullUrl();
|
||||
if (_allowUseDatabase) {
|
||||
allowUseDatabaseInRestActions = true;
|
||||
}
|
||||
|
||||
// only URLs starting with /dev will trigger an engine reset
|
||||
string const& fullUrl = request->fullUrl();
|
||||
|
||||
if (fullUrl.find("/dev/") == 0) {
|
||||
allowEngineReset = true;
|
||||
}
|
||||
|
@ -162,7 +167,7 @@ class v8_action_t : public TRI_action_t {
|
|||
vocbase,
|
||||
request,
|
||||
! allowEngineReset,
|
||||
allowUseDatabaseInRESTActions);
|
||||
allowUseDatabaseInRestActions);
|
||||
|
||||
// note: the context might be 0 in case of shut-down
|
||||
if (context == 0) {
|
||||
|
@ -270,6 +275,14 @@ static void ParseActionOptions (TRI_v8_global_t* v8g,
|
|||
else {
|
||||
action->_isPrefix = false;
|
||||
}
|
||||
|
||||
// check the "allowUseDatabase" field
|
||||
if (options->Has(v8g->AllowUseDatabaseKey)) {
|
||||
action->_allowUseDatabase = TRI_ObjectToBoolean(options->Get(v8g->AllowUseDatabaseKey));
|
||||
}
|
||||
else {
|
||||
action->_allowUseDatabase = false;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -762,8 +775,8 @@ static v8::Handle<v8::Value> JS_DefineAction (v8::Arguments const& argv) {
|
|||
isolate = v8::Isolate::GetCurrent();
|
||||
v8g = (TRI_v8_global_t*) isolate->GetData();
|
||||
|
||||
if (argv.Length() != 4) {
|
||||
TRI_V8_EXCEPTION_USAGE(scope, "defineAction(<name>, <callback>, <parameter>, <contexts>)");
|
||||
if (argv.Length() != 3) {
|
||||
TRI_V8_EXCEPTION_USAGE(scope, "defineAction(<name>, <callback>, <parameter>)");
|
||||
}
|
||||
|
||||
// extract the action name
|
||||
|
@ -792,25 +805,8 @@ static v8::Handle<v8::Value> JS_DefineAction (v8::Arguments const& argv) {
|
|||
options = v8::Object::New();
|
||||
}
|
||||
|
||||
// extract the contexts
|
||||
set<string> contexts;
|
||||
|
||||
if (! argv[3]->IsArray()) {
|
||||
TRI_V8_TYPE_ERROR(scope, "<contexts> must be a list of contexts");
|
||||
}
|
||||
|
||||
v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(argv[3]);
|
||||
|
||||
uint32_t n = array->Length();
|
||||
|
||||
for (uint32_t j = 0; j < n; ++j) {
|
||||
v8::Handle<v8::Value> item = array->Get(j);
|
||||
|
||||
contexts.insert(TRI_ObjectToString(item));
|
||||
}
|
||||
|
||||
// create an action with the given options
|
||||
v8_action_t* action = new v8_action_t(contexts);
|
||||
v8_action_t* action = new v8_action_t();
|
||||
ParseActionOptions(v8g, action, options);
|
||||
|
||||
// store an action with the given name
|
||||
|
|
|
@ -3747,11 +3747,10 @@ static v8::Handle<v8::Value> JS_CompletionsVocbase (v8::Arguments const& argv) {
|
|||
return scope.Close(result);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- javascript functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief removes a document
|
||||
/// @startDocuBlock documentsCollectionRemove
|
||||
|
|
|
@ -1445,6 +1445,22 @@ static v8::Handle<v8::Value> MapGetVocBase (v8::Local<v8::String> const name,
|
|||
return scope.Close(result);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief return the server version string
|
||||
/// @startDocuBlock databaseVersion
|
||||
/// `db._version()`
|
||||
///
|
||||
/// Returns the server version string. Note that this is not the version of the
|
||||
/// database.
|
||||
/// @endDocuBlock
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static v8::Handle<v8::Value> JS_VersionServer (v8::Arguments const& argv) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
return scope.Close(v8::String::New(TRI_VERSION));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief return the path to database files
|
||||
/// @startDocuBlock databasePath
|
||||
|
@ -1798,14 +1814,14 @@ static v8::Handle<v8::Value> CreateDatabaseCoordinator (v8::Arguments const& arg
|
|||
|
||||
// database was created successfully in agency
|
||||
|
||||
TRI_v8_global_t* v8g = (TRI_v8_global_t*) v8::Isolate::GetCurrent()->GetData();
|
||||
TRI_v8_global_t* v8g = static_cast<TRI_v8_global_t*>(v8::Isolate::GetCurrent()->GetData());
|
||||
|
||||
// now wait for heartbeat thread to create the database object
|
||||
TRI_vocbase_t* vocbase = nullptr;
|
||||
int tries = 0;
|
||||
|
||||
while (++tries <= 6000) {
|
||||
vocbase = TRI_UseByIdCoordinatorDatabaseServer((TRI_server_t*) v8g->_server, id);
|
||||
vocbase = TRI_UseByIdCoordinatorDatabaseServer(static_cast<TRI_server_t*>(v8g->_server), id);
|
||||
|
||||
if (vocbase != nullptr) {
|
||||
break;
|
||||
|
@ -1830,10 +1846,22 @@ static v8::Handle<v8::Value> CreateDatabaseCoordinator (v8::Arguments const& arg
|
|||
v8::Context::GetCurrent()->Global()->Set(v8::String::New("UPGRADE_ARGS"), v8::Object::New());
|
||||
}
|
||||
|
||||
if (TRI_V8RunVersionCheck(vocbase, static_cast<JSLoader*>(v8g->_loader), v8::Context::GetCurrent())) {
|
||||
// version check ok
|
||||
TRI_V8InitialiseFoxx(vocbase, v8::Context::GetCurrent());
|
||||
}
|
||||
// switch databases
|
||||
TRI_vocbase_t* orig = v8g->_vocbase;
|
||||
TRI_ASSERT(orig != nullptr);
|
||||
|
||||
v8g->_vocbase = vocbase;
|
||||
|
||||
// initalise database
|
||||
bool allowUseDatabase = v8g->_allowUseDatabase;
|
||||
v8g->_allowUseDatabase = true;
|
||||
|
||||
v8g->_loader->executeGlobalScript(v8::Context::GetCurrent(), "server/bootstrap/coordinator-database.js");
|
||||
|
||||
v8g->_allowUseDatabase = allowUseDatabase;
|
||||
|
||||
// and switch back
|
||||
v8g->_vocbase = orig;
|
||||
|
||||
TRI_ReleaseVocBase(vocbase);
|
||||
|
||||
|
@ -1969,10 +1997,17 @@ static v8::Handle<v8::Value> JS_CreateDatabase (v8::Arguments const& argv) {
|
|||
v8::Context::GetCurrent()->Global()->Set(v8::String::New("UPGRADE_ARGS"), v8::Object::New());
|
||||
}
|
||||
|
||||
if (TRI_V8RunVersionCheck(database, static_cast<JSLoader*>(v8g->_loader), v8::Context::GetCurrent())) {
|
||||
// version check ok
|
||||
TRI_V8InitialiseFoxx(database, v8::Context::GetCurrent());
|
||||
}
|
||||
// switch databases
|
||||
TRI_vocbase_t* orig = v8g->_vocbase;
|
||||
TRI_ASSERT(orig != nullptr);
|
||||
|
||||
v8g->_vocbase = database;
|
||||
|
||||
// initalise database
|
||||
v8g->_loader->executeGlobalScript(v8::Context::GetCurrent(), "server/bootstrap/local-database.js");
|
||||
|
||||
// and switch back
|
||||
v8g->_vocbase = orig;
|
||||
|
||||
// populate the authentication cache. otherwise no one can access the new database
|
||||
TRI_ReloadAuthInfo(database);
|
||||
|
@ -2317,17 +2352,17 @@ int32_t TRI_GetVocBaseColType () {
|
|||
/// @brief run version check
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TRI_V8RunVersionCheck (void* vocbase,
|
||||
JSLoader* startupLoader,
|
||||
v8::Handle<v8::Context> context) {
|
||||
bool TRI_UpgradeDatabase (TRI_vocbase_t* vocbase,
|
||||
JSLoader* startupLoader,
|
||||
v8::Handle<v8::Context> context) {
|
||||
TRI_ASSERT(startupLoader != nullptr);
|
||||
|
||||
v8::HandleScope scope;
|
||||
TRI_v8_global_t* v8g = static_cast<TRI_v8_global_t*>(v8::Isolate::GetCurrent()->GetData());
|
||||
void* orig = v8g->_vocbase;
|
||||
TRI_vocbase_t* orig = v8g->_vocbase;
|
||||
v8g->_vocbase = vocbase;
|
||||
|
||||
v8::Handle<v8::Value> result = startupLoader->executeGlobalScript(context, "server/version-check.js");
|
||||
v8::Handle<v8::Value> result = startupLoader->executeGlobalScript(context, "server/upgrade-database.js");
|
||||
bool ok = TRI_ObjectToBoolean(result);
|
||||
|
||||
if (! ok) {
|
||||
|
@ -2343,17 +2378,17 @@ bool TRI_V8RunVersionCheck (void* vocbase,
|
|||
/// @brief run upgrade check
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int TRI_V8RunUpgradeCheck (void* vocbase,
|
||||
JSLoader* startupLoader,
|
||||
v8::Handle<v8::Context> context) {
|
||||
int TRI_CheckDatabaseVersion (TRI_vocbase_t* vocbase,
|
||||
JSLoader* startupLoader,
|
||||
v8::Handle<v8::Context> context) {
|
||||
TRI_ASSERT(startupLoader != nullptr);
|
||||
|
||||
v8::HandleScope scope;
|
||||
TRI_v8_global_t* v8g = static_cast<TRI_v8_global_t*>(v8::Isolate::GetCurrent()->GetData());
|
||||
void* orig = v8g->_vocbase;
|
||||
TRI_vocbase_t* orig = v8g->_vocbase;
|
||||
v8g->_vocbase = vocbase;
|
||||
|
||||
v8::Handle<v8::Value> result = startupLoader->executeGlobalScript(context, "server/upgrade-check.js");
|
||||
v8::Handle<v8::Value> result = startupLoader->executeGlobalScript(context, "server/check-version.js");
|
||||
int code = (int) TRI_ObjectToInt64(result);
|
||||
|
||||
v8g->_vocbase = orig;
|
||||
|
@ -2361,33 +2396,6 @@ int TRI_V8RunUpgradeCheck (void* vocbase,
|
|||
return code;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief initialize foxx
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_V8InitialiseFoxx (void* vocbase,
|
||||
v8::Handle<v8::Context> context) {
|
||||
void* orig = nullptr;
|
||||
|
||||
{
|
||||
v8::HandleScope scope;
|
||||
TRI_v8_global_t* v8g = static_cast<TRI_v8_global_t*>(v8::Isolate::GetCurrent()->GetData());
|
||||
orig = v8g->_vocbase;
|
||||
v8g->_vocbase = vocbase;
|
||||
}
|
||||
|
||||
v8::HandleScope scope;
|
||||
TRI_ExecuteJavaScriptString(context,
|
||||
v8::String::New("require(\"internal\").initializeFoxx()"),
|
||||
v8::String::New("initialize foxx"),
|
||||
false);
|
||||
{
|
||||
v8::HandleScope scope;
|
||||
TRI_v8_global_t* v8g = static_cast<TRI_v8_global_t*>(v8::Isolate::GetCurrent()->GetData());
|
||||
v8g->_vocbase = orig;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief reloads routing
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -2446,6 +2454,7 @@ void TRI_InitV8VocBridge (v8::Handle<v8::Context> context,
|
|||
// for any database function added here, be sure to add it to in function
|
||||
// JS_CompletionsVocbase, too for the auto-completion
|
||||
|
||||
TRI_AddMethodVocbase(ArangoNS, "_version", JS_VersionServer);
|
||||
TRI_AddMethodVocbase(ArangoNS, "_id", JS_IdDatabase);
|
||||
TRI_AddMethodVocbase(ArangoNS, "_isSystem", JS_IsSystemDatabase);
|
||||
TRI_AddMethodVocbase(ArangoNS, "_name", JS_NameDatabase);
|
||||
|
|
|
@ -68,24 +68,17 @@ int32_t TRI_GetVocBaseColType ();
|
|||
/// @brief run version check
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TRI_V8RunVersionCheck (void*,
|
||||
triagens::arango::JSLoader*,
|
||||
v8::Handle<v8::Context>);
|
||||
bool TRI_UpgradeDatabase (TRI_vocbase_t*,
|
||||
triagens::arango::JSLoader*,
|
||||
v8::Handle<v8::Context>);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief run upgrade check
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int TRI_V8RunUpgradeCheck (void* vocbase,
|
||||
triagens::arango::JSLoader* startupLoader,
|
||||
v8::Handle<v8::Context> context);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief initialize foxx
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_V8InitialiseFoxx (void*,
|
||||
v8::Handle<v8::Context>);
|
||||
int TRI_CheckDatabaseVersion (TRI_vocbase_t* vocbase,
|
||||
triagens::arango::JSLoader* startupLoader,
|
||||
v8::Handle<v8::Context> context);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief reloads routing
|
||||
|
|
|
@ -32,12 +32,12 @@ The file will contain a JSON array with a "version" attribute. The version attri
|
|||
will contain the version number that ArangoDB was last started with.
|
||||
|
||||
It will also contain a "tasks" attribute with an array of all the tasks that are
|
||||
or were already executed by the upgrade procedure in js/server/version-check.js.
|
||||
or were already executed by the upgrade procedure in js/server/upgrade-database.js.
|
||||
Every successful upgrade task will be inserted into the "tasks" array with a value of
|
||||
true. Every failed upgrade task will be inserted into the "tasks" array with a value
|
||||
of false.
|
||||
Failed upgrade tasks will get re-executed on server startup if the task is still
|
||||
present in the js/server/version-check.js file.
|
||||
present in the js/server/upgrade-database.js file.
|
||||
|
||||
The VERSION file will be created on the first start of ArangoDB if the database
|
||||
directory is still empty.
|
||||
|
|
|
@ -508,6 +508,95 @@ size_t TRI_DocumentIteratorDocumentCollection (triagens::arango::TransactionBase
|
|||
#define TRI_UNLOCK_JOURNAL_ENTRIES_DOC_COLLECTION(a) \
|
||||
TRI_UnlockCondition(&(a)->_journalsCondition)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief whether or not the marker is an edge marker
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static inline bool TRI_IS_EDGE_MARKER (TRI_df_marker_t const* marker) {
|
||||
return (marker->_type == TRI_DOC_MARKER_KEY_EDGE ||
|
||||
marker->_type == TRI_WAL_MARKER_EDGE);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief extracts the pointer to the _from key from a marker
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static inline char const* TRI_EXTRACT_MARKER_FROM_KEY (TRI_df_marker_t const* marker) {
|
||||
if (marker->_type == TRI_DOC_MARKER_KEY_EDGE) {
|
||||
return ((char const*) marker) + ((TRI_doc_edge_key_marker_t const*) marker)->_offsetFromKey;
|
||||
}
|
||||
else if (marker->_type == TRI_WAL_MARKER_EDGE) {
|
||||
return ((char const*) marker) + ((triagens::wal::edge_marker_t const*) marker)->_offsetFromKey;
|
||||
}
|
||||
|
||||
#ifdef TRI_ENABLE_MAINTAINER_MODE
|
||||
// invalid marker type
|
||||
TRI_ASSERT(false);
|
||||
#endif
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief extracts the pointer to the _to key from a marker
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static inline char const* TRI_EXTRACT_MARKER_TO_KEY (TRI_df_marker_t const* marker) {
|
||||
if (marker->_type == TRI_DOC_MARKER_KEY_EDGE) {
|
||||
return ((char const*) marker) + ((TRI_doc_edge_key_marker_t const*) marker)->_offsetToKey;
|
||||
}
|
||||
else if (marker->_type == TRI_WAL_MARKER_EDGE) {
|
||||
return ((char const*) marker) + ((triagens::wal::edge_marker_t const*) marker)->_offsetToKey;
|
||||
}
|
||||
|
||||
#ifdef TRI_ENABLE_MAINTAINER_MODE
|
||||
// invalid marker type
|
||||
TRI_ASSERT(false);
|
||||
#endif
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief extracts the _from cid from a marker
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static inline TRI_voc_cid_t TRI_EXTRACT_MARKER_FROM_CID (TRI_df_marker_t const* marker) {
|
||||
if (marker->_type == TRI_DOC_MARKER_KEY_EDGE) {
|
||||
return ((TRI_doc_edge_key_marker_t const*) marker)->_fromCid;
|
||||
}
|
||||
else if (marker->_type == TRI_WAL_MARKER_EDGE) {
|
||||
return ((triagens::wal::edge_marker_t const*) marker)->_fromCid;
|
||||
}
|
||||
|
||||
#ifdef TRI_ENABLE_MAINTAINER_MODE
|
||||
// invalid marker type
|
||||
TRI_ASSERT(false);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief extracts the _to cid from a marker
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static inline TRI_voc_cid_t TRI_EXTRACT_MARKER_TO_CID (TRI_df_marker_t const* marker) {
|
||||
if (marker->_type == TRI_DOC_MARKER_KEY_EDGE) {
|
||||
return ((TRI_doc_edge_key_marker_t const*) marker)->_toCid;
|
||||
}
|
||||
else if (marker->_type == TRI_WAL_MARKER_EDGE) {
|
||||
return ((triagens::wal::edge_marker_t const*) marker)->_toCid;
|
||||
}
|
||||
|
||||
#ifdef TRI_ENABLE_MAINTAINER_MODE
|
||||
// invalid marker type
|
||||
TRI_ASSERT(false);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief extracts the revision id from a marker
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -71,7 +71,7 @@ JAVASCRIPT_JSLINT = \
|
|||
\
|
||||
@srcdir@/js/client/client.js \
|
||||
@srcdir@/js/server/server.js \
|
||||
@srcdir@/js/server/version-check.js \
|
||||
@srcdir@/js/server/upgrade-database.js \
|
||||
\
|
||||
@srcdir@/js/apps/system/aardvark/frontend/js/shell/browser.js
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2012 triagens GmbH, Cologne, Germany
|
||||
/// Copyright 2014 ArangoDB 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.
|
||||
|
@ -22,9 +22,10 @@
|
|||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Jan Steemann
|
||||
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
|
||||
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -36,11 +37,6 @@ var aqlfunctions = require("org/arangodb/aql/functions");
|
|||
// --SECTION-- private functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup ArangoAPI
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @startDocuBlock JSF_get_api_aqlfunction
|
||||
/// @brief gets all reqistered AQL user functions
|
||||
|
@ -113,9 +109,9 @@ function get_api_aqlfunction (req, res) {
|
|||
/// - *name*: the fully qualified name of the user functions.
|
||||
///
|
||||
/// - *code*: a string representation of the function body.
|
||||
///
|
||||
///
|
||||
/// - *isDeterministic*: an optional boolean value to indicate that the function
|
||||
/// results are fully deterministic (function return value solely depends on
|
||||
/// results are fully deterministic (function return value solely depends on
|
||||
/// the input value and return value is the same for repeated calls with same
|
||||
/// input). The *isDeterministic* attribute is currently not used but may be
|
||||
/// used later for optimisations.
|
||||
|
@ -145,7 +141,7 @@ function get_api_aqlfunction (req, res) {
|
|||
/// call, the server will respond with *HTTP 200*.
|
||||
///
|
||||
/// @RESTRETURNCODE{201}
|
||||
/// If the function can be registered by the server, the server will respond with
|
||||
/// If the function can be registered by the server, the server will respond with
|
||||
/// *HTTP 201*.
|
||||
///
|
||||
/// @RESTRETURNCODE{400}
|
||||
|
@ -156,7 +152,7 @@ function get_api_aqlfunction (req, res) {
|
|||
///
|
||||
/// @EXAMPLE_ARANGOSH_RUN{RestAqlfunctionCreate}
|
||||
/// var url = "/_api/aqlfunction";
|
||||
/// var body = '{ ' +
|
||||
/// var body = '{ ' +
|
||||
/// '"name" : "myfunctions::temperature::celsiustofahrenheit", ' +
|
||||
/// '"code" : "function (celsius) { return celsius * 1.8 + 32; }" ' +
|
||||
/// '}';
|
||||
|
@ -167,7 +163,7 @@ function get_api_aqlfunction (req, res) {
|
|||
///
|
||||
/// logJsonResponse(response);
|
||||
/// @END_EXAMPLE_ARANGOSH_RUN
|
||||
/// @endDocuBlock
|
||||
/// @endDocuBlock
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function post_api_aqlfunction (req, res) {
|
||||
|
@ -198,12 +194,12 @@ function post_api_aqlfunction (req, res) {
|
|||
/// @RESTQUERYPARAM{group,string,optional}
|
||||
/// If set to *true*, then the function name provided in *name* is treated as
|
||||
/// a namespace prefix, and all functions in the specified namespace will be deleted.
|
||||
/// If set to *false*, the function name provided in *name* must be fully
|
||||
/// If set to *false*, the function name provided in *name* must be fully
|
||||
/// qualified, including any namespaces.
|
||||
///
|
||||
/// @RESTDESCRIPTION
|
||||
///
|
||||
/// Removes an existing AQL user function, identified by *name*.
|
||||
/// Removes an existing AQL user function, identified by *name*.
|
||||
///
|
||||
/// In case of success, the returned JSON object has the following properties:
|
||||
///
|
||||
|
@ -226,7 +222,7 @@ function post_api_aqlfunction (req, res) {
|
|||
/// @RESTRETURNCODES
|
||||
///
|
||||
/// @RESTRETURNCODE{200}
|
||||
/// If the function can be removed by the server, the server will respond with
|
||||
/// If the function can be removed by the server, the server will respond with
|
||||
/// *HTTP 200*.
|
||||
///
|
||||
/// @RESTRETURNCODE{400}
|
||||
|
@ -297,26 +293,25 @@ function delete_api_aqlfunction (req, res) {
|
|||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief gateway
|
||||
/// @brief gateway
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : "_api/aqlfunction",
|
||||
context : "api",
|
||||
|
||||
callback : function (req, res) {
|
||||
try {
|
||||
switch (req.requestType) {
|
||||
case actions.GET:
|
||||
get_api_aqlfunction(req, res);
|
||||
case actions.GET:
|
||||
get_api_aqlfunction(req, res);
|
||||
break;
|
||||
|
||||
case actions.POST:
|
||||
post_api_aqlfunction(req, res);
|
||||
case actions.POST:
|
||||
post_api_aqlfunction(req, res);
|
||||
break;
|
||||
|
||||
case actions.DELETE:
|
||||
delete_api_aqlfunction(req, res);
|
||||
case actions.DELETE:
|
||||
delete_api_aqlfunction(req, res);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -329,11 +324,11 @@ actions.defineHttp({
|
|||
}
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @}\\)"
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*jslint indent: 2, nomen: true, maxlen: 140, sloppy: true, vars: true, white: true, plusplus: true, evil: true */
|
||||
/*global require, exports, module, SYS_CLUSTER_TEST, ArangoServerState, ArangoClusterComm, ArangoClusterInfo */
|
||||
/*global require, exports, module, SYS_CLUSTER_TEST, ArangoServerState, ArangoClusterComm, ArangoClusterInfo,
|
||||
UPGRADE_ARGS: true */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief cluster actions
|
||||
|
@ -8,7 +9,7 @@
|
|||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014-2014 triagens GmbH, Cologne, Germany
|
||||
/// Copyright 2014 ArangoDB 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.
|
||||
|
@ -22,20 +23,19 @@
|
|||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Max Neunhoeffer
|
||||
/// @author Copyright 2014, triAGENS GmbH, Cologne, Germany
|
||||
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
|
||||
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
|
||||
/// @author Copyright 2013-2014, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var actions = require("org/arangodb/actions");
|
||||
var cluster = require("org/arangodb/cluster");
|
||||
var internal = require("internal");
|
||||
var console = require("console");
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private functions
|
||||
// -----------------------------------------------------------------------------
|
||||
var fs = require("fs");
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public functions
|
||||
|
@ -167,9 +167,8 @@ var console = require("console");
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : "_admin/cluster-test",
|
||||
context : "admin",
|
||||
prefix : true,
|
||||
url: "_admin/cluster-test",
|
||||
prefix: true,
|
||||
|
||||
callback : function (req, res) {
|
||||
var path;
|
||||
|
@ -298,9 +297,9 @@ function parseAuthorization (authorization) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : "_admin/clusterPlanner",
|
||||
context : "admin",
|
||||
prefix : "false",
|
||||
url: "_admin/clusterPlanner",
|
||||
prefix: false,
|
||||
|
||||
callback : function (req, res) {
|
||||
if (ArangoServerState.disableDispatcherKickstarter() === true) {
|
||||
actions.resultError(req, res, actions.HTTP_FORBIDDEN);
|
||||
|
@ -389,9 +388,9 @@ actions.defineHttp({
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : "_admin/clusterDispatch",
|
||||
context : "admin",
|
||||
prefix : "false",
|
||||
url: "_admin/clusterDispatch",
|
||||
prefix: false,
|
||||
|
||||
callback : function (req, res) {
|
||||
if (ArangoServerState.disableDispatcherKickstarter() === true) {
|
||||
actions.resultError(req, res, actions.HTTP_FORBIDDEN);
|
||||
|
@ -540,9 +539,9 @@ actions.defineHttp({
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : "_admin/clusterCheckPort",
|
||||
context : "admin",
|
||||
prefix : "false",
|
||||
url: "_admin/clusterCheckPort",
|
||||
prefix: false,
|
||||
|
||||
callback : function (req, res) {
|
||||
if (ArangoServerState.disableDispatcherKickstarter() === true) {
|
||||
actions.resultError(req, res, actions.HTTP_FORBIDDEN);
|
||||
|
@ -604,9 +603,9 @@ actions.defineHttp({
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : "_admin/clusterStatistics",
|
||||
context : "admin",
|
||||
prefix : "false",
|
||||
url: "_admin/clusterStatistics",
|
||||
prefix: false,
|
||||
|
||||
callback : function (req, res) {
|
||||
if (req.requestType !== actions.GET) {
|
||||
actions.resultError(req, res, actions.HTTP_FORBIDDEN, 0,
|
||||
|
@ -654,10 +653,14 @@ actions.defineHttp({
|
|||
}
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief allows to query the historic statistics of a DBserver in the cluster
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : "_admin/history",
|
||||
context : "admin",
|
||||
prefix : "false",
|
||||
url: "_admin/history",
|
||||
prefix: false,
|
||||
|
||||
callback : function (req, res) {
|
||||
if (req.requestType !== actions.POST) {
|
||||
actions.resultError(req, res, actions.HTTP_FORBIDDEN, 0,
|
||||
|
@ -714,7 +717,7 @@ actions.defineHttp({
|
|||
}
|
||||
res.responseCode = actions.HTTP_OK;
|
||||
res.body = JSON.stringify({result : cursor.docs});
|
||||
}
|
||||
}
|
||||
else {
|
||||
// query a remote statistics collection
|
||||
var coord = { coordTransactionID: ArangoClusterInfo.uniqid() };
|
||||
|
@ -749,14 +752,132 @@ actions.defineHttp({
|
|||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
/// @brief bootstraps the all db servers
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url: "_admin/cluster/bootstrapDbServers",
|
||||
prefix: false,
|
||||
|
||||
callback: function (req, res) {
|
||||
var body = actions.getJsonBody(req, res);
|
||||
|
||||
try {
|
||||
var result = cluster.bootstrapDbServers(body.isRelaunch);
|
||||
|
||||
if (result) {
|
||||
actions.resultOk(req, res, actions.HTTP_OK);
|
||||
}
|
||||
else {
|
||||
actions.resultBad(req, res);
|
||||
}
|
||||
}
|
||||
catch(err) {
|
||||
actions.resultException(req, res, err);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief bootstraps one db server
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url: "_admin/cluster/bootstrapDbServer",
|
||||
prefix: false,
|
||||
|
||||
callback: function (req, res) {
|
||||
var body = actions.getJsonBody(req, res);
|
||||
|
||||
UPGRADE_ARGS = {
|
||||
isCluster: true,
|
||||
isDbServer: true,
|
||||
isRelaunch: body.isRelaunch
|
||||
};
|
||||
|
||||
try {
|
||||
var func = internal.loadStartup("server/bootstrap/db-server.js");
|
||||
var result = func && func();
|
||||
|
||||
if (result) {
|
||||
actions.resultOk(req, res, actions.HTTP_OK);
|
||||
}
|
||||
else {
|
||||
actions.resultBad(req, res);
|
||||
}
|
||||
}
|
||||
catch(err) {
|
||||
actions.resultException(req, res, err);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief upgrade cluster database
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url: "_admin/cluster/upgradeClusterDatabase",
|
||||
prefix: false,
|
||||
|
||||
callback: function (req, res) {
|
||||
var body = actions.getJsonBody(req, res);
|
||||
|
||||
UPGRADE_ARGS = {
|
||||
isCluster: true,
|
||||
isCoordinator: true,
|
||||
isRelaunch: body.isRelaunch || false,
|
||||
upgrade: body.upgrade || false
|
||||
};
|
||||
|
||||
try {
|
||||
var result = internal.loadStartup("server/upgrade-database.js");
|
||||
|
||||
if (result) {
|
||||
actions.resultOk(req, res, actions.HTTP_OK);
|
||||
}
|
||||
else {
|
||||
actions.resultBad(req, res);
|
||||
}
|
||||
}
|
||||
catch(err) {
|
||||
actions.resultException(req, res, err);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief bootstraps the coordinator
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url: "_admin/cluster/bootstrapCoordinator",
|
||||
allowUseDatabase: true,
|
||||
prefix: false,
|
||||
|
||||
callback: function (req, res) {
|
||||
try {
|
||||
var func = internal.loadStartup("server/bootstrap/coordinator.js");
|
||||
var result = func && func();
|
||||
|
||||
if (result) {
|
||||
actions.resultOk(req, res, actions.HTTP_OK);
|
||||
}
|
||||
else {
|
||||
actions.resultBad(req, res);
|
||||
}
|
||||
}
|
||||
catch(err) {
|
||||
actions.resultException(req, res, err);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @\\}"
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2012 triagens GmbH, Cologne, Germany
|
||||
/// Copyright 2014 ArangoDB 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.
|
||||
|
@ -22,9 +22,10 @@
|
|||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Achim Brandt
|
||||
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
|
||||
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -38,11 +39,6 @@ var API = "_api/collection";
|
|||
// --SECTION-- private functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup ArangoAPI
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief return a prefixed URL
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -73,7 +69,7 @@ function collectionRepresentation (collection, showProperties, showCount, showFi
|
|||
|
||||
result.doCompact = properties.doCompact;
|
||||
result.isVolatile = properties.isVolatile;
|
||||
result.journalSize = properties.journalSize;
|
||||
result.journalSize = properties.journalSize;
|
||||
result.keyOptions = properties.keyOptions;
|
||||
result.waitForSync = properties.waitForSync;
|
||||
|
||||
|
@ -101,19 +97,10 @@ function collectionRepresentation (collection, showProperties, showCount, showFi
|
|||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup ArangoAPI
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief helper to parse arguments for creating collections
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -143,15 +130,15 @@ function parseBodyForCreateCollection (req, res) {
|
|||
if (body.hasOwnProperty("isSystem")) {
|
||||
r.parameter.isSystem = body.isSystem;
|
||||
}
|
||||
|
||||
|
||||
if (body.hasOwnProperty("isVolatile")) {
|
||||
r.parameter.isVolatile = body.isVolatile;
|
||||
}
|
||||
|
||||
|
||||
if (body.hasOwnProperty("journalSize")) {
|
||||
r.parameter.journalSize = body.journalSize;
|
||||
}
|
||||
|
||||
|
||||
if (body.hasOwnProperty("keyOptions")) {
|
||||
r.parameter.keyOptions = body.keyOptions;
|
||||
}
|
||||
|
@ -159,15 +146,15 @@ function parseBodyForCreateCollection (req, res) {
|
|||
if (body.hasOwnProperty("type")) {
|
||||
r.type = body.type;
|
||||
}
|
||||
|
||||
|
||||
if (body.hasOwnProperty("waitForSync")) {
|
||||
r.parameter.waitForSync = body.waitForSync;
|
||||
}
|
||||
|
||||
|
||||
if (body.hasOwnProperty("shardKeys") && cluster.isCoordinator()) {
|
||||
r.parameter.shardKeys = body.shardKeys || { };
|
||||
}
|
||||
|
||||
|
||||
if (body.hasOwnProperty("numberOfShards") && cluster.isCoordinator()) {
|
||||
r.parameter.numberOfShards = body.numberOfShards || 0;
|
||||
}
|
||||
|
@ -178,7 +165,7 @@ function parseBodyForCreateCollection (req, res) {
|
|||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @startDocuBlock JSF_post_api_collection
|
||||
/// @brief creates a collection
|
||||
|
@ -203,7 +190,7 @@ function parseBodyForCreateCollection (req, res) {
|
|||
///
|
||||
/// - *journalSize* (optional, default is a
|
||||
/// configuration parameter): The maximal size of
|
||||
/// a journal or datafile.
|
||||
/// a journal or datafile.
|
||||
/// **Note**: This also limits the maximal
|
||||
/// size of a single object. Must be at least 1MB.
|
||||
///
|
||||
|
@ -217,21 +204,21 @@ function parseBodyForCreateCollection (req, res) {
|
|||
/// collection data is kept in-memory only and not made persistent. Unloading
|
||||
/// the collection will cause the collection data to be discarded. Stopping
|
||||
/// or re-starting the server will also cause full loss of data in the
|
||||
/// collection. Setting this option will make the resulting collection be
|
||||
/// collection. Setting this option will make the resulting collection be
|
||||
/// slightly faster than regular collections because ArangoDB does not
|
||||
/// enforce any synchronisation to disk and does not calculate any CRC
|
||||
/// enforce any synchronisation to disk and does not calculate any CRC
|
||||
/// checksums for datafiles (as there are no datafiles).
|
||||
///
|
||||
/// This option should threrefore be used for cache-type collections only,
|
||||
/// This option should threrefore be used for cache-type collections only,
|
||||
/// and not for data that cannot be re-created otherwise.
|
||||
///
|
||||
/// - *keyOptions* (optional) additional options for key generation. If
|
||||
/// specified, then *keyOptions* should be a JSON array containing the
|
||||
/// following attributes (note: some of them are optional):
|
||||
/// - *type*: specifies the type of the key generator. The currently
|
||||
/// - *type*: specifies the type of the key generator. The currently
|
||||
/// available generators are *traditional* and *autoincrement*.
|
||||
/// - *allowUserKeys*: if set to *true*, then it is allowed to supply
|
||||
/// own key values in the *_key* attribute of a document. If set to
|
||||
/// own key values in the *_key* attribute of a document. If set to
|
||||
/// *false*, then the key generator will solely be responsible for
|
||||
/// generating keys and supplying own key values in the *_key* attribute
|
||||
/// of documents is considered an error.
|
||||
|
@ -253,16 +240,16 @@ function parseBodyForCreateCollection (req, res) {
|
|||
/// attribute determines which document attributes are used to determine the
|
||||
/// target shard for documents. Documents are sent to shards based on the
|
||||
/// values of their shard key attributes. The values of all shard
|
||||
/// key attributes in a document are hashed, and the hash value is used to
|
||||
/// determine the target shard.
|
||||
/// key attributes in a document are hashed, and the hash value is used to
|
||||
/// determine the target shard.
|
||||
/// **Note**: Values of shard key attributes cannot be changed once set.
|
||||
/// This option is meaningless in a single server setup.
|
||||
/// @EXAMPLES
|
||||
///
|
||||
/// @EXAMPLE_ARANGOSH_RUN{RestCollectionCreateCollection}
|
||||
/// var url = "/_api/collection";
|
||||
/// var body = {
|
||||
/// name: "testCollectionBasics"
|
||||
/// var body = {
|
||||
/// name: "testCollectionBasics"
|
||||
/// };
|
||||
///
|
||||
/// var response = logCurlRequest('POST', url, JSON.stringify(body));
|
||||
|
@ -270,9 +257,9 @@ function parseBodyForCreateCollection (req, res) {
|
|||
/// assert(response.code === 200);
|
||||
///
|
||||
/// logJsonResponse(response);
|
||||
/// body = {
|
||||
/// name: "testCollectionEdges",
|
||||
/// type : 3
|
||||
/// body = {
|
||||
/// name: "testCollectionEdges",
|
||||
/// type : 3
|
||||
/// };
|
||||
///
|
||||
/// var response = logCurlRequest('POST', url, JSON.stringify(body));
|
||||
|
@ -287,12 +274,12 @@ function parseBodyForCreateCollection (req, res) {
|
|||
///
|
||||
/// @EXAMPLE_ARANGOSH_RUN{RestCollectionCreateKeyopt}
|
||||
/// var url = "/_api/collection";
|
||||
/// var body = {
|
||||
/// name: "testCollectionUsers",
|
||||
/// keyOptions : {
|
||||
/// type : "autoincrement",
|
||||
/// increment : 5,
|
||||
/// allowUserKeys : true
|
||||
/// var body = {
|
||||
/// name: "testCollectionUsers",
|
||||
/// keyOptions : {
|
||||
/// type : "autoincrement",
|
||||
/// increment : 5,
|
||||
/// allowUserKeys : true
|
||||
/// }
|
||||
/// };
|
||||
///
|
||||
|
@ -313,7 +300,7 @@ function post_api_collection (req, res) {
|
|||
if (r.bodyIsEmpty) {
|
||||
return; // error in JSON, is already reported
|
||||
}
|
||||
|
||||
|
||||
if (r.name === "") {
|
||||
actions.resultBad(req, res, arangodb.ERROR_ARANGO_ILLEGAL_NAME,
|
||||
"name must be non-empty");
|
||||
|
@ -350,7 +337,7 @@ function post_api_collection (req, res) {
|
|||
result.numberOfShards = collection.numberOfShards;
|
||||
result.distributeShardsLike = collection.distributeShardsLike || "";
|
||||
}
|
||||
|
||||
|
||||
var headers = {
|
||||
location: databasePrefix(req, "/" + API + "/" + result.name)
|
||||
};
|
||||
|
@ -374,7 +361,7 @@ function post_api_collection (req, res) {
|
|||
/// Whether or not system collections should be excluded from the result.
|
||||
///
|
||||
/// @RESTDESCRIPTION
|
||||
/// Returns an object with an attribute *collections* containing a
|
||||
/// Returns an object with an attribute *collections* containing a
|
||||
/// list of all collection descriptions. The same information is also
|
||||
/// available in the *names* as hash map with the collection names
|
||||
/// as keys.
|
||||
|
@ -439,7 +426,7 @@ function get_api_collections (req, res) {
|
|||
///
|
||||
/// @RESTURLPARAM{collection-name,string,required}
|
||||
/// The name of the collection.
|
||||
///
|
||||
///
|
||||
/// @RESTDESCRIPTION
|
||||
/// The result is an object describing the collection with the following
|
||||
/// attributes:
|
||||
|
@ -467,9 +454,9 @@ function get_api_collections (req, res) {
|
|||
/// If the *collection-name* is unknown, then a *HTTP 404* is
|
||||
/// returned.
|
||||
/// @endDocuBlock
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @startDocuBlock JSA_get_api_collection_properties
|
||||
///
|
||||
/// @RESTHEADER{GET /_api/collection/{collection-name}/properties, Read properties of a collection}
|
||||
|
@ -498,8 +485,8 @@ function get_api_collections (req, res) {
|
|||
/// In a cluster setup, the result will also contain the following attributes:
|
||||
/// - *numberOfShards*: the number of shards of the collection.
|
||||
///
|
||||
/// - *shardKeys*: contains the names of document attributes that are used to
|
||||
/// determine the target shard for documents.
|
||||
/// - *shardKeys*: contains the names of document attributes that are used to
|
||||
/// determine the target shard for documents.
|
||||
/// @RESTRETURNCODES
|
||||
///
|
||||
/// @RESTRETURNCODE{400}
|
||||
|
@ -543,9 +530,9 @@ function get_api_collections (req, res) {
|
|||
/// db._drop(cn);
|
||||
/// @END_EXAMPLE_ARANGOSH_RUN
|
||||
/// @endDocuBlock
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @startDocuBlock JSA_get_api_collection_count
|
||||
///
|
||||
/// @RESTHEADER{GET /_api/collection/{collection-name}/count, Return number of documents in a collection}
|
||||
|
@ -592,9 +579,9 @@ function get_api_collections (req, res) {
|
|||
/// db._drop(cn);
|
||||
/// @END_EXAMPLE_ARANGOSH_RUN
|
||||
/// @endDocuBlock
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @startDocuBlock JSA_get_api_collection_figures
|
||||
///
|
||||
/// @RESTHEADER{GET /_api/collection/{collection-name}/figures, Return statistics for a collection}
|
||||
|
@ -606,16 +593,16 @@ function get_api_collections (req, res) {
|
|||
///
|
||||
/// @RESTDESCRIPTION
|
||||
/// In addition to the above, the result also contains the number of documents
|
||||
/// and additional statistical information about the collection.
|
||||
/// and additional statistical information about the collection.
|
||||
/// **Note** : This will always load the collection into memory.
|
||||
///
|
||||
/// - *count*: The number of documents currently present in the collection.
|
||||
///
|
||||
/// * *figures.alive.count*: The number of curretly active documents in all datafiles
|
||||
/// * *figures.alive.count*: The number of curretly active documents in all datafiles
|
||||
/// and journals of the collection. Documents that are contained in the
|
||||
/// write-ahead log only are not reported in this figure.
|
||||
///
|
||||
/// * *figures.alive.size*: The total size in bytes used by all active documents of
|
||||
/// * *figures.alive.size*: The total size in bytes used by all active documents of
|
||||
/// the collection. Documents that are contained in the write-ahead log only are
|
||||
/// not reported in this figure.
|
||||
///
|
||||
|
@ -658,7 +645,7 @@ function get_api_collections (req, res) {
|
|||
/// not reported in this figure.
|
||||
/// * *figures.attributes.size*: The total size of the attribute data (in bytes).
|
||||
/// Note: the value includes data of attributes that are not in use anymore.
|
||||
/// Attributes that are contained in the write-ahead log only are not
|
||||
/// Attributes that are contained in the write-ahead log only are not
|
||||
/// reported in this figure.
|
||||
///
|
||||
/// * *figures.indexes.count*: The total number of indexes defined for the
|
||||
|
@ -678,7 +665,7 @@ function get_api_collections (req, res) {
|
|||
///
|
||||
/// **Note**: collection data that are stored in the write-ahead log only are
|
||||
/// not reported in the results. When the write-ahead log is collected, documents
|
||||
/// might be added to journals and datafiles of the collection, which may modify
|
||||
/// might be added to journals and datafiles of the collection, which may modify
|
||||
/// the figures of the collection.
|
||||
///
|
||||
/// Additionally, the filesizes of collection and index parameter JSON files are
|
||||
|
@ -691,8 +678,8 @@ function get_api_collections (req, res) {
|
|||
///
|
||||
/// That means that the figures reported do not reflect the actual disk
|
||||
/// usage of the collection with 100% accuracy. The actual disk usage of
|
||||
/// a collection is normally slightly higher than the sum of the reported
|
||||
/// *fileSize* values. Still the sum of the *fileSize* values can still be
|
||||
/// a collection is normally slightly higher than the sum of the reported
|
||||
/// *fileSize* values. Still the sum of the *fileSize* values can still be
|
||||
/// used as a lower bound approximation of the disk usage.
|
||||
///
|
||||
/// @RESTRETURNCODES
|
||||
|
@ -725,9 +712,9 @@ function get_api_collections (req, res) {
|
|||
/// db._drop(cn);
|
||||
/// @END_EXAMPLE_ARANGOSH_RUN
|
||||
/// @endDocuBlock
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @startDocuBlock JSA_get_api_collection_revision
|
||||
///
|
||||
/// @RESTHEADER{GET /_api/collection/{collection-name}/revision, Return collection revision id}
|
||||
|
@ -775,7 +762,7 @@ function get_api_collections (req, res) {
|
|||
/// @endDocuBlock
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @startDocuBlock JSA_get_api_collection_checksum
|
||||
///
|
||||
/// @RESTHEADER{GET /_api/collection/{collection-name}/checksum, Return checksum for the collection}
|
||||
|
@ -794,23 +781,23 @@ function get_api_collections (req, res) {
|
|||
/// Whether or not to include document body data in the checksum calculation.
|
||||
///
|
||||
/// @RESTDESCRIPTION
|
||||
/// Will calculate a checksum of the meta-data (keys and optionally revision ids) and
|
||||
/// Will calculate a checksum of the meta-data (keys and optionally revision ids) and
|
||||
/// optionally the document data in the collection.
|
||||
///
|
||||
/// The checksum can be used to compare if two collections on different ArangoDB
|
||||
/// instances contain the same contents. The current revision of the collection is
|
||||
/// returned too so one can make sure the checksums are calculated for the same
|
||||
/// instances contain the same contents. The current revision of the collection is
|
||||
/// returned too so one can make sure the checksums are calculated for the same
|
||||
/// state of data.
|
||||
///
|
||||
/// By default, the checksum will only be calculated on the *_key* system attribute
|
||||
/// of the documents contained in the collection. For edge collections, the system
|
||||
/// of the documents contained in the collection. For edge collections, the system
|
||||
/// attributes *_from* and *_to* will also be included in the calculation.
|
||||
///
|
||||
/// By setting the optional URL parameter *withRevisions* to *true*, then revision
|
||||
/// ids (*_rev* system attributes) are included in the checksumming.
|
||||
///
|
||||
/// By providing the optional URL parameter *withData* with a value of *true*,
|
||||
/// the user-defined document attributes will be included in the calculation too.
|
||||
/// By providing the optional URL parameter *withData* with a value of *true*,
|
||||
/// the user-defined document attributes will be included in the calculation too.
|
||||
/// **Note**: Including user-defined attributes will make the checksumming slower.
|
||||
///
|
||||
/// The response is a JSON object with the following attributes:
|
||||
|
@ -878,25 +865,25 @@ 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>
|
||||
// .............................................................................
|
||||
|
||||
name = decodeURIComponent(req.suffix[0]);
|
||||
|
||||
|
||||
var collection = arangodb.db._collection(name);
|
||||
|
||||
if (collection === null) {
|
||||
actions.collectionNotFound(req, res, name);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var headers;
|
||||
|
||||
// .............................................................................
|
||||
|
@ -905,8 +892,8 @@ function get_api_collection (req, res) {
|
|||
|
||||
if (req.suffix.length === 1) {
|
||||
result = collectionRepresentation(collection, false, false, false);
|
||||
headers = {
|
||||
location : databasePrefix(req, "/" + API + "/" + collection.name())
|
||||
headers = {
|
||||
location : databasePrefix(req, "/" + API + "/" + collection.name())
|
||||
};
|
||||
actions.resultOk(req, res, actions.HTTP_OK, result, headers);
|
||||
return;
|
||||
|
@ -929,7 +916,7 @@ function get_api_collection (req, res) {
|
|||
withRevisions = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (req.parameters.hasOwnProperty('withData')) {
|
||||
value = req.parameters.withData.toLowerCase();
|
||||
if (value === 'true' || value === 'yes' || value === 'on' || value === 'y' || value === '1') {
|
||||
|
@ -943,15 +930,15 @@ function get_api_collection (req, res) {
|
|||
result.revision = checksum.revision;
|
||||
actions.resultOk(req, res, actions.HTTP_OK, result);
|
||||
}
|
||||
|
||||
|
||||
// .............................................................................
|
||||
// /_api/collection/<identifier>/figures
|
||||
// .............................................................................
|
||||
|
||||
else if (sub === "figures") {
|
||||
result = collectionRepresentation(collection, true, true, true);
|
||||
headers = {
|
||||
location : databasePrefix(req, "/" + API + "/" + collection.name() + "/figures")
|
||||
headers = {
|
||||
location : databasePrefix(req, "/" + API + "/" + collection.name() + "/figures")
|
||||
};
|
||||
actions.resultOk(req, res, actions.HTTP_OK, result, headers);
|
||||
}
|
||||
|
@ -962,8 +949,8 @@ function get_api_collection (req, res) {
|
|||
|
||||
else if (sub === "count") {
|
||||
result = collectionRepresentation(collection, true, true, false);
|
||||
headers = {
|
||||
location : databasePrefix(req, "/" + API + "/" + collection.name() + "/count")
|
||||
headers = {
|
||||
location : databasePrefix(req, "/" + API + "/" + collection.name() + "/count")
|
||||
};
|
||||
actions.resultOk(req, res, actions.HTTP_OK, result, headers);
|
||||
}
|
||||
|
@ -974,8 +961,8 @@ function get_api_collection (req, res) {
|
|||
|
||||
else if (sub === "properties") {
|
||||
result = collectionRepresentation(collection, true, false, false);
|
||||
headers = {
|
||||
location : databasePrefix(req, "/" + API + "/" + collection.name() + "/properties")
|
||||
headers = {
|
||||
location : databasePrefix(req, "/" + API + "/" + collection.name() + "/properties")
|
||||
};
|
||||
actions.resultOk(req, res, actions.HTTP_OK, result, headers);
|
||||
}
|
||||
|
@ -1019,8 +1006,8 @@ function get_api_collection (req, res) {
|
|||
/// The request might optionally contain the following attribute:
|
||||
///
|
||||
/// - *count*: If set, this controls whether the return value should include
|
||||
/// the number of documents in the collection. Setting *count* to
|
||||
/// *false* may speed up loading a collection. The default value for
|
||||
/// the number of documents in the collection. Setting *count* to
|
||||
/// *false* may speed up loading a collection. The default value for
|
||||
/// *count* is *true*.
|
||||
///
|
||||
/// On success an object with the following attributes is returned:
|
||||
|
@ -1236,7 +1223,7 @@ function put_api_collection_truncate (req, res, collection) {
|
|||
/// - 3: edges collection
|
||||
///
|
||||
/// **Note**: some other collection properties, such as *type*, *isVolatile*,
|
||||
/// *numberOfShards* or *shardKeys* cannot be changed once a collection is
|
||||
/// *numberOfShards* or *shardKeys* cannot be changed once a collection is
|
||||
/// created.
|
||||
///
|
||||
/// @EXAMPLES
|
||||
|
@ -1361,12 +1348,12 @@ function put_api_collection_rename (req, res, collection) {
|
|||
/// The name of the collection.
|
||||
///
|
||||
/// @RESTDESCRIPTION
|
||||
/// Rotates the journal of a collection. The current journal of the collection will be closed
|
||||
/// Rotates the journal of a collection. The current journal of the collection will be closed
|
||||
/// and made a read-only datafile. The purpose of the rotate method is to make the data in
|
||||
/// the file available for compaction (compaction is only performed for read-only datafiles, and
|
||||
/// not for journals).
|
||||
///
|
||||
/// Saving new data in the collection subsequently will create a new journal file
|
||||
/// Saving new data in the collection subsequently will create a new journal file
|
||||
/// automatically if there is no current journal.
|
||||
///
|
||||
/// If returns an object with the attributes
|
||||
|
@ -1580,7 +1567,6 @@ function delete_api_collection (req, res) {
|
|||
|
||||
actions.defineHttp({
|
||||
url : API,
|
||||
context : "api",
|
||||
|
||||
callback : function (req, res) {
|
||||
try {
|
||||
|
@ -1606,15 +1592,11 @@ actions.defineHttp({
|
|||
}
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @\\}"
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014 triAGENS GmbH, Cologne, Germany
|
||||
/// Copyright 2014 ArangoDB 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.
|
||||
|
@ -22,7 +22,7 @@
|
|||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Jan Steemann
|
||||
/// @author Copyright 2014, triAGENS GmbH, Cologne, Germany
|
||||
|
@ -43,7 +43,6 @@ var configuration = require("org/arangodb/configuration");
|
|||
actions.defineHttp({
|
||||
url: "_admin/configuration/notifications/versions",
|
||||
prefix: false,
|
||||
context: "api",
|
||||
|
||||
callback : function (req, res) {
|
||||
var json;
|
||||
|
@ -82,5 +81,5 @@ actions.defineHttp({
|
|||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "/// @brief\\|/// @addtogroup\\|/// @page\\|// --SECTION--\\|/// @\\}\\|/\\*jslint"
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2012 triagens GmbH, Cologne, Germany
|
||||
/// Copyright 2014 ArangoDB 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.
|
||||
|
@ -22,10 +22,11 @@
|
|||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Achim Brandt
|
||||
/// @author Jan Steemann
|
||||
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
|
||||
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -61,34 +62,34 @@ var internal = require("internal");
|
|||
///
|
||||
/// - *count*: boolean flag that indicates whether the number of documents
|
||||
/// in the result set should be returned in the "count" attribute of the result (optional).
|
||||
/// Calculating the "count" attribute might in the future have a performance
|
||||
/// impact for some queries so this option is turned off by default, and "count"
|
||||
/// Calculating the "count" attribute might in the future have a performance
|
||||
/// impact for some queries so this option is turned off by default, and "count"
|
||||
/// is only returned when requested.
|
||||
///
|
||||
/// - *batchSize*: maximum number of result documents to be transferred from
|
||||
/// the server to the client in one roundtrip (optional). If this attribute is
|
||||
/// not set, a server-controlled default value will be used.
|
||||
///
|
||||
/// - *ttl*: an optional time-to-live for the cursor (in seconds). The cursor will be
|
||||
/// - *ttl*: an optional time-to-live for the cursor (in seconds). The cursor will be
|
||||
/// removed on the server automatically after the specified amount of time. This
|
||||
/// is useful to ensure garbage collection of cursors that are not fully fetched
|
||||
/// is useful to ensure garbage collection of cursors that are not fully fetched
|
||||
/// by clients. If not set, a server-defined value will be used.
|
||||
///
|
||||
/// - *bindVars*: key/value list of bind parameters (optional).
|
||||
/// - *bindVars*: key/value list of bind parameters (optional).
|
||||
///
|
||||
/// - *options*: key/value list of extra options for the query (optional).
|
||||
///
|
||||
/// The following options are supported at the moment:
|
||||
///
|
||||
///
|
||||
/// - *fullCount*: if set to *true* and the query contains a *LIMIT* clause, then the
|
||||
/// result will contain an extra attribute *extra* with a sub-attribute *fullCount*.
|
||||
/// result will contain an extra attribute *extra* with a sub-attribute *fullCount*.
|
||||
/// This sub-attribute will contain the number of documents in the result before the
|
||||
/// last LIMIT in the query was applied. It can be used to count the number of documents that
|
||||
/// match certain filter criteria, but only return a subset of them, in one go.
|
||||
/// It is thus similar to MySQL's *SQL_CALC_FOUND_ROWS* hint. Note that setting the option
|
||||
/// match certain filter criteria, but only return a subset of them, in one go.
|
||||
/// It is thus similar to MySQL's *SQL_CALC_FOUND_ROWS* hint. Note that setting the option
|
||||
/// will disable a few LIMIT optimizations and may lead to more documents being processed,
|
||||
/// and thus make queries run longer. Note that the *fullCount* sub-attribute will only
|
||||
/// be present in the result if the query has a LIMIT clause and the LIMIT clause is
|
||||
/// be present in the result if the query has a LIMIT clause and the LIMIT clause is
|
||||
/// actually used in the query.
|
||||
///
|
||||
/// If the result set can be created by the server, the server will respond with
|
||||
|
@ -104,7 +105,7 @@ var internal = require("internal");
|
|||
///
|
||||
/// - *result*: an array of result documents (might be empty if query has no results)
|
||||
///
|
||||
/// - *hasMore*: a boolean indicator whether there are more results
|
||||
/// - *hasMore*: a boolean indicator whether there are more results
|
||||
/// available for the cursor on the server
|
||||
///
|
||||
/// - *count*: the total number of result documents available (only
|
||||
|
@ -138,7 +139,7 @@ var internal = require("internal");
|
|||
/// A list of query errors can be found (../ArangoErrors/README.md) here.
|
||||
///
|
||||
/// @RESTRETURNCODES
|
||||
///
|
||||
///
|
||||
/// @RESTRETURNCODE{201}
|
||||
/// is returned if the result set can be created by the server.
|
||||
///
|
||||
|
@ -161,21 +162,21 @@ var internal = require("internal");
|
|||
/// var cn = "products";
|
||||
/// db._drop(cn);
|
||||
/// db._create(cn);
|
||||
///
|
||||
///
|
||||
/// db.products.save({"hello1":"world1"});
|
||||
/// db.products.save({"hello2":"world1"});
|
||||
///
|
||||
/// var url = "/_api/cursor";
|
||||
/// var body = {
|
||||
/// query: "FOR p IN products LIMIT 2 RETURN p",
|
||||
/// count: true,
|
||||
/// count: true,
|
||||
/// batchSize: 2
|
||||
/// };
|
||||
///
|
||||
///
|
||||
/// var response = logCurlRequest('POST', url, JSON.stringify(body));
|
||||
///
|
||||
///
|
||||
/// assert(response.code === 201);
|
||||
///
|
||||
///
|
||||
/// logJsonResponse(response);
|
||||
/// @END_EXAMPLE_ARANGOSH_RUN
|
||||
///
|
||||
|
@ -185,7 +186,7 @@ var internal = require("internal");
|
|||
/// var cn = "products";
|
||||
/// db._drop(cn);
|
||||
/// db._create(cn);
|
||||
///
|
||||
///
|
||||
/// db.products.save({"hello1":"world1"});
|
||||
/// db.products.save({"hello2":"world1"});
|
||||
/// db.products.save({"hello3":"world1"});
|
||||
|
@ -193,16 +194,16 @@ var internal = require("internal");
|
|||
/// db.products.save({"hello5":"world1"});
|
||||
///
|
||||
/// var url = "/_api/cursor";
|
||||
/// var body = {
|
||||
/// var body = {
|
||||
/// query: "FOR p IN products LIMIT 5 RETURN p",
|
||||
/// count: true,
|
||||
/// batchSize: 2
|
||||
/// };
|
||||
///
|
||||
///
|
||||
/// var response = logCurlRequest('POST', url, JSON.stringify(body));
|
||||
///
|
||||
///
|
||||
/// assert(response.code === 201);
|
||||
///
|
||||
///
|
||||
/// logJsonResponse(response);
|
||||
/// @END_EXAMPLE_ARANGOSH_RUN
|
||||
///
|
||||
|
@ -210,29 +211,29 @@ var internal = require("internal");
|
|||
///
|
||||
/// @EXAMPLE_ARANGOSH_RUN{RestCursorCreateCursorOption}
|
||||
/// var url = "/_api/cursor";
|
||||
/// var body = {
|
||||
/// var body = {
|
||||
/// query: "FOR i IN 1..1000 FILTER i > 500 LIMIT 10 RETURN i",
|
||||
/// count: true,
|
||||
/// options: {
|
||||
/// fullCount: true
|
||||
/// }
|
||||
/// };
|
||||
///
|
||||
///
|
||||
/// var response = logCurlRequest('POST', url, JSON.stringify(body));
|
||||
///
|
||||
///
|
||||
/// assert(response.code === 201);
|
||||
///
|
||||
///
|
||||
/// logJsonResponse(response);
|
||||
/// @END_EXAMPLE_ARANGOSH_RUN
|
||||
///
|
||||
/// Executes a data-modification query and retrieves the number of
|
||||
/// Executes a data-modification query and retrieves the number of
|
||||
/// modified documents:
|
||||
///
|
||||
/// @EXAMPLE_ARANGOSH_RUN{RestCursorDeleteQuery}
|
||||
/// var cn = "products";
|
||||
/// db._drop(cn);
|
||||
/// db._create(cn);
|
||||
///
|
||||
///
|
||||
/// db.products.save({"hello1":"world1"});
|
||||
/// db.products.save({"hello2":"world1"});
|
||||
///
|
||||
|
@ -240,13 +241,13 @@ var internal = require("internal");
|
|||
/// var body = {
|
||||
/// query: "FOR p IN products REMOVE p IN products"
|
||||
/// };
|
||||
///
|
||||
///
|
||||
/// var response = logCurlRequest('POST', url, JSON.stringify(body));
|
||||
///
|
||||
///
|
||||
/// assert(response.code === 201);
|
||||
/// assert(JSON.parse(response.body).extra.operations.executed === 2);
|
||||
/// assert(JSON.parse(response.body).extra.operations.ignored === 0);
|
||||
///
|
||||
///
|
||||
/// logJsonResponse(response);
|
||||
/// @END_EXAMPLE_ARANGOSH_RUN
|
||||
///
|
||||
|
@ -256,20 +257,20 @@ var internal = require("internal");
|
|||
/// var cn = "products";
|
||||
/// db._drop(cn);
|
||||
/// db._create(cn);
|
||||
///
|
||||
///
|
||||
/// db.products.save({ _key: "foo" });
|
||||
///
|
||||
/// var url = "/_api/cursor";
|
||||
/// var body = {
|
||||
/// query: "REMOVE 'bar' IN products OPTIONS { ignoreErrors: true }"
|
||||
/// };
|
||||
///
|
||||
///
|
||||
/// var response = logCurlRequest('POST', url, JSON.stringify(body));
|
||||
///
|
||||
///
|
||||
/// assert(response.code === 201);
|
||||
/// assert(JSON.parse(response.body).extra.operations.executed === 0);
|
||||
/// assert(JSON.parse(response.body).extra.operations.ignored === 1);
|
||||
///
|
||||
///
|
||||
/// logJsonResponse(response);
|
||||
/// @END_EXAMPLE_ARANGOSH_RUN
|
||||
///
|
||||
|
@ -279,11 +280,11 @@ var internal = require("internal");
|
|||
///
|
||||
/// @EXAMPLE_ARANGOSH_RUN{RestCursorCreateCursorMissingBody}
|
||||
/// var url = "/_api/cursor";
|
||||
///
|
||||
///
|
||||
/// var response = logCurlRequest('POST', url, '');
|
||||
///
|
||||
///
|
||||
/// assert(response.code === 400);
|
||||
///
|
||||
///
|
||||
/// logJsonResponse(response);
|
||||
/// @END_EXAMPLE_ARANGOSH_RUN
|
||||
///
|
||||
|
@ -291,16 +292,16 @@ var internal = require("internal");
|
|||
///
|
||||
/// @EXAMPLE_ARANGOSH_RUN{RestCursorCreateCursorUnknownCollection}
|
||||
/// var url = "/_api/cursor";
|
||||
/// var body = {
|
||||
/// query: "FOR u IN unknowncoll LIMIT 2 RETURN u",
|
||||
/// count: true,
|
||||
/// batchSize: 2
|
||||
/// var body = {
|
||||
/// query: "FOR u IN unknowncoll LIMIT 2 RETURN u",
|
||||
/// count: true,
|
||||
/// batchSize: 2
|
||||
/// };
|
||||
///
|
||||
///
|
||||
/// var response = logCurlRequest('POST', url, JSON.stringify(body));
|
||||
///
|
||||
///
|
||||
/// assert(response.code === 404);
|
||||
///
|
||||
///
|
||||
/// logJsonResponse(response);
|
||||
/// @END_EXAMPLE_ARANGOSH_RUN
|
||||
///
|
||||
|
@ -311,18 +312,18 @@ var internal = require("internal");
|
|||
/// var cn = "products";
|
||||
/// db._drop(cn);
|
||||
/// db._create(cn);
|
||||
///
|
||||
///
|
||||
/// db.products.save({ _key: "bar" });
|
||||
///
|
||||
/// var url = "/_api/cursor";
|
||||
/// var body = {
|
||||
/// query: "REMOVE 'foo' IN products"
|
||||
/// };
|
||||
///
|
||||
///
|
||||
/// var response = logCurlRequest('POST', url, JSON.stringify(body));
|
||||
///
|
||||
///
|
||||
/// assert(response.code === 404);
|
||||
///
|
||||
///
|
||||
/// logJsonResponse(response);
|
||||
/// @END_EXAMPLE_ARANGOSH_RUN
|
||||
///
|
||||
|
@ -345,12 +346,12 @@ function post_api_cursor(req, res) {
|
|||
var cursor;
|
||||
|
||||
if (json.query !== undefined) {
|
||||
cursor = internal.AQL_QUERY(json.query,
|
||||
json.bindVars,
|
||||
{
|
||||
cursor = internal.AQL_QUERY(json.query,
|
||||
json.bindVars,
|
||||
{
|
||||
count : json.count || false,
|
||||
batchSize: json.batchSize || 1000,
|
||||
ttl: json.ttl
|
||||
ttl: json.ttl
|
||||
},
|
||||
json.options);
|
||||
}
|
||||
|
@ -358,7 +359,7 @@ function post_api_cursor(req, res) {
|
|||
actions.resultBad(req, res, arangodb.ERROR_QUERY_EMPTY);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// error occurred
|
||||
if (cursor instanceof Error) {
|
||||
actions.resultException(req, res, cursor, undefined, false);
|
||||
|
@ -366,11 +367,11 @@ function post_api_cursor(req, res) {
|
|||
}
|
||||
|
||||
// this might dispose or persist the cursor
|
||||
actions.resultCursor(req,
|
||||
res,
|
||||
cursor,
|
||||
actions.HTTP_CREATED,
|
||||
{
|
||||
actions.resultCursor(req,
|
||||
res,
|
||||
cursor,
|
||||
actions.HTTP_CREATED,
|
||||
{
|
||||
countRequested: json.count ? true : false
|
||||
});
|
||||
}
|
||||
|
@ -402,9 +403,9 @@ function post_api_cursor(req, res) {
|
|||
/// *false*, the client can stop.
|
||||
///
|
||||
/// @RESTRETURNCODES
|
||||
///
|
||||
///
|
||||
/// @RESTRETURNCODE{200}
|
||||
/// The server will respond with *HTTP 200* in case of success.
|
||||
/// The server will respond with *HTTP 200* in case of success.
|
||||
///
|
||||
/// @RESTRETURNCODE{400}
|
||||
/// If the cursor identifier is omitted, the server will respond with *HTTP 404*.
|
||||
|
@ -422,7 +423,7 @@ function post_api_cursor(req, res) {
|
|||
/// var cn = "products";
|
||||
/// db._drop(cn);
|
||||
/// db._create(cn);
|
||||
///
|
||||
///
|
||||
/// db.products.save({"hello1":"world1"});
|
||||
/// db.products.save({"hello2":"world1"});
|
||||
/// db.products.save({"hello3":"world1"});
|
||||
|
@ -431,9 +432,9 @@ function post_api_cursor(req, res) {
|
|||
///
|
||||
/// var url = "/_api/cursor";
|
||||
/// var body = {
|
||||
/// query: "FOR p IN products LIMIT 5 RETURN p",
|
||||
/// count: true,
|
||||
/// batchSize: 2
|
||||
/// query: "FOR p IN products LIMIT 5 RETURN p",
|
||||
/// count: true,
|
||||
/// batchSize: 2
|
||||
/// };
|
||||
/// var response = logCurlRequest('POST', url, JSON.stringify(body));
|
||||
///
|
||||
|
@ -441,7 +442,7 @@ function post_api_cursor(req, res) {
|
|||
/// var _id = JSON.parse(body).id;
|
||||
/// response = logCurlRequest('PUT', url + '/' + _id, '');
|
||||
/// assert(response.code === 200);
|
||||
///
|
||||
///
|
||||
/// logJsonResponse(response);
|
||||
/// @END_EXAMPLE_ARANGOSH_RUN
|
||||
///
|
||||
|
@ -449,11 +450,11 @@ function post_api_cursor(req, res) {
|
|||
///
|
||||
/// @EXAMPLE_ARANGOSH_RUN{RestCursorMissingCursorIdentifier}
|
||||
/// var url = "/_api/cursor";
|
||||
///
|
||||
///
|
||||
/// var response = logCurlRequest('PUT', url, '');
|
||||
///
|
||||
///
|
||||
/// assert(response.code === 400);
|
||||
///
|
||||
///
|
||||
/// logJsonResponse(response);
|
||||
/// @END_EXAMPLE_ARANGOSH_RUN
|
||||
///
|
||||
|
@ -461,11 +462,11 @@ function post_api_cursor(req, res) {
|
|||
///
|
||||
/// @EXAMPLE_ARANGOSH_RUN{RestCursorInvalidCursorIdentifier}
|
||||
/// var url = "/_api/cursor/123123";
|
||||
///
|
||||
///
|
||||
/// var response = logCurlRequest('PUT', url, '');
|
||||
///
|
||||
///
|
||||
/// assert(response.code === 404);
|
||||
///
|
||||
///
|
||||
/// logJsonResponse(response);
|
||||
/// @END_EXAMPLE_ARANGOSH_RUN
|
||||
/// @endDocuBlock
|
||||
|
@ -477,15 +478,15 @@ function put_api_cursor (req, res) {
|
|||
return;
|
||||
}
|
||||
|
||||
var cursorId = decodeURIComponent(req.suffix[0]);
|
||||
var cursorId = decodeURIComponent(req.suffix[0]);
|
||||
var cursor = CURSOR(cursorId);
|
||||
|
||||
if (! (cursor instanceof arangodb.ArangoCursor)) {
|
||||
actions.resultBad(req, res, arangodb.ERROR_CURSOR_NOT_FOUND);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
try {
|
||||
// note: this might dispose or persist the cursor
|
||||
actions.resultCursor(req, res, cursor, actions.HTTP_OK);
|
||||
}
|
||||
|
@ -509,18 +510,18 @@ function put_api_cursor (req, res) {
|
|||
/// The name of the cursor
|
||||
///
|
||||
/// @RESTDESCRIPTION
|
||||
/// Deletes the cursor and frees the resources associated with it.
|
||||
/// Deletes the cursor and frees the resources associated with it.
|
||||
///
|
||||
/// The cursor will automatically be destroyed on the server when the client has
|
||||
/// retrieved all documents from it. The client can also explicitly destroy the
|
||||
/// cursor at any earlier time using an HTTP DELETE request. The cursor id must
|
||||
/// be included as part of the URL.
|
||||
///
|
||||
/// Note: the server will also destroy abandoned cursors automatically after a
|
||||
///
|
||||
/// Note: the server will also destroy abandoned cursors automatically after a
|
||||
/// certain server-controlled timeout to avoid resource leakage.
|
||||
///
|
||||
/// @RESTRETURNCODES
|
||||
///
|
||||
///
|
||||
/// @RESTRETURNCODE{202}
|
||||
/// is returned if the server is aware of the cursor.
|
||||
///
|
||||
|
@ -535,7 +536,7 @@ function put_api_cursor (req, res) {
|
|||
/// var cn = "products";
|
||||
/// db._drop(cn);
|
||||
/// db._create(cn);
|
||||
///
|
||||
///
|
||||
/// db.products.save({"hello1":"world1"});
|
||||
/// db.products.save({"hello2":"world1"});
|
||||
/// db.products.save({"hello3":"world1"});
|
||||
|
@ -544,7 +545,7 @@ function put_api_cursor (req, res) {
|
|||
///
|
||||
/// var url = "/_api/cursor";
|
||||
/// var body = {
|
||||
/// query: "FOR p IN products LIMIT 5 RETURN p",
|
||||
/// query: "FOR p IN products LIMIT 5 RETURN p",
|
||||
/// count: true,
|
||||
/// batchSize: 2
|
||||
/// };
|
||||
|
@ -553,7 +554,7 @@ function put_api_cursor (req, res) {
|
|||
/// var body = response.body.replace(/\\/g, '');
|
||||
/// var _id = JSON.parse(body).id;
|
||||
/// response = logCurlRequest('DELETE', url + '/' + _id);
|
||||
///
|
||||
///
|
||||
/// assert(response.code === 202);
|
||||
/// @END_EXAMPLE_ARANGOSH_RUN
|
||||
/// @endDocuBlock
|
||||
|
@ -582,26 +583,25 @@ function delete_api_cursor(req, res) {
|
|||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief cursor actions gateway
|
||||
/// @brief cursor actions gateway
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : "_api/cursor",
|
||||
context : "api",
|
||||
|
||||
callback : function (req, res) {
|
||||
try {
|
||||
switch (req.requestType) {
|
||||
case actions.POST:
|
||||
post_api_cursor(req, res);
|
||||
case actions.POST:
|
||||
post_api_cursor(req, res);
|
||||
break;
|
||||
|
||||
case actions.PUT:
|
||||
put_api_cursor(req, res);
|
||||
case actions.PUT:
|
||||
put_api_cursor(req, res);
|
||||
break;
|
||||
|
||||
case actions.DELETE:
|
||||
delete_api_cursor(req, res);
|
||||
case actions.DELETE:
|
||||
delete_api_cursor(req, res);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -614,7 +614,11 @@ actions.defineHttp({
|
|||
}
|
||||
});
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @}\\)"
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2013 triagens GmbH, Cologne, Germany
|
||||
/// Copyright 2014 ArangoDB 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.
|
||||
|
@ -22,9 +22,10 @@
|
|||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Jan Steemann
|
||||
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
|
||||
/// @author Copyright 2013, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -38,11 +39,6 @@ var API = "_api/database";
|
|||
// --SECTION-- public functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup ArangoAPI
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @startDocuBlock JSF_get_api_database_list
|
||||
/// @brief retrieves a list of all existing databases
|
||||
|
@ -55,7 +51,7 @@ var API = "_api/database";
|
|||
/// **Note**: retrieving the list of databases is only possible from within the *_system* database.
|
||||
///
|
||||
/// @RESTRETURNCODES
|
||||
///
|
||||
///
|
||||
/// @RESTRETURNCODE{200}
|
||||
/// is returned if the list of database was compiled successfully.
|
||||
///
|
||||
|
@ -70,9 +66,9 @@ var API = "_api/database";
|
|||
/// @EXAMPLE_ARANGOSH_RUN{RestDatabaseGet}
|
||||
/// var url = "/_api/database";
|
||||
/// var response = logCurlRequest('GET', url);
|
||||
///
|
||||
///
|
||||
/// assert(response.code === 200);
|
||||
///
|
||||
///
|
||||
/// logJsonResponse(response);
|
||||
/// @END_EXAMPLE_ARANGOSH_RUN
|
||||
/// @endDocuBlock
|
||||
|
@ -85,11 +81,11 @@ var API = "_api/database";
|
|||
/// @RESTHEADER{GET /_api/database/user, List of accessible databases }
|
||||
///
|
||||
/// @RESTDESCRIPTION
|
||||
/// Retrieves the list of all databases the current user can access without
|
||||
/// Retrieves the list of all databases the current user can access without
|
||||
/// specifying a different username or password.
|
||||
///
|
||||
/// @RESTRETURNCODES
|
||||
///
|
||||
///
|
||||
/// @RESTRETURNCODE{200}
|
||||
/// is returned if the list of database was compiled successfully.
|
||||
///
|
||||
|
@ -101,9 +97,9 @@ var API = "_api/database";
|
|||
/// @EXAMPLE_ARANGOSH_RUN{RestDatabaseGetUser}
|
||||
/// var url = "/_api/database/user";
|
||||
/// var response = logCurlRequest('GET', url);
|
||||
///
|
||||
///
|
||||
/// assert(response.code === 200);
|
||||
///
|
||||
///
|
||||
/// logJsonResponse(response);
|
||||
/// @END_EXAMPLE_ARANGOSH_RUN
|
||||
/// @endDocuBlock
|
||||
|
@ -119,7 +115,7 @@ var API = "_api/database";
|
|||
/// Retrieves information about the current database
|
||||
///
|
||||
/// The response is a JSON object with the following attributes:
|
||||
///
|
||||
///
|
||||
/// - *name*: the name of the current database
|
||||
///
|
||||
/// - *id*: the id of the current database
|
||||
|
@ -129,7 +125,7 @@ var API = "_api/database";
|
|||
/// - *isSystem*: whether or not the current database is the *_system* database
|
||||
///
|
||||
/// @RESTRETURNCODES
|
||||
///
|
||||
///
|
||||
/// @RESTRETURNCODE{200}
|
||||
/// is returned if the information was retrieved successfully.
|
||||
///
|
||||
|
@ -144,20 +140,20 @@ var API = "_api/database";
|
|||
/// @EXAMPLE_ARANGOSH_RUN{RestDatabaseGetInfo}
|
||||
/// var url = "/_api/database/current";
|
||||
/// var response = logCurlRequest('GET', url);
|
||||
///
|
||||
///
|
||||
/// assert(response.code === 200);
|
||||
///
|
||||
///
|
||||
/// logJsonResponse(response);
|
||||
/// @END_EXAMPLE_ARANGOSH_RUN
|
||||
/// @endDocuBlock
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function get_api_database (req, res) {
|
||||
if (req.suffix.length > 1) {
|
||||
if (req.suffix.length > 1) {
|
||||
actions.resultBad(req, res, arangodb.ERROR_HTTP_BAD_PARAMETER);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var result;
|
||||
if (req.suffix.length === 0) {
|
||||
// list of all databases
|
||||
|
@ -228,7 +224,7 @@ function get_api_database (req, res) {
|
|||
/// The request body must be a JSON object with the attribute *name*. *name* must
|
||||
/// contain a valid database name.
|
||||
///
|
||||
/// The request body can optionally contain an attribute *users*, which then
|
||||
/// The request body can optionally contain an attribute *users*, which then
|
||||
/// must be a list of user objects to initially create for the new database.
|
||||
/// Each user object can contain the following attributes:
|
||||
///
|
||||
|
@ -253,12 +249,12 @@ function get_api_database (req, res) {
|
|||
/// **Note**: creating a new database is only possible from within the *_system* database.
|
||||
///
|
||||
/// @RESTRETURNCODES
|
||||
///
|
||||
///
|
||||
/// @RESTRETURNCODE{201}
|
||||
/// is returned if the database was created successfully.
|
||||
///
|
||||
/// @RESTRETURNCODE{400}
|
||||
/// is returned if the request parameters are invalid or if a database with the
|
||||
/// is returned if the request parameters are invalid or if a database with the
|
||||
/// specified name already exists.
|
||||
///
|
||||
/// @RESTRETURNCODE{403}
|
||||
|
@ -287,7 +283,7 @@ function get_api_database (req, res) {
|
|||
///
|
||||
/// db._dropDatabase(name);
|
||||
/// assert(response.code === 201);
|
||||
///
|
||||
///
|
||||
/// logJsonResponse(response);
|
||||
/// @END_EXAMPLE_ARANGOSH_RUN
|
||||
///
|
||||
|
@ -305,13 +301,13 @@ function get_api_database (req, res) {
|
|||
/// var data = {
|
||||
/// name: name,
|
||||
/// users: [
|
||||
/// {
|
||||
/// username : "admin",
|
||||
/// {
|
||||
/// username : "admin",
|
||||
/// passwd : "secret",
|
||||
/// active: true
|
||||
/// },
|
||||
/// {
|
||||
/// username : "tester",
|
||||
/// username : "tester",
|
||||
/// passwd : "test001",
|
||||
/// active: false
|
||||
/// }
|
||||
|
@ -321,27 +317,27 @@ function get_api_database (req, res) {
|
|||
///
|
||||
/// db._dropDatabase(name);
|
||||
/// assert(response.code === 201);
|
||||
///
|
||||
///
|
||||
/// logJsonResponse(response);
|
||||
/// @END_EXAMPLE_ARANGOSH_RUN
|
||||
/// @endDocuBlock
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function post_api_database (req, res) {
|
||||
if (req.suffix.length !== 0) {
|
||||
if (req.suffix.length !== 0) {
|
||||
actions.resultBad(req, res, arangodb.ERROR_HTTP_BAD_PARAMETER);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var json = actions.getJsonBody(req, res);
|
||||
|
||||
|
||||
if (json === undefined) {
|
||||
actions.resultBad(req, res, arangodb.ERROR_HTTP_BAD_PARAMETER);
|
||||
return;
|
||||
}
|
||||
|
||||
var options = json.options;
|
||||
|
||||
|
||||
if (options === undefined) {
|
||||
options = { };
|
||||
}
|
||||
|
@ -352,7 +348,7 @@ function post_api_database (req, res) {
|
|||
}
|
||||
|
||||
var users = json.users;
|
||||
|
||||
|
||||
if (users === undefined) {
|
||||
users = [ ];
|
||||
}
|
||||
|
@ -364,7 +360,7 @@ function post_api_database (req, res) {
|
|||
var i;
|
||||
for (i = 0; i < users.length; ++i) {
|
||||
var user = users[i];
|
||||
if (typeof user !== 'object' ||
|
||||
if (typeof user !== 'object' ||
|
||||
! user.hasOwnProperty('username') ||
|
||||
typeof(user.username) !== 'string') {
|
||||
// bad username
|
||||
|
@ -411,7 +407,7 @@ function post_api_database (req, res) {
|
|||
/// The *_system* database itself cannot be dropped.
|
||||
///
|
||||
/// @RESTRETURNCODES
|
||||
///
|
||||
///
|
||||
/// @RESTRETURNCODE{200}
|
||||
/// is returned if the database was dropped successfully.
|
||||
///
|
||||
|
@ -430,22 +426,22 @@ function post_api_database (req, res) {
|
|||
/// var url = "/_api/database";
|
||||
/// var name = "example";
|
||||
///
|
||||
/// db._createDatabase(name);
|
||||
/// db._createDatabase(name);
|
||||
/// var response = logCurlRequest('DELETE', url + '/' + name);
|
||||
///
|
||||
///
|
||||
/// assert(response.code === 200);
|
||||
///
|
||||
///
|
||||
/// logJsonResponse(response);
|
||||
/// @END_EXAMPLE_ARANGOSH_RUN
|
||||
/// @endDocuBlock
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function delete_api_database (req, res) {
|
||||
if (req.suffix.length !== 1) {
|
||||
if (req.suffix.length !== 1) {
|
||||
actions.resultBad(req, res, arangodb.ERROR_HTTP_BAD_PARAMETER);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var result = arangodb.db._dropDatabase(req.suffix[0]);
|
||||
|
||||
actions.resultOk(req, res, actions.HTTP_OK, { result : result });
|
||||
|
@ -457,7 +453,6 @@ function delete_api_database (req, res) {
|
|||
|
||||
actions.defineHttp({
|
||||
url : API,
|
||||
context : "api",
|
||||
|
||||
callback : function (req, res) {
|
||||
try {
|
||||
|
@ -480,15 +475,11 @@ actions.defineHttp({
|
|||
}
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @\\}"
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2012 triagens GmbH, Cologne, Germany
|
||||
/// Copyright 2014 ArangoDB 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.
|
||||
|
@ -22,9 +22,10 @@
|
|||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Achim Brandt
|
||||
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
|
||||
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -33,11 +34,6 @@ var actions = require("org/arangodb/actions");
|
|||
|
||||
var API = "/_api/edges";
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup ArangoAPI
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @startDocuBlock API_EDGE_READINOUTBOUND
|
||||
/// @brief get edges
|
||||
|
@ -79,7 +75,7 @@ var API = "/_api/edges";
|
|||
///
|
||||
/// var url = "/_api/edges/edges?vertex=vertices/1";
|
||||
/// var response = logCurlRequest('GET', url);
|
||||
///
|
||||
///
|
||||
/// assert(response.code === 200);
|
||||
///
|
||||
/// logJsonResponse(response);
|
||||
|
@ -103,7 +99,7 @@ var API = "/_api/edges";
|
|||
///
|
||||
/// var url = "/_api/edges/edges?vertex=vertices/1&direction=in";
|
||||
/// var response = logCurlRequest('GET', url);
|
||||
///
|
||||
///
|
||||
/// assert(response.code === 200);
|
||||
///
|
||||
/// logJsonResponse(response);
|
||||
|
@ -127,7 +123,7 @@ var API = "/_api/edges";
|
|||
///
|
||||
/// var url = "/_api/edges/edges?vertex=vertices/1&direction=out";
|
||||
/// var response = logCurlRequest('GET', url);
|
||||
///
|
||||
///
|
||||
/// assert(response.code === 200);
|
||||
///
|
||||
/// logJsonResponse(response);
|
||||
|
@ -140,10 +136,10 @@ var API = "/_api/edges";
|
|||
|
||||
function get_edges (req, res) {
|
||||
if (req.suffix.length !== 1) {
|
||||
actions.resultBad(req,
|
||||
res,
|
||||
actions.resultBad(req,
|
||||
res,
|
||||
arangodb.ERROR_HTTP_BAD_PARAMETER,
|
||||
"expect GET /" + API +
|
||||
"expect GET /" + API +
|
||||
"/<collection-identifier>?vertex=<vertex-handle>&direction=<direction>");
|
||||
return;
|
||||
}
|
||||
|
@ -174,7 +170,7 @@ function get_edges (req, res) {
|
|||
"<direction> must be any, in, or out, not: " + JSON.stringify(direction));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
actions.resultOk(req, res, actions.HTTP_OK, { edges: e });
|
||||
}
|
||||
|
||||
|
@ -184,7 +180,6 @@ function get_edges (req, res) {
|
|||
|
||||
actions.defineHttp({
|
||||
url : API,
|
||||
context : "api",
|
||||
|
||||
callback : function (req, res) {
|
||||
try {
|
||||
|
@ -201,11 +196,11 @@ actions.defineHttp({
|
|||
}
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @}\\)"
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2010-2012 triagens GmbH, Cologne, Germany
|
||||
/// Copyright 2014 ArangoDB 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.
|
||||
|
@ -22,9 +22,10 @@
|
|||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Jan Steemann
|
||||
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
|
||||
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -36,11 +37,6 @@ var internal = require("internal");
|
|||
// --SECTION-- public functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup ArangoAPI
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @startDocuBlock JSF_get_api_endpoint
|
||||
/// @brief returns a list of all endpoints
|
||||
|
@ -58,8 +54,8 @@ var internal = require("internal");
|
|||
/// accessed via the endpoint. If a list of mapped databases contains more than
|
||||
/// one database name, this means that any of the databases might be accessed
|
||||
/// via the endpoint, and the first database in the list will be treated as
|
||||
/// the default database for the endpoint. The default database will be used
|
||||
/// when an incoming request does not specify a database name in the request
|
||||
/// the default database for the endpoint. The default database will be used
|
||||
/// when an incoming request does not specify a database name in the request
|
||||
/// explicitly.
|
||||
///
|
||||
/// **Note**: retrieving the list of all endpoints is allowed in the system database
|
||||
|
@ -67,7 +63,7 @@ var internal = require("internal");
|
|||
/// an error.
|
||||
///
|
||||
/// @RESTRETURNCODES
|
||||
///
|
||||
///
|
||||
/// @RESTRETURNCODE{200}
|
||||
/// is returned when the list of endpoints can be determined successfully.
|
||||
///
|
||||
|
@ -89,9 +85,9 @@ var internal = require("internal");
|
|||
/// curlRequest('POST', url, JSON.stringify(body));
|
||||
///
|
||||
/// var response = logCurlRequest('GET', url);
|
||||
///
|
||||
///
|
||||
/// assert(response.code === 200);
|
||||
///
|
||||
///
|
||||
/// logJsonResponse(response);
|
||||
/// curlRequest('DELETE', url + '/' + encodeURIComponent(endpoint));
|
||||
/// @END_EXAMPLE_ARANGOSH_RUN
|
||||
|
@ -116,35 +112,35 @@ var internal = require("internal");
|
|||
///
|
||||
/// If *databases* is an empty list, all databases present in the server will
|
||||
/// become accessible via the endpoint, with the *_system* database being the
|
||||
/// default database.
|
||||
/// default database.
|
||||
///
|
||||
/// If *databases* is non-empty, only the specified databases will become
|
||||
/// available via the endpoint. The first database name in the *databases*
|
||||
/// list will also become the default database for the endpoint. The default
|
||||
/// database will always be used if a request coming in on the endpoint does
|
||||
/// If *databases* is non-empty, only the specified databases will become
|
||||
/// available via the endpoint. The first database name in the *databases*
|
||||
/// list will also become the default database for the endpoint. The default
|
||||
/// database will always be used if a request coming in on the endpoint does
|
||||
/// not specify the database name explicitly.
|
||||
///
|
||||
/// **Note**: adding or reconfiguring endpoints is allowed in the system database
|
||||
/// only. Calling this action in any other database will make the server
|
||||
/// **Note**: adding or reconfiguring endpoints is allowed in the system database
|
||||
/// only. Calling this action in any other database will make the server
|
||||
/// return an error.
|
||||
///
|
||||
/// Adding SSL endpoints at runtime is only supported if the server was started
|
||||
/// Adding SSL endpoints at runtime is only supported if the server was started
|
||||
/// with SSL properly configured (e.g. *--server.keyfile* must have been set).
|
||||
///
|
||||
/// @RESTRETURNCODES
|
||||
///
|
||||
///
|
||||
/// @RESTRETURNCODE{200}
|
||||
/// is returned when the endpoint was added or changed successfully.
|
||||
///
|
||||
/// @RESTRETURNCODE{400}
|
||||
/// is returned if the request is malformed or if the action is not carried out
|
||||
/// is returned if the request is malformed or if the action is not carried out
|
||||
/// in the system database.
|
||||
///
|
||||
/// @RESTRETURNCODE{405}
|
||||
/// The server will respond with *HTTP 405* if an unsupported HTTP method is used.
|
||||
///
|
||||
/// @EXAMPLES
|
||||
/// Adding an endpoint *tcp://127.0.0.1:8532* with two mapped databases
|
||||
/// Adding an endpoint *tcp://127.0.0.1:8532* with two mapped databases
|
||||
/// (*mydb1* and *mydb2*). *mydb1* will become the default database for the
|
||||
/// endpoint.
|
||||
///
|
||||
|
@ -156,7 +152,7 @@ var internal = require("internal");
|
|||
/// databases: [ "mydb1", "mydb2" ]
|
||||
/// };
|
||||
/// var response = logCurlRequest('POST', url, JSON.stringify(body));
|
||||
///
|
||||
///
|
||||
/// assert(response.code === 200);
|
||||
///
|
||||
/// logJsonResponse(response);
|
||||
|
@ -176,7 +172,7 @@ var internal = require("internal");
|
|||
/// databases: [ ]
|
||||
/// };
|
||||
/// var response = logCurlRequest('POST', url, JSON.stringify(body));
|
||||
///
|
||||
///
|
||||
/// assert(response.code === 200);
|
||||
///
|
||||
/// logJsonResponse(response);
|
||||
|
@ -186,7 +182,7 @@ var internal = require("internal");
|
|||
/// Adding an endpoint *tcp://127.0.0.1:8533* without any databases first,
|
||||
/// and then updating the databases for the endpoint to *testdb1*, *testdb2*, and
|
||||
/// *testdb3*.
|
||||
///
|
||||
///
|
||||
/// @EXAMPLE_ARANGOSH_RUN{RestEndpointPostChange}
|
||||
/// var url = "/_api/endpoint";
|
||||
/// var endpoint = "tcp://127.0.0.1:8533";
|
||||
|
@ -195,14 +191,14 @@ var internal = require("internal");
|
|||
/// databases: [ ]
|
||||
/// };
|
||||
/// var response = logCurlRequest('POST', url, JSON.stringify(body));
|
||||
///
|
||||
///
|
||||
/// assert(response.code === 200);
|
||||
///
|
||||
/// logJsonResponse(response);
|
||||
///
|
||||
/// body.database = [ "testdb1", "testdb2", "testdb3" ];
|
||||
/// response = logCurlRequest('POST', url, JSON.stringify(body));
|
||||
///
|
||||
///
|
||||
/// assert(response.code === 200);
|
||||
///
|
||||
/// logJsonResponse(response);
|
||||
|
@ -226,20 +222,20 @@ var internal = require("internal");
|
|||
/// This operation deletes an existing endpoint from the list of all endpoints,
|
||||
/// and makes the server stop listening on the endpoint.
|
||||
///
|
||||
/// **Note**: deleting and disconnecting an endpoint is allowed in the system
|
||||
/// database only. Calling this action in any other database will make the server
|
||||
/// **Note**: deleting and disconnecting an endpoint is allowed in the system
|
||||
/// database only. Calling this action in any other database will make the server
|
||||
/// return an error.
|
||||
///
|
||||
/// Futhermore, the last remaining endpoint cannot be deleted as this would make
|
||||
/// the server kaputt.
|
||||
///
|
||||
/// @RESTRETURNCODES
|
||||
///
|
||||
///
|
||||
/// @RESTRETURNCODE{200}
|
||||
/// is returned when the endpoint was deleted and disconnected successfully.
|
||||
///
|
||||
/// @RESTRETURNCODE{400}
|
||||
/// is returned if the request is malformed or if the action is not carried out
|
||||
/// is returned if the request is malformed or if the action is not carried out
|
||||
/// in the system database.
|
||||
///
|
||||
/// @RESTRETURNCODE{404}
|
||||
|
@ -261,7 +257,7 @@ var internal = require("internal");
|
|||
/// };
|
||||
/// curlRequest('POST', url, JSON.stringify(body));
|
||||
/// var response = logCurlRequest('DELETE', url + '/' + encodeURIComponent(endpoint));
|
||||
///
|
||||
///
|
||||
/// assert(response.code === 200);
|
||||
///
|
||||
/// logJsonResponse(response);
|
||||
|
@ -273,7 +269,7 @@ var internal = require("internal");
|
|||
/// var url = "/_api/endpoint";
|
||||
/// var endpoint = "tcp://127.0.0.1:8532";
|
||||
/// var response = logCurlRequest('DELETE', url + '/' + encodeURIComponent(endpoint));
|
||||
///
|
||||
///
|
||||
/// assert(response.code === 404);
|
||||
///
|
||||
/// logJsonResponse(response);
|
||||
|
@ -283,7 +279,6 @@ var internal = require("internal");
|
|||
|
||||
actions.defineHttp({
|
||||
url : "_api/endpoint",
|
||||
context : "admin",
|
||||
prefix : true,
|
||||
|
||||
callback : function (req, res) {
|
||||
|
@ -304,7 +299,7 @@ actions.defineHttp({
|
|||
}
|
||||
|
||||
result = internal.configureEndpoint(body.endpoint, body.databases || [ ]);
|
||||
actions.resultOk(req, res, actions.HTTP_OK, { result: result });
|
||||
actions.resultOk(req, res, actions.HTTP_OK, { result: result });
|
||||
}
|
||||
|
||||
else if (req.requestType === actions.DELETE) {
|
||||
|
@ -328,15 +323,11 @@ actions.defineHttp({
|
|||
}
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @\\}"
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2012 triagens GmbH, Cologne, Germany
|
||||
/// Copyright 2014 ArangoDB 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.
|
||||
|
@ -22,9 +22,10 @@
|
|||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Jan Steemann
|
||||
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
|
||||
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -37,11 +38,6 @@ var EXPLAIN = require("internal").AQL_EXPLAIN;
|
|||
// --SECTION-- global variables
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup ArangoAPI
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @startDocuBlock JSF_post_api_explain
|
||||
/// @brief explain a query and return information about it
|
||||
|
@ -50,22 +46,22 @@ var EXPLAIN = require("internal").AQL_EXPLAIN;
|
|||
///
|
||||
/// @RESTBODYPARAM{body,json,required}
|
||||
/// The query string needs to be passed in the attribute *query* of a JSON
|
||||
/// object as the body of the POST request. If the query references any bind
|
||||
/// object as the body of the POST request. If the query references any bind
|
||||
/// variables, these must also be passed in the attribute *bindVars*.
|
||||
///
|
||||
/// @RESTDESCRIPTION
|
||||
///
|
||||
/// To explain how an AQL query would be executed on the server, the query string
|
||||
/// To explain how an AQL query would be executed on the server, the query string
|
||||
/// can be sent to the server via an HTTP POST request. The server will then validate
|
||||
/// the query and create an execution plan for it, but will not execute it.
|
||||
///
|
||||
/// The execution plan that is returned by the server can be used to estimate the
|
||||
/// probable performance of an AQL query. Though the actual performance will depend
|
||||
/// on many different factors, the execution plan normally can give some good hint
|
||||
/// on the amount of work the server needs to do in order to actually run the query.
|
||||
/// on the amount of work the server needs to do in order to actually run the query.
|
||||
///
|
||||
/// The top-level statements will appear in the result in the same order in which
|
||||
/// they have been used in the original query. Each result element has at most the
|
||||
/// they have been used in the original query. Each result element has at most the
|
||||
/// following attributes:
|
||||
/// - *id*: the row number of the top-level statement, starting at 1
|
||||
/// - *type*: the type of the top-level statement (e.g. *for*, *return* ...)
|
||||
|
@ -75,13 +71,13 @@ var EXPLAIN = require("internal").AQL_EXPLAIN;
|
|||
/// used.
|
||||
/// Many top-level statements will provide an *expression* attribute that
|
||||
/// contains data about the expression they operate on. This is true for *FOR*,
|
||||
/// *FILTER*, *SORT*, *COLLECT*, and *RETURN* statements. The
|
||||
/// *FILTER*, *SORT*, *COLLECT*, and *RETURN* statements. The
|
||||
/// *expression* attribute has the following sub-attributes:
|
||||
/// - *type*: the type of the expression. Some possible values are:
|
||||
/// - *collection*: an iteration over documents from a collection. The
|
||||
/// - *collection*: an iteration over documents from a collection. The
|
||||
/// *value* attribute will then contain the collection name. The *extra*
|
||||
/// attribute will contain information about if and which index is used when
|
||||
/// accessing the documents from the collection. If no index is used, the
|
||||
/// accessing the documents from the collection. If no index is used, the
|
||||
/// *accessType* sub-attribute of the *extra* attribute will have the
|
||||
/// value *all*, otherwise it will be *index*.
|
||||
/// - *list*: a list of dynamic values. The *value* attribute will contain the
|
||||
|
@ -93,7 +89,7 @@ var EXPLAIN = require("internal").AQL_EXPLAIN;
|
|||
///
|
||||
/// Please note that the structure of the explain result data might change in future
|
||||
/// versions of ArangoDB without further notice and without maintaining backwards
|
||||
/// compatibility.
|
||||
/// compatibility.
|
||||
///
|
||||
/// @RESTRETURNCODES
|
||||
///
|
||||
|
@ -151,7 +147,7 @@ var EXPLAIN = require("internal").AQL_EXPLAIN;
|
|||
/// @END_EXAMPLE_ARANGOSH_RUN
|
||||
///
|
||||
/// The data returned in the *plan* attribute of the result contains one
|
||||
/// element per AQL top-level statement (i.e. *FOR*, *RETURN*,
|
||||
/// element per AQL top-level statement (i.e. *FOR*, *RETURN*,
|
||||
/// *FILTER* etc.). If the query optimiser removed some unnecessary statements,
|
||||
/// the result might also contain less elements than there were top-level
|
||||
/// statements in the AQL query.
|
||||
|
@ -176,9 +172,9 @@ var EXPLAIN = require("internal").AQL_EXPLAIN;
|
|||
|
||||
function post_api_explain (req, res) {
|
||||
if (req.suffix.length !== 0) {
|
||||
actions.resultNotFound(req,
|
||||
res,
|
||||
ERRORS.errors.ERROR_HTTP_NOT_FOUND.code,
|
||||
actions.resultNotFound(req,
|
||||
res,
|
||||
ERRORS.errors.ERROR_HTTP_NOT_FOUND.code,
|
||||
ERRORS.errors.ERROR_HTTP_NOT_FOUND.message);
|
||||
return;
|
||||
}
|
||||
|
@ -205,18 +201,17 @@ function post_api_explain (req, res) {
|
|||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief explain gateway
|
||||
/// @brief explain gateway
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : "_api/explain",
|
||||
context : "api",
|
||||
|
||||
callback : function (req, res) {
|
||||
try {
|
||||
switch (req.requestType) {
|
||||
case actions.POST:
|
||||
post_api_explain(req, res);
|
||||
case actions.POST:
|
||||
post_api_explain(req, res);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -229,11 +224,11 @@ actions.defineHttp({
|
|||
}
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @}\\)"
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2010-2012 triagens GmbH, Cologne, Germany
|
||||
/// Copyright 2014 ArangoDB 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.
|
||||
|
@ -22,9 +22,10 @@
|
|||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Dr. Frank Celler
|
||||
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
|
||||
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -48,7 +49,6 @@ var easyPostCallback = actions.easyPostCallback;
|
|||
|
||||
actions.defineHttp({
|
||||
url : "_admin/foxx/fetch",
|
||||
context : "admin",
|
||||
prefix : false,
|
||||
|
||||
callback : function (req, res) {
|
||||
|
@ -62,13 +62,13 @@ actions.defineHttp({
|
|||
}
|
||||
|
||||
var json = actions.getJsonBody(req, res, actions.HTTP_BAD);
|
||||
|
||||
|
||||
if (json === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
var serverFile = json.filename;
|
||||
var realFile = fs.join(fs.getTempPath(), serverFile);
|
||||
var realFile = fs.join(fs.getTempPath(), serverFile);
|
||||
|
||||
if (! fs.isFile(realFile)) {
|
||||
actions.resultNotFound(req, res, arangodb.errors.ERROR_FILE_NOT_FOUND.code);
|
||||
|
@ -116,7 +116,7 @@ actions.defineHttp({
|
|||
if (found !== null) {
|
||||
found = found.app;
|
||||
}
|
||||
|
||||
|
||||
actions.resultOk(req, res, actions.HTTP_OK, { path: path, app: found });
|
||||
}
|
||||
catch (err) {
|
||||
|
@ -131,7 +131,6 @@ actions.defineHttp({
|
|||
|
||||
actions.defineHttp({
|
||||
url : "_admin/foxx/mount",
|
||||
context : "admin",
|
||||
prefix : false,
|
||||
|
||||
callback: easyPostCallback({
|
||||
|
@ -145,14 +144,13 @@ actions.defineHttp({
|
|||
}
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief rescans the FOXX application directory
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : "_admin/foxx/rescan",
|
||||
context : "admin",
|
||||
prefix : false,
|
||||
|
||||
callback: easyPostCallback({
|
||||
|
@ -170,7 +168,6 @@ actions.defineHttp({
|
|||
|
||||
actions.defineHttp({
|
||||
url : "_admin/foxx/setup",
|
||||
context : "admin",
|
||||
prefix : false,
|
||||
|
||||
callback: easyPostCallback({
|
||||
|
@ -189,7 +186,6 @@ actions.defineHttp({
|
|||
|
||||
actions.defineHttp({
|
||||
url : "_admin/foxx/teardown",
|
||||
context : "admin",
|
||||
prefix : false,
|
||||
|
||||
callback: easyPostCallback({
|
||||
|
@ -208,7 +204,6 @@ actions.defineHttp({
|
|||
|
||||
actions.defineHttp({
|
||||
url : "_admin/foxx/unmount",
|
||||
context : "admin",
|
||||
prefix : false,
|
||||
|
||||
callback: easyPostCallback({
|
||||
|
@ -227,7 +222,6 @@ actions.defineHttp({
|
|||
|
||||
actions.defineHttp({
|
||||
url : "_admin/foxx/dev-setup",
|
||||
context : "admin",
|
||||
prefix : false,
|
||||
|
||||
callback: easyPostCallback({
|
||||
|
@ -246,7 +240,6 @@ actions.defineHttp({
|
|||
|
||||
actions.defineHttp({
|
||||
url : "_admin/foxx/dev-teardown",
|
||||
context : "admin",
|
||||
prefix : false,
|
||||
|
||||
callback: easyPostCallback({
|
||||
|
@ -265,7 +258,6 @@ actions.defineHttp({
|
|||
|
||||
actions.defineHttp({
|
||||
url : "_admin/foxx/purge",
|
||||
context : "admin",
|
||||
prefix : false,
|
||||
|
||||
callback: easyPostCallback({
|
||||
|
@ -284,7 +276,6 @@ actions.defineHttp({
|
|||
|
||||
actions.defineHttp({
|
||||
url : "_admin/foxx/config",
|
||||
context : "admin",
|
||||
prefix : false,
|
||||
|
||||
callback : function (req, res) {
|
||||
|
@ -305,5 +296,5 @@ actions.defineHttp({
|
|||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @\\}"
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -8,7 +8,7 @@
|
|||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2012 triagens GmbH, Cologne, Germany
|
||||
/// Copyright 2014 ArangoDB 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.
|
||||
|
@ -22,9 +22,10 @@
|
|||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Achim Brandt
|
||||
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
|
||||
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -37,11 +38,6 @@ var API = "_api/index";
|
|||
// --SECTION-- public functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup ArangoAPI
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @startDocuBlock JSF_get_api_index
|
||||
/// @brief returns all indexes of a collection
|
||||
|
@ -83,7 +79,7 @@ var API = "_api/index";
|
|||
function get_api_indexes (req, res) {
|
||||
var name = req.parameters.collection;
|
||||
var collection = arangodb.db._collection(name);
|
||||
|
||||
|
||||
if (collection === null) {
|
||||
actions.collectionNotFound(req, res, name);
|
||||
return;
|
||||
|
@ -93,13 +89,13 @@ function get_api_indexes (req, res) {
|
|||
|
||||
for (i = 0; i < indexes.length; ++i) {
|
||||
var index = indexes[i];
|
||||
|
||||
|
||||
list.push(index);
|
||||
ids[index.id] = index;
|
||||
}
|
||||
|
||||
var result = { indexes : list, identifiers : ids };
|
||||
|
||||
|
||||
actions.resultOk(req, res, actions.HTTP_OK, result);
|
||||
}
|
||||
|
||||
|
@ -167,7 +163,7 @@ function get_api_index (req, res) {
|
|||
else if (req.suffix.length === 2) {
|
||||
var name = decodeURIComponent(req.suffix[0]);
|
||||
var collection = arangodb.db._collection(name);
|
||||
|
||||
|
||||
if (collection === null) {
|
||||
actions.collectionNotFound(req, res, name);
|
||||
return;
|
||||
|
@ -218,7 +214,7 @@ function get_api_index (req, res) {
|
|||
///
|
||||
/// - *size*: The maximal number of documents for the collection. If specified,
|
||||
/// the value must be greater than zero.
|
||||
///
|
||||
///
|
||||
/// - *byteSize*: The maximal size of the active document data in the collection
|
||||
/// (in bytes). If specified, the value must be at least 16384.
|
||||
///
|
||||
|
@ -258,9 +254,9 @@ function get_api_index (req, res) {
|
|||
/// db._create(cn, { waitForSync: true });
|
||||
///
|
||||
/// var url = "/_api/index?collection=" + cn;
|
||||
/// var body = {
|
||||
/// type: "cap",
|
||||
/// size : 10
|
||||
/// var body = {
|
||||
/// type: "cap",
|
||||
/// size : 10
|
||||
/// };
|
||||
///
|
||||
/// var response = logCurlRequest('POST', url, JSON.stringify(body));
|
||||
|
@ -292,7 +288,7 @@ function get_api_index (req, res) {
|
|||
///
|
||||
/// - *type*: must be equal to *"geo"*.
|
||||
///
|
||||
/// - *fields*: A list with one or two attribute paths.
|
||||
/// - *fields*: A list with one or two attribute paths.
|
||||
///
|
||||
/// If it is a list with one attribute path *location*, then a geo-spatial
|
||||
/// index on all documents is created using *location* as path to the
|
||||
|
@ -310,12 +306,12 @@ function get_api_index (req, res) {
|
|||
///
|
||||
/// - *geoJson*: If a geo-spatial index on a *location* is constructed
|
||||
/// and *geoJson* is *true*, then the order within the list is longitude
|
||||
/// followed by latitude. This corresponds to the format described in
|
||||
/// followed by latitude. This corresponds to the format described in
|
||||
/// http://geojson.org/geojson-spec.html#positions
|
||||
///
|
||||
/// - *constraint*: If *constraint* is *true*, then a geo-spatial
|
||||
/// constraint is created. The constraint is a non-unique variant of the index.
|
||||
/// **Note**: It is also possible to set the *unique* attribute instead of
|
||||
/// constraint is created. The constraint is a non-unique variant of the index.
|
||||
/// **Note**: It is also possible to set the *unique* attribute instead of
|
||||
/// the *constraint* attribute.
|
||||
///
|
||||
/// - *ignoreNull*: If a geo-spatial constraint is created and
|
||||
|
@ -332,7 +328,7 @@ function get_api_index (req, res) {
|
|||
///
|
||||
/// @RESTRETURNCODE{201}
|
||||
/// If the index does not already exist and could be created, then a *HTTP 201*
|
||||
/// is returned.
|
||||
/// is returned.
|
||||
///
|
||||
/// @RESTRETURNCODE{404}
|
||||
/// If the *collection-name* is unknown, then a *HTTP 404* is returned.
|
||||
|
@ -410,7 +406,7 @@ function get_api_index (req, res) {
|
|||
///
|
||||
/// @RESTRETURNCODE{201}
|
||||
/// If the index does not already exist and could be created, then a *HTTP 201*
|
||||
/// is returned.
|
||||
/// is returned.
|
||||
///
|
||||
/// @RESTRETURNCODE{400}
|
||||
/// If the collection already contains documents and you try to create a unique
|
||||
|
@ -545,7 +541,7 @@ function get_api_index (req, res) {
|
|||
///
|
||||
/// - *type*: must be equal to *"fulltext"*.
|
||||
///
|
||||
/// - *fields*: A list of attribute names. Currently, the list is limited
|
||||
/// - *fields*: A list of attribute names. Currently, the list is limited
|
||||
/// to exactly one attribute, so the value of *fields* should look like
|
||||
/// this for example: *[ "text" ]*.
|
||||
///
|
||||
|
@ -635,9 +631,9 @@ function get_api_index (req, res) {
|
|||
/// db._create(cn, { waitForSync: true });
|
||||
///
|
||||
/// var url = "/_api/index?collection=" + cn;
|
||||
/// var body = '{ ' +
|
||||
/// '"type" : "bitarray", ' +
|
||||
/// '"unique" : false, ' +
|
||||
/// var body = '{ ' +
|
||||
/// '"type" : "bitarray", ' +
|
||||
/// '"unique" : false, ' +
|
||||
/// '"fields" : [ "x", [0,1,[]], "y", ["a","b",[]] ] ' +
|
||||
/// '}';
|
||||
///
|
||||
|
@ -675,26 +671,26 @@ function get_api_index (req, res) {
|
|||
///
|
||||
/// Most indexes (a notable exception being the cap constraint) require the
|
||||
/// list of attributes to be indexed in the *fields* attribute of the index
|
||||
/// details. Depending on the index type, a single attribute or multiple
|
||||
/// attributes may be indexed.
|
||||
///
|
||||
/// details. Depending on the index type, a single attribute or multiple
|
||||
/// attributes may be indexed.
|
||||
///
|
||||
/// Indexing system attributes such as *_id*, *_key*, *_from*, and *_to*
|
||||
/// is not supported by any index type. Manually creating an index that
|
||||
/// is not supported by any index type. Manually creating an index that
|
||||
/// relies on any of these attributes is unsupported.
|
||||
///
|
||||
/// Some indexes can be created as unique or non-unique variants. Uniqueness
|
||||
/// can be controlled for most indexes by specifying the *unique* in the
|
||||
/// index details. Setting it to *true* will create a unique index.
|
||||
/// index details. Setting it to *true* will create a unique index.
|
||||
/// Setting it to *false* or omitting the *unique* attribute will
|
||||
/// create a non-unique index.
|
||||
///
|
||||
/// **Note**: The following index types do not support uniqueness, and using
|
||||
/// **Note**: The following index types do not support uniqueness, and using
|
||||
/// the *unique* attribute with these types may lead to an error:
|
||||
/// - cap constraints
|
||||
/// - fulltext indexes
|
||||
/// - bitarray indexes
|
||||
///
|
||||
/// **Note**: Unique indexes on non-shard keys are not supported in a
|
||||
/// **Note**: Unique indexes on non-shard keys are not supported in a
|
||||
/// cluster.
|
||||
///
|
||||
/// @RESTRETURNCODES
|
||||
|
@ -741,7 +737,7 @@ function post_api_index (req, res) {
|
|||
body.collection = name;
|
||||
}
|
||||
|
||||
// fill "unique" attribute from "constraint" attribute to be downward-compatible
|
||||
// fill "unique" attribute from "constraint" attribute to be downward-compatible
|
||||
// with old geo index API
|
||||
if (body.hasOwnProperty("constraint") && ! body.hasOwnProperty("unique")) {
|
||||
body.unique = body.constraint;
|
||||
|
@ -749,7 +745,7 @@ function post_api_index (req, res) {
|
|||
|
||||
// rewrite bitarray fields
|
||||
if (body.type === "bitarray") {
|
||||
if (typeof body.fields === "object" &&
|
||||
if (typeof body.fields === "object" &&
|
||||
Array.isArray(body.fields) &&
|
||||
body.fields.length > 0) {
|
||||
if (! Array.isArray(body.fields[0])) {
|
||||
|
@ -762,7 +758,7 @@ function post_api_index (req, res) {
|
|||
}
|
||||
}
|
||||
|
||||
// create the index
|
||||
// create the index
|
||||
var index = collection.ensureIndex(body);
|
||||
if (index.isNewlyCreated) {
|
||||
actions.resultOk(req, res, actions.HTTP_CREATED, index);
|
||||
|
@ -845,7 +841,6 @@ function delete_api_index (req, res) {
|
|||
|
||||
actions.defineHttp({
|
||||
url : API,
|
||||
context : "api",
|
||||
|
||||
callback : function (req, res) {
|
||||
try {
|
||||
|
@ -868,11 +863,11 @@ actions.defineHttp({
|
|||
}
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @}\\)"
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014 triagens GmbH, Cologne, Germany
|
||||
/// Copyright 2014 ArangoDB 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.
|
||||
|
@ -24,7 +24,7 @@
|
|||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Dr. Frank Celler
|
||||
/// @author Copyright 2014, triAGENS GmbH, Cologne, Germany
|
||||
|
@ -42,8 +42,7 @@ var console = require("console");
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : "_open/cerberus",
|
||||
context : "admin",
|
||||
url: "_open/cerberus",
|
||||
prefix : true,
|
||||
|
||||
callback : function (req, res) {
|
||||
|
@ -55,7 +54,7 @@ actions.defineHttp({
|
|||
suffix = suffix.concat(req.suffix);
|
||||
|
||||
req.suffix = suffix;
|
||||
|
||||
|
||||
actions.routeRequest(req, res);
|
||||
}
|
||||
});
|
||||
|
@ -66,5 +65,5 @@ actions.defineHttp({
|
|||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @\\}"
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2012 triagens GmbH, Cologne, Germany
|
||||
/// Copyright 2014 ArangoDB 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.
|
||||
|
@ -22,9 +22,10 @@
|
|||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Jan Steemann
|
||||
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
|
||||
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -38,11 +39,6 @@ var PARSE = require("internal").AQL_PARSE;
|
|||
// --SECTION-- global variables
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup ArangoAPI
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @startDocuBlock JSF_post_api_query
|
||||
/// @brief parse a query and return information about it
|
||||
|
@ -100,9 +96,9 @@ var PARSE = require("internal").AQL_PARSE;
|
|||
|
||||
function post_api_query (req, res) {
|
||||
if (req.suffix.length !== 0) {
|
||||
actions.resultNotFound(req,
|
||||
res,
|
||||
arangodb.ERROR_HTTP_NOT_FOUND,
|
||||
actions.resultNotFound(req,
|
||||
res,
|
||||
arangodb.ERROR_HTTP_NOT_FOUND,
|
||||
arangodb.errors.ERROR_HTTP_NOT_FOUND.message);
|
||||
return;
|
||||
}
|
||||
|
@ -130,18 +126,17 @@ function post_api_query (req, res) {
|
|||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief query actions gateway
|
||||
/// @brief query actions gateway
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : "_api/query",
|
||||
context : "api",
|
||||
url: "_api/query",
|
||||
|
||||
callback : function (req, res) {
|
||||
try {
|
||||
switch (req.requestType) {
|
||||
case actions.POST:
|
||||
post_api_query(req, res);
|
||||
case actions.POST:
|
||||
post_api_query(req, res);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -154,11 +149,11 @@ actions.defineHttp({
|
|||
}
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @}\\)"
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2012 triagens GmbH, Cologne, Germany
|
||||
/// Copyright 2014 ArangoDB 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.
|
||||
|
@ -22,9 +22,10 @@
|
|||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Achim Brandt
|
||||
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
|
||||
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -34,18 +35,13 @@ var ERRORS = require("internal").errors;
|
|||
|
||||
var API = "_api/simple/";
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup ArangoAPI
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @startDocuBlock JSA_put_api_simple_by_example_hash
|
||||
/// @brief returns all documents of a collection matching a given example,
|
||||
/// @brief returns all documents of a collection matching a given example,
|
||||
/// using a specific hash index
|
||||
///
|
||||
/// @RESTHEADER{PUT /_api/simple/by-example-hash, Hash index}
|
||||
|
@ -92,7 +88,7 @@ var API = "_api/simple/";
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @startDocuBlock JSA_put_api_simple_by_example_skiplist
|
||||
/// @brief returns all documents of a collection matching a given example,
|
||||
/// @brief returns all documents of a collection matching a given example,
|
||||
/// using a specific skiplist index
|
||||
///
|
||||
/// @RESTHEADER{PUT /_api/simple/by-example-skiplist, Skiplist index}
|
||||
|
@ -109,7 +105,7 @@ var API = "_api/simple/";
|
|||
///
|
||||
/// - *collection*: The name of the collection to query.
|
||||
///
|
||||
/// - *index*: The id of the index to be used for the query. The index must
|
||||
/// - *index*: The id of the index to be used for the query. The index must
|
||||
/// exist and must be of type *skiplist*.
|
||||
///
|
||||
/// - *example*: an example document. The example must contain a value for each
|
||||
|
@ -139,7 +135,7 @@ var API = "_api/simple/";
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @startDocuBlock JSA_put_api_simple_by_example_bitarray
|
||||
/// @brief returns all documents of a collection matching a given example,
|
||||
/// @brief returns all documents of a collection matching a given example,
|
||||
/// using a specific bitarray index
|
||||
///
|
||||
/// @RESTHEADER{PUT /_api/simple/by-example-bitarray, Bitarray index}
|
||||
|
@ -156,7 +152,7 @@ var API = "_api/simple/";
|
|||
///
|
||||
/// - *collection*: The name of the collection to query.
|
||||
///
|
||||
/// - *index*: The id of the index to be used for the query. The index must
|
||||
/// - *index*: The id of the index to be used for the query. The index must
|
||||
/// exist and must be of type *bitarray*.
|
||||
///
|
||||
/// - *example*: an example document. The example must contain a value for each
|
||||
|
@ -186,7 +182,7 @@ var API = "_api/simple/";
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @startDocuBlock JSA_put_api_simple_by_condition_skiplist
|
||||
/// @brief returns all documents of a collection matching a given condition,
|
||||
/// @brief returns all documents of a collection matching a given condition,
|
||||
/// using a specific skiplist index
|
||||
///
|
||||
/// @RESTHEADER{PUT /_api/simple/by-condition-skiplist,Query by-condition using Skiplist index}
|
||||
|
@ -203,11 +199,11 @@ var API = "_api/simple/";
|
|||
///
|
||||
/// - *collection*: The name of the collection to query.
|
||||
///
|
||||
/// - *index*: The id of the index to be used for the query. The index must
|
||||
/// - *index*: The id of the index to be used for the query. The index must
|
||||
/// exist and must be of type *skiplist*.
|
||||
///
|
||||
/// - *condition*: the condition which all returned documents shall satisfy.
|
||||
/// Conditions must be specified for all indexed attributes.
|
||||
/// - *condition*: the condition which all returned documents shall satisfy.
|
||||
/// Conditions must be specified for all indexed attributes.
|
||||
///
|
||||
/// - *skip*: The number of documents to skip in the query. (optional)
|
||||
///
|
||||
|
@ -233,7 +229,7 @@ var API = "_api/simple/";
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @startDocuBlock JSA_put_api_simple_by_condition_bitarray
|
||||
/// @brief returns all documents of a collection matching a given condition,
|
||||
/// @brief returns all documents of a collection matching a given condition,
|
||||
/// using a specific bitarray index
|
||||
///
|
||||
/// @RESTHEADER{PUT /_api/simple/by-condition-bitarray, Query by-condition using bitarray index}
|
||||
|
@ -250,11 +246,11 @@ var API = "_api/simple/";
|
|||
///
|
||||
/// - *collection*: The name of the collection to query.
|
||||
///
|
||||
/// - *index*: The id of the index to be used for the query. The index must
|
||||
/// - *index*: The id of the index to be used for the query. The index must
|
||||
/// exist and must be of type *bitarray*.
|
||||
///
|
||||
/// - *condition*: the condition which all returned documents shall satisfy.
|
||||
/// Conditions must be specified for all indexed attributes.
|
||||
/// - *condition*: the condition which all returned documents shall satisfy.
|
||||
/// Conditions must be specified for all indexed attributes.
|
||||
///
|
||||
/// - *skip*: The number of documents to skip in the query. (optional)
|
||||
///
|
||||
|
@ -282,7 +278,7 @@ var API = "_api/simple/";
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create a cursor response
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
function createCursorResponse (req, res, cursor) {
|
||||
actions.resultCursor(req, res, cursor, undefined, { countRequested: true });
|
||||
}
|
||||
|
@ -293,10 +289,9 @@ function createCursorResponse (req, res, cursor) {
|
|||
|
||||
function setupIndexQuery (name, func, isExampleQuery) {
|
||||
actions.defineHttp({
|
||||
url : API + name,
|
||||
context : "api",
|
||||
url: API + name,
|
||||
|
||||
callback : function (req, res) {
|
||||
callback: function (req, res) {
|
||||
try {
|
||||
var body = actions.getJsonBody(req, res);
|
||||
|
||||
|
@ -326,7 +321,7 @@ function setupIndexQuery (name, func, isExampleQuery) {
|
|||
actions.badParameter(req, res, "example");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
result = collection[func](index, body.example);
|
||||
}
|
||||
else {
|
||||
|
@ -334,23 +329,23 @@ function setupIndexQuery (name, func, isExampleQuery) {
|
|||
actions.badParameter(req, res, "condition");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
result = collection[func](index, body.condition);
|
||||
}
|
||||
|
||||
|
||||
if (skip > 0) {
|
||||
result.skip(skip);
|
||||
}
|
||||
if (limit !== undefined && limit !== null) {
|
||||
result.limit(limit);
|
||||
}
|
||||
|
||||
|
||||
createCursorResponse(req, res, CREATE_CURSOR(result.toArray(), true, body.batchSize, body.ttl));
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
actions.resultException(req, res, err, undefined, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -442,7 +437,7 @@ setupIndexQueries();
|
|||
/// logJsonResponse(response);
|
||||
/// db._drop(cn);
|
||||
/// @END_EXAMPLE_ARANGOSH_RUN
|
||||
///
|
||||
///
|
||||
/// Using a *batchSize* value
|
||||
///
|
||||
/// @EXAMPLE_ARANGOSH_RUN{RestSimpleAllBatch}
|
||||
|
@ -469,8 +464,7 @@ setupIndexQueries();
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : API + "all",
|
||||
context : "api",
|
||||
url: API + "all",
|
||||
|
||||
callback : function (req, res) {
|
||||
try {
|
||||
|
@ -572,10 +566,9 @@ actions.defineHttp({
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : API + "any",
|
||||
context : "api",
|
||||
url: API + "any",
|
||||
|
||||
callback : function (req, res) {
|
||||
callback: function (req, res) {
|
||||
try {
|
||||
var body = actions.getJsonBody(req, res);
|
||||
|
||||
|
@ -620,7 +613,7 @@ actions.defineHttp({
|
|||
///
|
||||
/// The default will find at most 100 documents near the given coordinate. The
|
||||
/// returned list is sorted according to the distance, with the nearest document
|
||||
/// being first in the list. If there are near documents of equal distance, documents
|
||||
/// being first in the list. If there are near documents of equal distance, documents
|
||||
/// are chosen randomly from this set until the limit is reached.
|
||||
///
|
||||
/// In order to use the *near* operator, a geo index must be defined for the
|
||||
|
@ -675,7 +668,7 @@ actions.defineHttp({
|
|||
/// products.save({ name : "Name/" + i + "/",loc: [ i, 0 ] });
|
||||
/// }
|
||||
/// var url = "/_api/simple/near";
|
||||
/// var body = '{ ' +
|
||||
/// var body = '{ ' +
|
||||
/// '"collection": "products", ' +
|
||||
/// '"latitude" : 0, ' +
|
||||
/// '"longitude" : 0, ' +
|
||||
|
@ -703,8 +696,8 @@ actions.defineHttp({
|
|||
/// products.save({ name : "Name/" + i + "/",loc: [ i, 0 ] });
|
||||
/// }
|
||||
/// var url = "/_api/simple/near";
|
||||
/// var body = '{ ' +
|
||||
/// '"collection": "products", ' +
|
||||
/// var body = '{ ' +
|
||||
/// '"collection": "products", ' +
|
||||
/// '"latitude" : 0, ' +
|
||||
/// '"longitude" : 0, ' +
|
||||
/// '"skip" : 1, ' +
|
||||
|
@ -723,8 +716,7 @@ actions.defineHttp({
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : API + "near",
|
||||
context : "api",
|
||||
url: API + "near",
|
||||
|
||||
callback : function (req, res) {
|
||||
try {
|
||||
|
@ -900,8 +892,7 @@ actions.defineHttp({
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : API + "within",
|
||||
context : "api",
|
||||
url: API + "within",
|
||||
|
||||
callback : function (req, res) {
|
||||
try {
|
||||
|
@ -943,19 +934,19 @@ actions.defineHttp({
|
|||
else {
|
||||
result = collection.geo({ id : geo }).within(latitude, longitude, radius);
|
||||
}
|
||||
|
||||
|
||||
if (skip !== null && skip !== undefined) {
|
||||
result = result.skip(skip);
|
||||
}
|
||||
|
||||
|
||||
if (limit !== null && limit !== undefined) {
|
||||
result = result.limit(limit);
|
||||
}
|
||||
|
||||
|
||||
if (distance !== null && distance !== undefined) {
|
||||
result = result.distance(distance);
|
||||
}
|
||||
|
||||
|
||||
createCursorResponse(req, res, CREATE_CURSOR(result.toArray(), true, body.batchSize, body.ttl));
|
||||
}
|
||||
}
|
||||
|
@ -980,7 +971,7 @@ actions.defineHttp({
|
|||
/// This will find all documents from the collection that match the fulltext
|
||||
/// query specified in *query*.
|
||||
///
|
||||
/// In order to use the *fulltext* operator, a fulltext index must be defined
|
||||
/// In order to use the *fulltext* operator, a fulltext index must be defined
|
||||
/// for the collection and the specified attribute.
|
||||
///
|
||||
/// The call expects a JSON object as body with the following attributes:
|
||||
|
@ -1037,8 +1028,7 @@ actions.defineHttp({
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : API + "fulltext",
|
||||
context : "api",
|
||||
url: API + "fulltext",
|
||||
|
||||
callback : function (req, res) {
|
||||
try {
|
||||
|
@ -1056,7 +1046,7 @@ actions.defineHttp({
|
|||
var skip = body.skip;
|
||||
var attribute = body.attribute;
|
||||
var query = body.query;
|
||||
var iid = body.index || undefined;
|
||||
var iid = body.index || undefined;
|
||||
var name = body.collection;
|
||||
var collection = db._collection(name);
|
||||
|
||||
|
@ -1071,15 +1061,15 @@ actions.defineHttp({
|
|||
}
|
||||
else {
|
||||
var result = collection.fulltext(attribute, query, iid);
|
||||
|
||||
|
||||
if (skip !== null && skip !== undefined) {
|
||||
result = result.skip(skip);
|
||||
}
|
||||
|
||||
|
||||
if (limit !== null && limit !== undefined) {
|
||||
result = result.limit(limit);
|
||||
}
|
||||
|
||||
|
||||
createCursorResponse(req, res, CREATE_CURSOR(result.toArray(), true, body.batchSize, body.ttl));
|
||||
}
|
||||
}
|
||||
|
@ -1197,8 +1187,7 @@ actions.defineHttp({
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : API + "by-example",
|
||||
context : "api",
|
||||
url: API + "by-example",
|
||||
|
||||
callback : function (req, res) {
|
||||
try {
|
||||
|
@ -1265,7 +1254,7 @@ actions.defineHttp({
|
|||
/// - *example*: The example document.
|
||||
///
|
||||
/// Returns a result containing the document or *HTTP 404* if no
|
||||
/// document matched the example.
|
||||
/// document matched the example.
|
||||
///
|
||||
/// If more than one document in the collection matches the specified example, only
|
||||
/// one of these documents will be returned, and it is undefined which of the matching
|
||||
|
@ -1331,13 +1320,12 @@ actions.defineHttp({
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : API + "first-example",
|
||||
context : "api",
|
||||
url: API + "first-example",
|
||||
|
||||
callback : function (req, res) {
|
||||
try {
|
||||
var body = actions.getJsonBody(req, res);
|
||||
|
||||
|
||||
if (body === undefined) {
|
||||
return;
|
||||
}
|
||||
|
@ -1358,7 +1346,7 @@ actions.defineHttp({
|
|||
}
|
||||
else {
|
||||
var result = collection.byExample(example).limit(1);
|
||||
|
||||
|
||||
if (result.hasNext()) {
|
||||
actions.resultOk(req, res, actions.HTTP_OK, { document : result.next() });
|
||||
}
|
||||
|
@ -1394,13 +1382,13 @@ actions.defineHttp({
|
|||
///
|
||||
/// The request body must be a JSON object with the following attributes:
|
||||
/// - *collection*: the name of the collection
|
||||
///
|
||||
/// - *count*: the number of documents to return at most. Specifiying count is
|
||||
///
|
||||
/// - *count*: the number of documents to return at most. Specifiying count is
|
||||
/// optional. If it is not specified, it defaults to 1.
|
||||
///
|
||||
/// Note: this method is not supported for sharded collections with more than
|
||||
/// Note: this method is not supported for sharded collections with more than
|
||||
/// one shard.
|
||||
///
|
||||
///
|
||||
/// @RESTRETURNCODES
|
||||
///
|
||||
/// @RESTRETURNCODE{200}
|
||||
|
@ -1461,8 +1449,7 @@ actions.defineHttp({
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : API + "first",
|
||||
context : "api",
|
||||
url: API + "first",
|
||||
|
||||
callback : function (req, res) {
|
||||
try {
|
||||
|
@ -1511,8 +1498,8 @@ actions.defineHttp({
|
|||
///
|
||||
/// The request body must be a JSON object with the following attributes:
|
||||
/// - *collection*: the name of the collection
|
||||
///
|
||||
/// - *count*: the number of documents to return at most. Specifiying count is
|
||||
///
|
||||
/// - *count*: the number of documents to return at most. Specifiying count is
|
||||
/// optional. If it is not specified, it defaults to 1.
|
||||
///
|
||||
/// If the *count* argument is not supplied, the result is the "latest" document
|
||||
|
@ -1520,7 +1507,7 @@ actions.defineHttp({
|
|||
///
|
||||
/// Note: this method is not supported for sharded collections with more than
|
||||
/// one shard.
|
||||
///
|
||||
///
|
||||
/// @RESTRETURNCODES
|
||||
///
|
||||
/// @RESTRETURNCODE{200}
|
||||
|
@ -1581,8 +1568,7 @@ actions.defineHttp({
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : API + "last",
|
||||
context : "api",
|
||||
url: API + "last",
|
||||
|
||||
callback : function (req, res) {
|
||||
try {
|
||||
|
@ -1685,8 +1671,7 @@ actions.defineHttp({
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : API + "range",
|
||||
context : "api",
|
||||
url: API + "range",
|
||||
|
||||
callback : function (req, res) {
|
||||
try {
|
||||
|
@ -1751,8 +1736,8 @@ actions.defineHttp({
|
|||
///
|
||||
/// @RESTDESCRIPTION
|
||||
///
|
||||
/// This will find all documents in the collection that match the specified
|
||||
/// example object.
|
||||
/// This will find all documents in the collection that match the specified
|
||||
/// example object.
|
||||
///
|
||||
/// The call expects a JSON object as body with the following attributes:
|
||||
///
|
||||
|
@ -1763,20 +1748,20 @@ actions.defineHttp({
|
|||
///
|
||||
/// - options: an json object which can contains following attributes:
|
||||
///
|
||||
/// - *waitForSync*: if set to true, then all removal operations will
|
||||
/// - *waitForSync*: if set to true, then all removal operations will
|
||||
/// instantly be synchronised to disk. If this is not specified, then the
|
||||
/// collection's default sync behavior will be applied.
|
||||
///
|
||||
/// - *limit*: an optional value that determines how many documents to
|
||||
/// - *limit*: an optional value that determines how many documents to
|
||||
/// delete at most. If *limit* is specified but is less than the number
|
||||
/// of documents in the collection, it is undefined which of the documents
|
||||
/// of documents in the collection, it is undefined which of the documents
|
||||
/// will be deleted.
|
||||
///
|
||||
/// Note: the *limit* attribute is not supported on sharded collections.
|
||||
/// Note: the *limit* attribute is not supported on sharded collections.
|
||||
/// Using it will result in an error.
|
||||
/// The options attributes waitForSync and limit can given yet without
|
||||
/// an ecapsulation into a json object. but this may be deprecated in future
|
||||
/// versions of arango
|
||||
/// The options attributes waitForSync and limit can given yet without
|
||||
/// an ecapsulation into a json object. but this may be deprecated in future
|
||||
/// versions of arango
|
||||
///
|
||||
/// Returns the number of documents that were deleted.
|
||||
///
|
||||
|
@ -1823,7 +1808,7 @@ actions.defineHttp({
|
|||
/// products.save({ "i": 1});
|
||||
/// products.save({ "a": { "k": 2, "j": 2 }, "i": 1});
|
||||
/// var url = "/_api/simple/remove-by-example";
|
||||
/// var body = '{ "collection": "products", "example" : { "a" : { "j" : 1 } },' +
|
||||
/// var body = '{ "collection": "products", "example" : { "a" : { "j" : 1 } },' +
|
||||
/// '"waitForSync": true, "limit": 2 }';
|
||||
///
|
||||
/// var response = logCurlRequest('PUT', url, body);
|
||||
|
@ -1860,13 +1845,12 @@ actions.defineHttp({
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : API + "remove-by-example",
|
||||
context : "api",
|
||||
url: API + "remove-by-example",
|
||||
|
||||
callback : function (req, res) {
|
||||
try {
|
||||
var body = actions.getJsonBody(req, res);
|
||||
|
||||
|
||||
if (body === undefined) {
|
||||
return;
|
||||
}
|
||||
|
@ -1905,7 +1889,7 @@ actions.defineHttp({
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @startDocuBlock JSA_put_api_simple_replace_by_example
|
||||
/// @brief replaces the body of all documents of a collection that match an
|
||||
/// @brief replaces the body of all documents of a collection that match an
|
||||
/// example
|
||||
///
|
||||
/// @RESTHEADER{PUT /_api/simple/replace-by-example, Replace documents by example}
|
||||
|
@ -1915,10 +1899,10 @@ actions.defineHttp({
|
|||
///
|
||||
/// @RESTDESCRIPTION
|
||||
///
|
||||
/// This will find all documents in the collection that match the specified
|
||||
/// This will find all documents in the collection that match the specified
|
||||
/// example object, and replace the entire document body with the new value
|
||||
/// specified. Note that document meta-attributes such as *_id*, *_key*,
|
||||
/// *_from*, *_to* etc. cannot be replaced.
|
||||
/// *_from*, *_to* etc. cannot be replaced.
|
||||
///
|
||||
/// The call expects a JSON object as body with the following attributes:
|
||||
///
|
||||
|
@ -1932,20 +1916,20 @@ actions.defineHttp({
|
|||
///
|
||||
/// - *options*: an json object which can contain following attributes
|
||||
///
|
||||
/// - *waitForSync*: if set to true, then all removal operations will
|
||||
/// - *waitForSync*: if set to true, then all removal operations will
|
||||
/// instantly be synchronised to disk. If this is not specified, then the
|
||||
/// collection's default sync behavior will be applied.
|
||||
///
|
||||
/// - *limit*: an optional value that determines how many documents to
|
||||
/// - *limit*: an optional value that determines how many documents to
|
||||
/// replace at most. If *limit* is specified but is less than the number
|
||||
/// of documents in the collection, it is undefined which of the documents
|
||||
/// of documents in the collection, it is undefined which of the documents
|
||||
/// will be replaced.
|
||||
///
|
||||
/// Note: the *limit* attribute is not supported on sharded collections.
|
||||
/// Note: the *limit* attribute is not supported on sharded collections.
|
||||
/// Using it will result in an error.
|
||||
/// The options attributes waitForSync and limit can given yet without
|
||||
/// an ecapsulation into a json object. but this may be deprecated in future
|
||||
/// versions of arango
|
||||
/// The options attributes waitForSync and limit can given yet without
|
||||
/// an ecapsulation into a json object. but this may be deprecated in future
|
||||
/// versions of arango
|
||||
///
|
||||
/// Returns the number of documents that were replaced.
|
||||
///
|
||||
|
@ -2015,13 +1999,12 @@ actions.defineHttp({
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : API + "replace-by-example",
|
||||
context : "api",
|
||||
url: API + "replace-by-example",
|
||||
|
||||
callback : function (req, res) {
|
||||
try {
|
||||
var body = actions.getJsonBody(req, res);
|
||||
|
||||
|
||||
if (body === undefined) {
|
||||
return;
|
||||
}
|
||||
|
@ -2074,10 +2057,10 @@ actions.defineHttp({
|
|||
///
|
||||
/// @RESTDESCRIPTION
|
||||
///
|
||||
/// This will find all documents in the collection that match the specified
|
||||
/// This will find all documents in the collection that match the specified
|
||||
/// example object, and partially update the document body with the new value
|
||||
/// specified. Note that document meta-attributes such as *_id*, *_key*,
|
||||
/// *_from*, *_to* etc. cannot be replaced.
|
||||
/// *_from*, *_to* etc. cannot be replaced.
|
||||
///
|
||||
/// The call expects a JSON object as body with the following attributes:
|
||||
///
|
||||
|
@ -2093,20 +2076,20 @@ actions.defineHttp({
|
|||
///
|
||||
/// - *keepNull*: This parameter can be used to modify the behavior when
|
||||
/// handling *null* values. Normally, *null* values are stored in the
|
||||
/// database. By setting the *keepNull* parameter to *false*, this
|
||||
/// behavior can be changed so that all attributes in *data* with *null*
|
||||
/// database. By setting the *keepNull* parameter to *false*, this
|
||||
/// behavior can be changed so that all attributes in *data* with *null*
|
||||
/// values will be removed from the updated document.
|
||||
///
|
||||
/// - *waitForSync*: if set to true, then all removal operations will
|
||||
/// - *waitForSync*: if set to true, then all removal operations will
|
||||
/// instantly be synchronised to disk. If this is not specified, then the
|
||||
/// collection's default sync behavior will be applied.
|
||||
///
|
||||
/// - *limit*: an optional value that determines how many documents to
|
||||
/// - *limit*: an optional value that determines how many documents to
|
||||
/// update at most. If *limit* is specified but is less than the number
|
||||
/// of documents in the collection, it is undefined which of the documents
|
||||
/// of documents in the collection, it is undefined which of the documents
|
||||
/// will be updated.
|
||||
///
|
||||
/// Note: the *limit* attribute is not supported on sharded collections.
|
||||
/// Note: the *limit* attribute is not supported on sharded collections.
|
||||
/// Using it will result in an error.
|
||||
///
|
||||
/// Returns the number of documents that were updated.
|
||||
|
@ -2137,7 +2120,7 @@ actions.defineHttp({
|
|||
/// products.save({ "i": 1});
|
||||
/// products.save({ "a": { "k": 2, "j": 2 }, "i": 1});
|
||||
/// var url = "/_api/simple/update-by-example";
|
||||
/// var body = '{ ' +
|
||||
/// var body = '{ ' +
|
||||
/// '"collection": "products", ' +
|
||||
/// '"example" : { "a" : { "j" : 1 } }, ' +
|
||||
/// '"newValue" : { "a" : { "j" : 22 } }, ' +
|
||||
|
@ -2161,11 +2144,11 @@ actions.defineHttp({
|
|||
/// products.save({ "i": 1});
|
||||
/// products.save({ "a": { "k": 2, "j": 2 }, "i": 1});
|
||||
/// var url = "/_api/simple/update-by-example";
|
||||
/// var body = '{ ' +
|
||||
/// var body = '{ ' +
|
||||
/// '"collection": "products", ' +
|
||||
/// '"example" : { "a" : { "j" : 1 } }, ' +
|
||||
/// '"newValue" : { "a" : { "j" : 22 } }, ' +
|
||||
/// '"options" : { "limit" : 3, "waitForSync": true } ' +
|
||||
/// '"options" : { "limit" : 3, "waitForSync": true } ' +
|
||||
/// '}';
|
||||
///
|
||||
/// var response = logCurlRequest('PUT', url, body);
|
||||
|
@ -2179,13 +2162,12 @@ actions.defineHttp({
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : API + "update-by-example",
|
||||
context : "api",
|
||||
url: API + "update-by-example",
|
||||
|
||||
callback : function (req, res) {
|
||||
try {
|
||||
var body = actions.getJsonBody(req, res);
|
||||
|
||||
|
||||
if (body === undefined) {
|
||||
return;
|
||||
}
|
||||
|
@ -2217,8 +2199,8 @@ actions.defineHttp({
|
|||
limit = body.limit || undefined;
|
||||
options = {waitForSync: waitForSync, keepNull: keepNull, limit: limit};
|
||||
}
|
||||
var result = collection.updateByExample(example,
|
||||
newValue,
|
||||
var result = collection.updateByExample(example,
|
||||
newValue,
|
||||
options);
|
||||
actions.resultOk(req, res, actions.HTTP_OK, { updated: result });
|
||||
}
|
||||
|
@ -2230,11 +2212,11 @@ actions.defineHttp({
|
|||
}
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @}\\)"
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -8,7 +8,7 @@
|
|||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2010-2012 triagens GmbH, Cologne, Germany
|
||||
/// Copyright 2014 ArangoDB 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.
|
||||
|
@ -22,9 +22,10 @@
|
|||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Dr. Frank Celler
|
||||
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
|
||||
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -34,6 +35,8 @@ var internal = require("internal");
|
|||
var console = require("console");
|
||||
var users = require("org/arangodb/users");
|
||||
|
||||
var targetDatabaseVersion = require("org/arangodb/database-version").CURRENT_VERSION;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -45,7 +48,6 @@ var users = require("org/arangodb/users");
|
|||
actions.defineHttp({
|
||||
url : "",
|
||||
prefix : true,
|
||||
context : "admin",
|
||||
|
||||
callback : function (req, res) {
|
||||
try {
|
||||
|
@ -69,6 +71,33 @@ actions.defineHttp({
|
|||
}
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief _admin/database/version
|
||||
/// @startDocuBlock JSF_get_admin_database_version
|
||||
///
|
||||
/// @RESTHEADER{GET /_admin/database/target-version, Return the required version of the database}
|
||||
///
|
||||
/// @RESTDESCRIPTION
|
||||
///
|
||||
/// Returns the database-version that this server requires.
|
||||
/// The version is returned in the *version* attribute of the result.
|
||||
///
|
||||
/// @RESTRETURNCODES
|
||||
///
|
||||
/// @RESTRETURNCODE{200}
|
||||
/// Is returned in all cases.
|
||||
/// @endDocuBlock
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : "_admin/database/target-version",
|
||||
prefix : false,
|
||||
|
||||
callback : function (req, res) {
|
||||
actions.resultOk(req, res, actions.HTTP_OK, { version: String(targetDatabaseVersion) });
|
||||
}
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief returns the role of a server in a cluster
|
||||
/// @startDocuBlock JSF_get_admin_server_role
|
||||
|
@ -83,7 +112,7 @@ actions.defineHttp({
|
|||
/// - *COORDINATOR*: the server is a coordinator in a cluster
|
||||
/// - *PRIMARY*: the server is a primary database server in a cluster
|
||||
/// - *SECONDARY*: the server is a secondary database server in a cluster
|
||||
/// - *UNDEFINED*: in a cluster, *UNDEFINED* is returned if the server role cannot be
|
||||
/// - *UNDEFINED*: in a cluster, *UNDEFINED* is returned if the server role cannot be
|
||||
/// determined. On a single server, *UNDEFINED* is the only possible return
|
||||
/// value.
|
||||
///
|
||||
|
@ -96,7 +125,6 @@ actions.defineHttp({
|
|||
|
||||
actions.defineHttp({
|
||||
url : "_admin/server/role",
|
||||
context : "admin",
|
||||
prefix : false,
|
||||
|
||||
callback : function (req, res) {
|
||||
|
@ -143,7 +171,6 @@ actions.defineHttp({
|
|||
|
||||
actions.defineHttp({
|
||||
url : "_admin/wal/flush",
|
||||
context : "admin",
|
||||
prefix : false,
|
||||
|
||||
callback : function (req, res) {
|
||||
|
@ -153,7 +180,7 @@ actions.defineHttp({
|
|||
}
|
||||
|
||||
/*jslint node: true, stupid: true */
|
||||
internal.wal.flush(req.parameters.waitForSync === "true",
|
||||
internal.wal.flush(req.parameters.waitForSync === "true",
|
||||
req.parameters.waitForCollector === "true");
|
||||
actions.resultOk(req, res, actions.HTTP_OK);
|
||||
}
|
||||
|
@ -169,7 +196,7 @@ actions.defineHttp({
|
|||
///
|
||||
/// Configures the behavior of the write-ahead log. The body of the request
|
||||
/// must be a JSON object with the following attributes:
|
||||
/// - *allowOversizeEntries*: whether or not operations that are bigger than a
|
||||
/// - *allowOversizeEntries*: whether or not operations that are bigger than a
|
||||
/// single logfile can be executed and stored
|
||||
/// - *logfileSize*: the size of each write-ahead logfile
|
||||
/// - *historicLogfiles*: the maximum number of historic logfiles to keep
|
||||
|
@ -177,7 +204,7 @@ actions.defineHttp({
|
|||
/// allocates in the background
|
||||
/// - *throttleWait*: the maximum wait time that operations will wait before
|
||||
/// they get aborted if case of write-throttling (in milliseconds)
|
||||
/// - *throttleWhenPending*: the number of unprocessed garbage-collection
|
||||
/// - *throttleWhenPending*: the number of unprocessed garbage-collection
|
||||
/// operations that, when reached, will activate write-throttling. A value of
|
||||
/// *0* means that write-throttling will not be triggered.
|
||||
///
|
||||
|
@ -194,7 +221,7 @@ actions.defineHttp({
|
|||
/// @endDocuBlock
|
||||
///
|
||||
/// @EXAMPLES
|
||||
///
|
||||
///
|
||||
/// @EXAMPLE_ARANGOSH_RUN{RestWalPropertiesPut}
|
||||
/// var url = "/_admin/wal/properties";
|
||||
/// var body = {
|
||||
|
@ -202,9 +229,9 @@ actions.defineHttp({
|
|||
/// allowOversizeEntries: true
|
||||
/// };
|
||||
/// var response = logCurlRequest('PUT', url, JSON.stringify(body));
|
||||
///
|
||||
///
|
||||
/// assert(response.code === 200);
|
||||
///
|
||||
///
|
||||
/// logJsonResponse(response);
|
||||
/// @END_EXAMPLE_ARANGOSH_RUN
|
||||
/// @endDocuBlock
|
||||
|
@ -230,7 +257,7 @@ actions.defineHttp({
|
|||
/// synchronized write-ahead log data (in milliseconds)
|
||||
/// - *throttleWait*: the maximum wait time that operations will wait before
|
||||
/// they get aborted if case of write-throttling (in milliseconds)
|
||||
/// - *throttleWhenPending*: the number of unprocessed garbage-collection
|
||||
/// - *throttleWhenPending*: the number of unprocessed garbage-collection
|
||||
/// operations that, when reached, will activate write-throttling. A value of
|
||||
/// *0* means that write-throttling will not be triggered.
|
||||
///
|
||||
|
@ -244,13 +271,13 @@ actions.defineHttp({
|
|||
/// @endDocuBlock
|
||||
///
|
||||
/// @EXAMPLES
|
||||
///
|
||||
///
|
||||
/// @EXAMPLE_ARANGOSH_RUN{RestWalPropertiesGet}
|
||||
/// var url = "/_admin/wal/properties";
|
||||
/// var response = logCurlRequest('GET', url);
|
||||
///
|
||||
///
|
||||
/// assert(response.code === 200);
|
||||
///
|
||||
///
|
||||
/// logJsonResponse(response);
|
||||
/// @END_EXAMPLE_ARANGOSH_RUN
|
||||
/// @endDocuBlock
|
||||
|
@ -258,7 +285,6 @@ actions.defineHttp({
|
|||
|
||||
actions.defineHttp({
|
||||
url : "_admin/wal/properties",
|
||||
context : "admin",
|
||||
prefix : false,
|
||||
|
||||
callback : function (req, res) {
|
||||
|
@ -289,7 +315,6 @@ actions.defineHttp({
|
|||
|
||||
actions.defineHttp({
|
||||
url : "_admin/auth/reload",
|
||||
context : "admin",
|
||||
prefix : false,
|
||||
|
||||
callback : function (req, res) {
|
||||
|
@ -304,7 +329,6 @@ actions.defineHttp({
|
|||
|
||||
actions.defineHttp({
|
||||
url : "_admin/aql/reload",
|
||||
context : "admin",
|
||||
prefix : false,
|
||||
|
||||
callback : function (req, res) {
|
||||
|
@ -332,7 +356,6 @@ actions.defineHttp({
|
|||
|
||||
actions.defineHttp({
|
||||
url : "_admin/routing/reload",
|
||||
context : "admin",
|
||||
prefix : false,
|
||||
|
||||
callback : function (req, res) {
|
||||
|
@ -343,12 +366,11 @@ actions.defineHttp({
|
|||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief returns the current routing information
|
||||
/// @brief returns the current routing information
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : "_admin/routing/routes",
|
||||
context : "admin",
|
||||
prefix : false,
|
||||
|
||||
callback : function (req, res) {
|
||||
|
@ -376,7 +398,6 @@ actions.defineHttp({
|
|||
|
||||
actions.defineHttp({
|
||||
url : "_admin/modules/flush",
|
||||
context : "admin",
|
||||
prefix : false,
|
||||
|
||||
callback : function (req, res) {
|
||||
|
@ -406,7 +427,6 @@ actions.defineHttp({
|
|||
|
||||
actions.defineHttp({
|
||||
url : "_admin/time",
|
||||
context : "admin",
|
||||
prefix : false,
|
||||
|
||||
callback : function (req, res) {
|
||||
|
@ -434,7 +454,6 @@ actions.defineHttp({
|
|||
|
||||
actions.defineHttp({
|
||||
url : "_admin/sleep",
|
||||
context : "admin",
|
||||
prefix : false,
|
||||
|
||||
callback : function (req, res) {
|
||||
|
@ -472,7 +491,6 @@ actions.defineHttp({
|
|||
|
||||
actions.defineHttp({
|
||||
url : "_admin/echo",
|
||||
context : "admin",
|
||||
prefix : true,
|
||||
|
||||
callback : function (req, res) {
|
||||
|
@ -500,20 +518,20 @@ actions.defineHttp({
|
|||
/// In case of a distribution, the returned object contains the total count in
|
||||
/// *count* and the distribution list in *counts*. The sum (or total) of the
|
||||
/// individual values is returned in *sum*.
|
||||
///
|
||||
///
|
||||
/// @RESTRETURNCODES
|
||||
///
|
||||
///
|
||||
/// @RESTRETURNCODE{200}
|
||||
/// Statistics were returned successfully.
|
||||
///
|
||||
///
|
||||
/// @EXAMPLES
|
||||
///
|
||||
///
|
||||
/// @EXAMPLE_ARANGOSH_RUN{RestAdminStatistics1}
|
||||
/// var url = "/_admin/statistics";
|
||||
/// var response = logCurlRequest('GET', url);
|
||||
///
|
||||
///
|
||||
/// assert(response.code === 200);
|
||||
///
|
||||
///
|
||||
/// logJsonResponse(response);
|
||||
/// @END_EXAMPLE_ARANGOSH_RUN
|
||||
/// @endDocuBlock
|
||||
|
@ -521,7 +539,6 @@ actions.defineHttp({
|
|||
|
||||
actions.defineHttp({
|
||||
url : "_admin/statistics",
|
||||
context : "admin",
|
||||
prefix : false,
|
||||
|
||||
callback : function (req, res) {
|
||||
|
@ -548,7 +565,7 @@ actions.defineHttp({
|
|||
/// @startDocuBlock JSF_get_admin_statistics_description
|
||||
///
|
||||
/// @RESTHEADER{GET /_admin/statistics-description, Statistics description}
|
||||
///
|
||||
///
|
||||
/// @RESTDESCRIPTION
|
||||
///
|
||||
/// Returns a description of the statistics returned by */_admin/statistics*.
|
||||
|
@ -572,18 +589,18 @@ actions.defineHttp({
|
|||
/// - *units*: Units in which the figure is measured.
|
||||
///
|
||||
/// @RESTRETURNCODES
|
||||
///
|
||||
///
|
||||
/// @RESTRETURNCODE{200}
|
||||
/// Description was returned successfully.
|
||||
///
|
||||
///
|
||||
/// @EXAMPLES
|
||||
///
|
||||
///
|
||||
/// @EXAMPLE_ARANGOSH_RUN{RestAdminStatisticsDescription1}
|
||||
/// var url = "/_admin/statistics-description";
|
||||
/// var response = logCurlRequest('GET', url);
|
||||
///
|
||||
///
|
||||
/// assert(response.code === 200);
|
||||
///
|
||||
///
|
||||
/// logJsonResponse(response);
|
||||
/// @END_EXAMPLE_ARANGOSH_RUN
|
||||
/// @endDocuBlock
|
||||
|
@ -591,7 +608,6 @@ actions.defineHttp({
|
|||
|
||||
actions.defineHttp({
|
||||
url : "_admin/statistics-description",
|
||||
context : "admin",
|
||||
prefix : false,
|
||||
|
||||
callback : function (req, res) {
|
||||
|
@ -611,13 +627,13 @@ actions.defineHttp({
|
|||
name: "Client Connection Statistics",
|
||||
description: "Statistics about the connections."
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
group: "http",
|
||||
name: "HTTP Request Statistics",
|
||||
description: "Statistics about the HTTP requests."
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
group: "server",
|
||||
name: "Server Statistics",
|
||||
|
@ -636,7 +652,7 @@ actions.defineHttp({
|
|||
group: "system",
|
||||
identifier: "userTime",
|
||||
name: "User Time",
|
||||
description: "Amount of time that this process has been scheduled in user mode, " +
|
||||
description: "Amount of time that this process has been scheduled in user mode, " +
|
||||
"measured in seconds.",
|
||||
type: "accumulated",
|
||||
units: "seconds"
|
||||
|
@ -665,7 +681,7 @@ actions.defineHttp({
|
|||
group: "system",
|
||||
identifier: "residentSize",
|
||||
name: "Resident Set Size",
|
||||
description: "The total size of the number of pages the process has in real memory. " +
|
||||
description: "The total size of the number of pages the process has in real memory. " +
|
||||
"This is just the pages which count toward text, data, or stack space. " +
|
||||
"This does not include pages which have not been demand-loaded in, " +
|
||||
"or which are swapped out. The resident set size is reported in bytes.",
|
||||
|
@ -720,7 +736,7 @@ actions.defineHttp({
|
|||
// .............................................................................
|
||||
// client statistics
|
||||
// .............................................................................
|
||||
|
||||
|
||||
{
|
||||
group: "client",
|
||||
identifier: "httpConnections",
|
||||
|
@ -759,7 +775,7 @@ actions.defineHttp({
|
|||
cuts: internal.requestTimeDistribution,
|
||||
units: "seconds"
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
group: "client",
|
||||
identifier: "bytesSent",
|
||||
|
@ -789,7 +805,7 @@ actions.defineHttp({
|
|||
cuts: internal.connectionTimeDistribution,
|
||||
units: "seconds"
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
group: "http",
|
||||
identifier: "requestsTotal",
|
||||
|
@ -798,7 +814,7 @@ actions.defineHttp({
|
|||
type: "accumulated",
|
||||
units: "number"
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
group: "http",
|
||||
identifier: "requestsAsync",
|
||||
|
@ -807,7 +823,7 @@ actions.defineHttp({
|
|||
type: "accumulated",
|
||||
units: "number"
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
group: "http",
|
||||
identifier: "requestsGet",
|
||||
|
@ -816,7 +832,7 @@ actions.defineHttp({
|
|||
type: "accumulated",
|
||||
units: "number"
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
group: "http",
|
||||
identifier: "requestsHead",
|
||||
|
@ -825,7 +841,7 @@ actions.defineHttp({
|
|||
type: "accumulated",
|
||||
units: "number"
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
group: "http",
|
||||
identifier: "requestsPost",
|
||||
|
@ -834,7 +850,7 @@ actions.defineHttp({
|
|||
type: "accumulated",
|
||||
units: "number"
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
group: "http",
|
||||
identifier: "requestsPut",
|
||||
|
@ -843,7 +859,7 @@ actions.defineHttp({
|
|||
type: "accumulated",
|
||||
units: "number"
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
group: "http",
|
||||
identifier: "requestsPatch",
|
||||
|
@ -852,7 +868,7 @@ actions.defineHttp({
|
|||
type: "accumulated",
|
||||
units: "number"
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
group: "http",
|
||||
identifier: "requestsDelete",
|
||||
|
@ -861,7 +877,7 @@ actions.defineHttp({
|
|||
type: "accumulated",
|
||||
units: "number"
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
group: "http",
|
||||
identifier: "requestsOptions",
|
||||
|
@ -870,7 +886,7 @@ actions.defineHttp({
|
|||
type: "accumulated",
|
||||
units: "number"
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
group: "http",
|
||||
identifier: "requestsOther",
|
||||
|
@ -921,21 +937,20 @@ actions.defineHttp({
|
|||
/// @RESTHEADER{POST /_admin/test, Runs tests on server}
|
||||
///
|
||||
/// @RESTBODYPARAM{body,javascript,required}
|
||||
/// A JSON body containing an attribute "tests" which lists the files
|
||||
/// A JSON body containing an attribute "tests" which lists the files
|
||||
/// containing the test suites.
|
||||
///
|
||||
/// @RESTDESCRIPTION
|
||||
///
|
||||
/// Executes the specified tests on the server and returns an object with the
|
||||
/// test results. The object has an attribute "error" which states whether
|
||||
/// any error occurred. The object also has an attribute "passed" which
|
||||
/// test results. The object has an attribute "error" which states whether
|
||||
/// any error occurred. The object also has an attribute "passed" which
|
||||
/// indicates which tests passed and which did not.
|
||||
/// @endDocuBlock
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : "_admin/test",
|
||||
context : "admin",
|
||||
prefix : false,
|
||||
|
||||
callback : function (req, res) {
|
||||
|
@ -944,7 +959,7 @@ actions.defineHttp({
|
|||
if (body === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var tests = body.tests;
|
||||
if (! Array.isArray(tests)) {
|
||||
actions.resultError(req, res,
|
||||
|
@ -955,7 +970,7 @@ actions.defineHttp({
|
|||
|
||||
var jsUnity = require("jsunity");
|
||||
var testResults = { passed: { }, error: false };
|
||||
|
||||
|
||||
tests.forEach (function (test) {
|
||||
var result = false;
|
||||
try {
|
||||
|
@ -980,7 +995,7 @@ actions.defineHttp({
|
|||
/// @RESTHEADER{POST /_admin/execute, Execute program}
|
||||
///
|
||||
/// @RESTBODYPARAM{body,javascript,required}
|
||||
/// The body to be executed.
|
||||
/// The body to be executed.
|
||||
///
|
||||
/// @RESTDESCRIPTION
|
||||
///
|
||||
|
@ -996,7 +1011,6 @@ actions.defineHttp({
|
|||
|
||||
actions.defineHttp({
|
||||
url : "_admin/execute",
|
||||
context : "admin",
|
||||
prefix : false,
|
||||
|
||||
callback : function (req, res) {
|
||||
|
@ -1025,5 +1039,5 @@ actions.defineHttp({
|
|||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @\\}"
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2012 triagens GmbH, Cologne, Germany
|
||||
/// Copyright 2014 ArangoDB 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.
|
||||
|
@ -22,9 +22,10 @@
|
|||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Jan Steemann
|
||||
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
|
||||
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -54,33 +55,33 @@ var actions = require("org/arangodb/actions");
|
|||
/// transaction (mandatory). *collections* must be a JSON array that can
|
||||
/// have the optional sub-attributes *read* and *write*. *read*
|
||||
/// and *write* must each be either lists of collections names or strings
|
||||
/// with a single collection name.
|
||||
/// with a single collection name.
|
||||
///
|
||||
/// - *action*: the actual transaction operations to be executed, in the
|
||||
/// form of stringified Javascript code. The code will be executed on server
|
||||
/// side, with late binding. It is thus critical that the code specified in
|
||||
/// *action* properly sets up all the variables it needs.
|
||||
/// *action* properly sets up all the variables it needs.
|
||||
/// If the code specified in *action* ends with a return statement, the
|
||||
/// value returned will also be returned by the REST API in the *result*
|
||||
/// attribute if the transaction committed successfully.
|
||||
///
|
||||
/// The following optional attributes may also be specified in the request:
|
||||
///
|
||||
/// - *waitForSync*: an optional boolean flag that, if set, will force the
|
||||
/// - *waitForSync*: an optional boolean flag that, if set, will force the
|
||||
/// transaction to write all data to disk before returning.
|
||||
///
|
||||
/// - *lockTimeout*: an optional numeric value that can be used to set a
|
||||
/// timeout for waiting on collection locks. If not specified, a default
|
||||
/// value will be used. Setting *lockTimeout* to *0* will make ArangoDB
|
||||
/// timeout for waiting on collection locks. If not specified, a default
|
||||
/// value will be used. Setting *lockTimeout* to *0* will make ArangoDB
|
||||
/// not time out waiting for a lock.
|
||||
///
|
||||
/// - *params*: optional arguments passed to *action*.
|
||||
///
|
||||
/// If the transaction is fully executed and committed on the server,
|
||||
/// *HTTP 200* will be returned. Additionally, the return value of the
|
||||
/// If the transaction is fully executed and committed on the server,
|
||||
/// *HTTP 200* will be returned. Additionally, the return value of the
|
||||
/// code defined in *action* will be returned in the *result* attribute.
|
||||
///
|
||||
/// For successfully committed transactions, the returned JSON object has the
|
||||
///
|
||||
/// For successfully committed transactions, the returned JSON object has the
|
||||
/// following properties:
|
||||
///
|
||||
/// - *error*: boolean flag to indicate if an error occurred (*false*
|
||||
|
@ -104,16 +105,16 @@ var actions = require("org/arangodb/actions");
|
|||
///
|
||||
/// - *errorMessage*: a descriptive error message
|
||||
///
|
||||
/// If a transaction fails to commit, either by an exception thrown in the
|
||||
/// *action* code, or by an internal error, the server will respond with
|
||||
/// an error.
|
||||
/// If a transaction fails to commit, either by an exception thrown in the
|
||||
/// *action* code, or by an internal error, the server will respond with
|
||||
/// an error.
|
||||
/// Any other errors will be returned with any of the return codes
|
||||
/// *HTTP 400*, *HTTP 409*, or *HTTP 500*.
|
||||
///
|
||||
/// @RESTRETURNCODES
|
||||
///
|
||||
/// @RESTRETURNCODE{200}
|
||||
/// If the transaction is fully executed and committed on the server,
|
||||
/// If the transaction is fully executed and committed on the server,
|
||||
/// *HTTP 200* will be returned.
|
||||
///
|
||||
/// @RESTRETURNCODE{400}
|
||||
|
@ -125,8 +126,8 @@ var actions = require("org/arangodb/actions");
|
|||
/// will respond with *HTTP 404*.
|
||||
///
|
||||
/// @RESTRETURNCODE{500}
|
||||
/// Exceptions thrown by users will make the server respond with a return code of
|
||||
/// *HTTP 500*
|
||||
/// Exceptions thrown by users will make the server respond with a return code of
|
||||
/// *HTTP 500*
|
||||
///
|
||||
/// @EXAMPLES
|
||||
///
|
||||
|
@ -137,10 +138,10 @@ var actions = require("org/arangodb/actions");
|
|||
/// db._drop(cn);
|
||||
/// var products = db._create(cn);
|
||||
/// var url = "/_api/transaction";
|
||||
/// var body = {
|
||||
/// collections: {
|
||||
/// write : "products"
|
||||
/// },
|
||||
/// var body = {
|
||||
/// collections: {
|
||||
/// write : "products"
|
||||
/// },
|
||||
/// action: "function () { var db = require('internal').db; db.products.save({}); return db.products.count(); }"
|
||||
/// };
|
||||
///
|
||||
|
@ -163,9 +164,9 @@ var actions = require("org/arangodb/actions");
|
|||
/// products.save({ "a": 1});
|
||||
/// materials.save({ "b": 1});
|
||||
/// var url = "/_api/transaction";
|
||||
/// var body = {
|
||||
/// collections: {
|
||||
/// write : [ "products", "materials" ]
|
||||
/// var body = {
|
||||
/// collections: {
|
||||
/// write : [ "products", "materials" ]
|
||||
/// },
|
||||
/// action: "function () { var db = require('internal').db; db.products.save({}); db.materials.save({}); return 'worked!'; }"
|
||||
/// };
|
||||
|
@ -185,9 +186,9 @@ var actions = require("org/arangodb/actions");
|
|||
/// db._drop(cn);
|
||||
/// var products = db._create(cn);
|
||||
/// var url = "/_api/transaction";
|
||||
/// var body = {
|
||||
/// collections: {
|
||||
/// write : "products"
|
||||
/// var body = {
|
||||
/// collections: {
|
||||
/// write : "products"
|
||||
/// },
|
||||
/// action : "function () { var db = require('internal').db; db.products.save({ _key: 'abc'}); db.products.save({ _key: 'abc'}); }"
|
||||
/// };
|
||||
|
@ -207,10 +208,10 @@ var actions = require("org/arangodb/actions");
|
|||
/// var products = db._create(cn, { waitForSync: true });
|
||||
/// products.save({ "a": 1 });
|
||||
/// var url = "/_api/transaction";
|
||||
/// var body = {
|
||||
/// var body = {
|
||||
/// collections: {
|
||||
/// read : "products"
|
||||
/// },
|
||||
/// read : "products"
|
||||
/// },
|
||||
/// action : "function () { throw 'doh!'; }"
|
||||
/// };
|
||||
///
|
||||
|
@ -227,10 +228,10 @@ var actions = require("org/arangodb/actions");
|
|||
/// var cn = "products";
|
||||
/// db._drop(cn);
|
||||
/// var url = "/_api/transaction";
|
||||
/// var body = {
|
||||
/// var body = {
|
||||
/// collections: {
|
||||
/// read : "products"
|
||||
/// },
|
||||
/// read : "products"
|
||||
/// },
|
||||
/// action : "function () { return true; }"
|
||||
/// };
|
||||
///
|
||||
|
@ -239,7 +240,7 @@ var actions = require("org/arangodb/actions");
|
|||
///
|
||||
/// logJsonResponse(response);
|
||||
/// @END_EXAMPLE_ARANGOSH_RUN
|
||||
/// @endDocuBlock
|
||||
/// @endDocuBlock
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function post_api_transaction(req, res) {
|
||||
|
@ -260,18 +261,17 @@ function post_api_transaction(req, res) {
|
|||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief gateway
|
||||
/// @brief gateway
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : "_api/transaction",
|
||||
context : "api",
|
||||
|
||||
callback : function (req, res) {
|
||||
try {
|
||||
switch (req.requestType) {
|
||||
case actions.POST:
|
||||
post_api_transaction(req, res);
|
||||
case actions.POST:
|
||||
post_api_transaction(req, res);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -284,7 +284,11 @@ actions.defineHttp({
|
|||
}
|
||||
});
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @}\\)"
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2012 triagens GmbH, Cologne, Germany
|
||||
/// Copyright 2014 ArangoDB 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.
|
||||
|
@ -22,9 +22,10 @@
|
|||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Jan Steemann
|
||||
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
|
||||
/// @author Copyright 2013, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -39,11 +40,6 @@ var graph = require("org/arangodb/general-graph");
|
|||
// --SECTION-- private functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup ArangoAPI
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create a "bad parameter" error
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -390,14 +386,14 @@ function notFound (req, res, code, message) {
|
|||
/// expander: "var connections = [ ];" +
|
||||
/// "if (vertex.name === \"Alice\") {" +
|
||||
/// "config.datasource.getInEdges(vertex).forEach(function (e) {" +
|
||||
/// "connections.push({ " +
|
||||
/// "vertex: require(\"internal\").db._document(e._from), " +
|
||||
/// "connections.push({ " +
|
||||
/// "vertex: require(\"internal\").db._document(e._from), " +
|
||||
/// "edge: e" +
|
||||
/// "});" +
|
||||
/// "});" +
|
||||
/// "}" +
|
||||
/// "if (vertex.name === \"Eve\") {" +
|
||||
/// "config.datasource.getOutEdges(vertex).forEach(function (e) {" +
|
||||
/// "config.datasource.getOutEdges(vertex).forEach(function (e) {" +
|
||||
/// "connections.push({" +
|
||||
/// "vertex: require(\"internal\").db._document(e._to), " +
|
||||
/// "edge: e" +
|
||||
|
@ -737,10 +733,6 @@ function post_api_traversal(req, res) {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- initialiser
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -751,7 +743,6 @@ function post_api_traversal(req, res) {
|
|||
|
||||
actions.defineHttp({
|
||||
url : "_api/traversal",
|
||||
context : "api",
|
||||
|
||||
callback : function (req, res) {
|
||||
try {
|
||||
|
@ -770,11 +761,11 @@ actions.defineHttp({
|
|||
}
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @}\\)"
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
|
||||
/// Copyright 2014 ArangoDB 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.
|
||||
|
@ -22,9 +22,10 @@
|
|||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Jan Steemann
|
||||
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
|
||||
/// @author Copyright 2012-2014, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -46,27 +47,27 @@ var users = require("org/arangodb/users");
|
|||
/// @startDocuBlock JSF_api_user_fetch
|
||||
///
|
||||
/// @RESTHEADER{GET /_api/user/{user}, Fetch User}
|
||||
///
|
||||
///
|
||||
/// @RESTDESCRIPTION
|
||||
///
|
||||
/// Fetches data about the specified user.
|
||||
///
|
||||
///
|
||||
/// The call will return a JSON document with at least the following attributes on success:
|
||||
///
|
||||
///
|
||||
/// * *user*: The name of the user as a string.
|
||||
/// * *active*: An optional flag that specifies whether the user is active.
|
||||
/// * *extra*: An optional JSON object with arbitrary extra data about the user.
|
||||
/// * *changePassword*: An optional flag that specifies whether the user must
|
||||
/// * *changePassword*: An optional flag that specifies whether the user must
|
||||
/// change the password or not.
|
||||
///
|
||||
///
|
||||
/// @RESTRETURNCODES
|
||||
///
|
||||
///
|
||||
/// @RESTRETURNCODE{200}
|
||||
/// The user was found
|
||||
///
|
||||
///
|
||||
/// @RESTRETURNCODE{404}
|
||||
/// The user with user does not exist
|
||||
///
|
||||
///
|
||||
/// @endDocuBlock
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -106,22 +107,22 @@ function get_api_user (req, res) {
|
|||
/// @startDocuBlock JSF_api_user_create
|
||||
///
|
||||
/// @RESTHEADER{POST /_api/user, Create User}
|
||||
///
|
||||
///
|
||||
/// @RESTDESCRIPTION
|
||||
///
|
||||
/// The following data need to be passed in a JSON representation in the body
|
||||
/// The following data need to be passed in a JSON representation in the body
|
||||
/// of the POST request:
|
||||
///
|
||||
/// * *user*: The name of the user as a string. This is mandatory
|
||||
/// * *passwd*: The user password as a string. If no password is specified,
|
||||
/// * *passwd*: The user password as a string. If no password is specified,
|
||||
/// the empty string will be used
|
||||
/// * *active*: An optional flag that specifies whether the user is active.
|
||||
/// If not specified, this will default to true
|
||||
/// * *extra*: An optional JSON object with arbitrary extra data about the user
|
||||
/// * *changePassword*: An optional flag that specifies whethers the user must
|
||||
/// * *changePassword*: An optional flag that specifies whethers the user must
|
||||
/// change the password or not. If not specified, this will default to false
|
||||
///
|
||||
/// If set to true, the only operations allowed are PUT /_api/user or PATCH /_api/user.
|
||||
/// If set to true, the only operations allowed are PUT /_api/user or PATCH /_api/user.
|
||||
/// All other operations will result in a HTTP 403.
|
||||
/// If the user can be added by the server, the server will respond with HTTP 201.
|
||||
/// In case of success, the returned JSON object has the following properties:
|
||||
|
@ -129,10 +130,10 @@ function get_api_user (req, res) {
|
|||
/// * *error*: Boolean flag to indicate that an error occurred (false in this case)
|
||||
/// * *code*: The HTTP status code
|
||||
///
|
||||
/// If the JSON representation is malformed or mandatory data is missing from the request,
|
||||
/// If the JSON representation is malformed or mandatory data is missing from the request,
|
||||
/// the server will respond with HTTP 400.
|
||||
///
|
||||
/// The body of the response will contain a JSON object with additional error details.
|
||||
/// The body of the response will contain a JSON object with additional error details.
|
||||
/// The object has the following attributes:
|
||||
///
|
||||
/// * *error*: Boolean flag to indicate that an error occurred (true in this case)
|
||||
|
@ -141,13 +142,13 @@ function get_api_user (req, res) {
|
|||
/// * *errorMessage*: A descriptive error message
|
||||
///
|
||||
/// @RESTRETURNCODES
|
||||
///
|
||||
///
|
||||
/// @RESTRETURNCODE{201}
|
||||
/// Returned if the user can be added by the server
|
||||
///
|
||||
///
|
||||
/// @RESTRETURNCODE{400}
|
||||
/// If the JSON representation is malformed or mandatory data is missing from the request.
|
||||
///
|
||||
///
|
||||
/// @endDocuBlock
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -205,51 +206,51 @@ function post_api_user (req, res) {
|
|||
/// @startDocuBlock JSF_api_user_replace
|
||||
///
|
||||
/// @RESTHEADER{PUT /_api/user/{user}, Replace User}
|
||||
///
|
||||
///
|
||||
/// @RESTDESCRIPTION
|
||||
///
|
||||
/// Replaces the data of an existing user. The name of an existing user must be specified in user.
|
||||
///
|
||||
///
|
||||
/// The following data can to be passed in a JSON representation in the body of the POST request:
|
||||
///
|
||||
/// * *passwd*: The user password as a string. Specifying a password is mandatory,
|
||||
///
|
||||
/// * *passwd*: The user password as a string. Specifying a password is mandatory,
|
||||
/// but the empty string is allowed for passwords
|
||||
/// * *active*: An optional flag that specifies whether the user is active.
|
||||
/// * *active*: An optional flag that specifies whether the user is active.
|
||||
/// If not specified, this will default to true
|
||||
/// * *extra*: An optional JSON object with arbitrary extra data about the user
|
||||
/// * *changePassword*: An optional flag that specifies whether the user must change
|
||||
/// * *changePassword*: An optional flag that specifies whether the user must change
|
||||
/// the password or not. If not specified, this will default to false
|
||||
///
|
||||
///
|
||||
/// If the user can be replaced by the server, the server will respond with HTTP 200.
|
||||
///
|
||||
///
|
||||
/// In case of success, the returned JSON object has the following properties:
|
||||
///
|
||||
///
|
||||
/// * *error*: Boolean flag to indicate that an error occurred (false in this case)
|
||||
/// * *code*: The HTTP status code
|
||||
///
|
||||
/// If the JSON representation is malformed or mandatory data is missing from the request,
|
||||
/// the server will respond with HTTP 400. If the specified user does not exist,
|
||||
///
|
||||
/// If the JSON representation is malformed or mandatory data is missing from the request,
|
||||
/// the server will respond with HTTP 400. If the specified user does not exist,
|
||||
/// the server will respond with HTTP 404.
|
||||
///
|
||||
/// The body of the response will contain a JSON object with additional
|
||||
///
|
||||
/// The body of the response will contain a JSON object with additional
|
||||
/// error details. The object has the following attributes:
|
||||
///
|
||||
///
|
||||
/// * *error*: Boolean flag to indicate that an error occurred (true in this case)
|
||||
/// * *code*: The HTTP status code
|
||||
/// * *errorNum*: The server error number
|
||||
/// * *errorMessage*: A descriptive error message
|
||||
///
|
||||
///
|
||||
/// @RESTRETURNCODES
|
||||
///
|
||||
///
|
||||
/// @RESTRETURNCODE{200}
|
||||
/// Is returned if the user data can be replaced by the server
|
||||
///
|
||||
///
|
||||
/// @RESTRETURNCODE{400}
|
||||
/// The JSON representation is malformed or mandatory data is missing from the request
|
||||
///
|
||||
/// @RESTRETURNCODE{404}
|
||||
/// The specified user does not exist
|
||||
///
|
||||
///
|
||||
/// @endDocuBlock
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -293,54 +294,54 @@ function put_api_user (req, res) {
|
|||
/// @startDocuBlock JSF_api_user_update
|
||||
///
|
||||
/// @RESTHEADER{PATCH /_api/user/{user}, Update User}
|
||||
///
|
||||
///
|
||||
/// @RESTDESCRIPTION
|
||||
///
|
||||
/// Partially updates the data of an existing user. The name of an existing
|
||||
/// Partially updates the data of an existing user. The name of an existing
|
||||
/// user must be specified in user.
|
||||
///
|
||||
/// The following data can be passed in a JSON representation in the body of the
|
||||
///
|
||||
/// The following data can be passed in a JSON representation in the body of the
|
||||
/// POST request:
|
||||
///
|
||||
/// * *passwd*: The user password as a string. Specifying a password is optional.
|
||||
///
|
||||
/// * *passwd*: The user password as a string. Specifying a password is optional.
|
||||
/// If not specified, the previously existing value will not be modified.
|
||||
/// * *active*: An optional flag that specifies whether the user is active.
|
||||
/// * *active*: An optional flag that specifies whether the user is active.
|
||||
/// If not specified, the previously existing value will not be modified.
|
||||
/// * *extra*: An optional JSON object with arbitrary extra data about the user.
|
||||
/// * *extra*: An optional JSON object with arbitrary extra data about the user.
|
||||
/// If not specified, the previously existing value will not be modified.
|
||||
/// * *changePassword*: An optional flag that specifies whether the user must change
|
||||
/// * *changePassword*: An optional flag that specifies whether the user must change
|
||||
/// the password or not. If not specified, the previously existing value will not be modified.
|
||||
///
|
||||
///
|
||||
/// If the user can be updated by the server, the server will respond with HTTP 200.
|
||||
///
|
||||
///
|
||||
/// In case of success, the returned JSON object has the following properties:
|
||||
///
|
||||
///
|
||||
/// * *error*: Boolean flag to indicate that an error occurred (false in this case)
|
||||
/// * *code*: The HTTP status code
|
||||
///
|
||||
/// If the JSON representation is malformed or mandatory data is missing from the request,
|
||||
/// the server will respond with HTTP 400. If the specified user does not exist,
|
||||
///
|
||||
/// If the JSON representation is malformed or mandatory data is missing from the request,
|
||||
/// the server will respond with HTTP 400. If the specified user does not exist,
|
||||
/// the server will respond with HTTP 404.
|
||||
///
|
||||
/// The body of the response will contain a JSON object with additional error details.
|
||||
///
|
||||
/// The body of the response will contain a JSON object with additional error details.
|
||||
/// The object has the following attributes:
|
||||
///
|
||||
///
|
||||
/// * *error*: Boolean flag to indicate that an error occurred (true in this case)
|
||||
/// * *code*: The HTTP status code
|
||||
/// * *errorNum*: The server error number
|
||||
/// * *errorMessage*: A descriptive error message
|
||||
///
|
||||
///
|
||||
/// @RESTRETURNCODES
|
||||
///
|
||||
///
|
||||
/// @RESTRETURNCODE{200}
|
||||
/// Is returned if the user data can be replaced by the server
|
||||
///
|
||||
///
|
||||
/// @RESTRETURNCODE{400}
|
||||
/// The JSON representation is malformed or mandatory data is missing from the request
|
||||
///
|
||||
/// @RESTRETURNCODE{404}
|
||||
/// The specified user does not exist
|
||||
///
|
||||
///
|
||||
/// @endDocuBlock
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -381,35 +382,35 @@ function patch_api_user (req, res) {
|
|||
/// @startDocuBlock JSF_api_user_delete
|
||||
///
|
||||
/// @RESTHEADER{DELETE /_api/user/{user}, Remove User}
|
||||
///
|
||||
///
|
||||
/// @RESTDESCRIPTION
|
||||
///
|
||||
/// Removes an existing user, identified by user.
|
||||
///
|
||||
///
|
||||
/// If the user can be removed, the server will respond with HTTP 202.
|
||||
/// In case of success, the returned JSON object has the following properties:
|
||||
///
|
||||
///
|
||||
/// * *error*: Boolean flag to indicate that an error occurred (false in this case)
|
||||
/// * *code*: The HTTP status code
|
||||
///
|
||||
///
|
||||
/// If the specified user does not exist, the server will respond with HTTP 404.
|
||||
///
|
||||
/// The body of the response will contain a JSON object with additional error details.
|
||||
///
|
||||
/// The body of the response will contain a JSON object with additional error details.
|
||||
/// The object has the following attributes:
|
||||
///
|
||||
///
|
||||
/// * *error*: Boolean flag to indicate that an error occurred (true in this case)
|
||||
/// * *code*: The HTTP status code
|
||||
/// * *errorNum*: The server error number
|
||||
/// * *errorMessage*: A descriptive error message
|
||||
///
|
||||
///
|
||||
/// @RESTRETURNCODES
|
||||
///
|
||||
///
|
||||
/// @RESTRETURNCODE{202}
|
||||
/// Is returned if the user was removed by the server
|
||||
///
|
||||
///
|
||||
/// @RESTRETURNCODE{404}
|
||||
/// The specified user does not exist
|
||||
///
|
||||
///
|
||||
/// @endDocuBlock
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -446,7 +447,6 @@ function delete_api_user (req, res) {
|
|||
|
||||
actions.defineHttp({
|
||||
url : "_api/user",
|
||||
context : "api",
|
||||
|
||||
callback : function (req, res) {
|
||||
try {
|
||||
|
@ -487,5 +487,5 @@ actions.defineHttp({
|
|||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "/// @brief\\|/// @addtogroup\\|/// @page\\|// --SECTION--\\|/// @\\}\\|/\\*jslint"
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2012 triagens GmbH, Cologne, Germany
|
||||
/// Copyright 2014 ArangoDB 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.
|
||||
|
@ -22,18 +22,14 @@
|
|||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Achim Brandt
|
||||
/// @author Jan Steemann
|
||||
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
|
||||
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup ArangoAPI
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- global variables
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -47,9 +43,9 @@ var arangodb = require("org/arangodb");
|
|||
// --SECTION-- private functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
function formatTimeStamp (timestamp) {
|
||||
function formatTimeStamp (timestamp) {
|
||||
var d = new Date(timestamp * 1000);
|
||||
|
||||
|
||||
var year = d.getUTCFullYear();
|
||||
var month = d.getUTCMonth() + 1;
|
||||
var date = d.getUTCDate();
|
||||
|
@ -74,12 +70,12 @@ function formatTimeStamp (timestamp) {
|
|||
if (seconds < 10) {
|
||||
seconds = "0" + seconds;
|
||||
}
|
||||
|
||||
return year + "-" + month + "-" + date + "T" + hour + ":" + minutes + ":" + seconds + "Z";
|
||||
|
||||
return year + "-" + month + "-" + date + "T" + hour + ":" + minutes + ":" + seconds + "Z";
|
||||
}
|
||||
|
||||
function buildDocumentFromReq(req) {
|
||||
|
||||
|
||||
// Example requests:
|
||||
// Header:
|
||||
// POST /_api/key/example_collection/example_key1 HTTP/1.1
|
||||
|
@ -89,35 +85,35 @@ function buildDocumentFromReq(req) {
|
|||
// Body:
|
||||
// 12
|
||||
//
|
||||
//
|
||||
|
||||
//
|
||||
|
||||
var key = req.suffix[1], i;
|
||||
|
||||
|
||||
for (i = 2; i < req.suffix.length; ++i) {
|
||||
key += "/" + req.suffix[i];
|
||||
}
|
||||
|
||||
var doc = {
|
||||
"$key" : key,
|
||||
"$value" : req.requestBody
|
||||
"$value" : req.requestBody
|
||||
};
|
||||
|
||||
|
||||
if (req.headers["x-voc-expires"] !== undefined) {
|
||||
var d = new Date(req.headers["x-voc-expires"]);
|
||||
// store time stamp as double
|
||||
doc.$expires = d.getTime() / 1000;
|
||||
doc.$expires = d.getTime() / 1000;
|
||||
}
|
||||
|
||||
|
||||
if (req.headers["x-voc-extended"] !== undefined) {
|
||||
var json = JSON.parse(req.headers["x-voc-extended"]);
|
||||
if (json !== undefined) {
|
||||
doc.$extended = json;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// store time stamp as double
|
||||
doc.$created = internal.time();
|
||||
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
||||
|
@ -138,39 +134,39 @@ function postKeyValue(req, res) {
|
|||
}
|
||||
|
||||
var collection = req.suffix[0];
|
||||
|
||||
|
||||
if (db._collection(collection) === null) {
|
||||
actions.collectionNotFound(req, res, collection);
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
if (req.requestBody === "" || req.requestBody === undefined) {
|
||||
actions.resultError(req,
|
||||
res,
|
||||
actions.HTTP_BAD,
|
||||
arangodb.ERROR_KEYVALUE_NO_VALUE,
|
||||
actions.resultError(req,
|
||||
res,
|
||||
actions.HTTP_BAD,
|
||||
arangodb.ERROR_KEYVALUE_NO_VALUE,
|
||||
actions.getErrorMessage(arangodb.ERROR_KEYVALUE_NO_VALUE));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var doc = buildDocumentFromReq(req);
|
||||
|
||||
var oldDoc = db._collection(collection).firstExample("$key", doc.$key);
|
||||
|
||||
|
||||
if (oldDoc !== undefined) {
|
||||
actions.resultError(req,
|
||||
res,
|
||||
actions.HTTP_BAD,
|
||||
arangodb.ERROR_KEYVALUE_KEY_EXISTS,
|
||||
actions.resultError(req,
|
||||
res,
|
||||
actions.HTTP_BAD,
|
||||
arangodb.ERROR_KEYVALUE_KEY_EXISTS,
|
||||
actions.getErrorMessage(arangodb.ERROR_KEYVALUE_KEY_EXISTS));
|
||||
}
|
||||
else {
|
||||
var id = db[collection].save(doc);
|
||||
var id = db[collection].save(doc);
|
||||
var result = {
|
||||
"saved" : true,
|
||||
"_id" : id
|
||||
};
|
||||
actions.resultOk(req, res, actions.HTTP_CREATED, result);
|
||||
actions.resultOk(req, res, actions.HTTP_CREATED, result);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -189,51 +185,51 @@ function putKeyValue(req, res) {
|
|||
}
|
||||
|
||||
var collection = req.suffix[0];
|
||||
|
||||
|
||||
if (db._collection(collection) === null) {
|
||||
actions.collectionNotFound(req, res);
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var doc = buildDocumentFromReq(req);
|
||||
var oldDoc = db._collection(collection).firstExample("$key", doc.$key);
|
||||
var id;
|
||||
|
||||
|
||||
if (oldDoc === undefined) {
|
||||
if (req.parameters.create === 1 || req.parameters.create === "1") {
|
||||
id = db[collection].save(doc);
|
||||
id = db[collection].save(doc);
|
||||
var result = {
|
||||
"saved" : true,
|
||||
"_id" : id
|
||||
};
|
||||
actions.resultOk(req, res, actions.HTTP_CREATED, result);
|
||||
actions.resultOk(req, res, actions.HTTP_CREATED, result);
|
||||
return;
|
||||
}
|
||||
actions.resultError(req,
|
||||
res,
|
||||
actions.HTTP_NOT_FOUND,
|
||||
arangodb.ERROR_KEYVALUE_KEY_NOT_FOUND,
|
||||
actions.resultError(req,
|
||||
res,
|
||||
actions.HTTP_NOT_FOUND,
|
||||
arangodb.ERROR_KEYVALUE_KEY_NOT_FOUND,
|
||||
actions.getErrorMessage(arangodb.ERROR_KEYVALUE_KEY_NOT_FOUND));
|
||||
}
|
||||
else {
|
||||
// get _id
|
||||
id = oldDoc._id;
|
||||
|
||||
|
||||
// save x-voc-created
|
||||
var created = oldDoc.$created;
|
||||
var created = oldDoc.$created;
|
||||
if (created !== undefined) {
|
||||
doc["x-voc-created"] = created;
|
||||
doc["x-voc-created"] = created;
|
||||
}
|
||||
|
||||
|
||||
// replace the document
|
||||
if (db[collection].replace(id, doc)) {
|
||||
actions.resultOk(req, res, actions.HTTP_ACCEPTED, {"changed" : true});
|
||||
if (db[collection].replace(id, doc)) {
|
||||
actions.resultOk(req, res, actions.HTTP_ACCEPTED, {"changed" : true});
|
||||
}
|
||||
else {
|
||||
actions.resultError(req,
|
||||
res,
|
||||
actions.HTTP_BAD,
|
||||
arangodb.ERROR_KEYVALUE_KEY_NOT_CHANGED,
|
||||
actions.resultError(req,
|
||||
res,
|
||||
actions.HTTP_BAD,
|
||||
arangodb.ERROR_KEYVALUE_KEY_NOT_CHANGED,
|
||||
actions.getErrorMessage(arangodb.ERROR_KEYVALUE_KEY_NOT_CHANGED));
|
||||
}
|
||||
}
|
||||
|
@ -253,37 +249,37 @@ function deleteKeyValue(req, res) {
|
|||
}
|
||||
|
||||
var collection = req.suffix[0];
|
||||
|
||||
|
||||
if (db._collection(collection) === null) {
|
||||
actions.collectionNotFound(req, res);
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var key = req.suffix[1], i;
|
||||
|
||||
|
||||
for (i = 2; i < req.suffix.length; ++i) {
|
||||
key += "/" + req.suffix[i];
|
||||
}
|
||||
|
||||
var doc = db._collection(collection).firstExample("$key", key);
|
||||
|
||||
|
||||
if (doc === undefined) {
|
||||
actions.resultError(req,
|
||||
res,
|
||||
actions.HTTP_NOT_FOUND,
|
||||
arangodb.ERROR_KEYVALUE_KEY_NOT_FOUND,
|
||||
actions.resultError(req,
|
||||
res,
|
||||
actions.HTTP_NOT_FOUND,
|
||||
arangodb.ERROR_KEYVALUE_KEY_NOT_FOUND,
|
||||
actions.getErrorMessage(arangodb.ERROR_KEYVALUE_KEY_NOT_FOUND));
|
||||
}
|
||||
else {
|
||||
var id = doc._id;
|
||||
if (db[collection].remove(id)) {
|
||||
actions.resultOk(req, res, actions.HTTP_ACCEPTED, {"removed" : true});
|
||||
if (db[collection].remove(id)) {
|
||||
actions.resultOk(req, res, actions.HTTP_ACCEPTED, {"removed" : true});
|
||||
}
|
||||
else {
|
||||
actions.resultError(req,
|
||||
res,
|
||||
actions.HTTP_BAD,
|
||||
arangodb.ERROR_KEYVALUE_KEY_NOT_REMOVED,
|
||||
actions.resultError(req,
|
||||
res,
|
||||
actions.HTTP_BAD,
|
||||
arangodb.ERROR_KEYVALUE_KEY_NOT_REMOVED,
|
||||
actions.getErrorMessage(arangodb.ERROR_KEYVALUE_KEY_NOT_REMOVED));
|
||||
}
|
||||
}
|
||||
|
@ -295,7 +291,7 @@ function deleteKeyValue(req, res) {
|
|||
/// @REST{GET /_api/key/@FA{collection-name}/@FA{key}}
|
||||
///
|
||||
/// returned headers: "x-voc-expires", "x-voc-extended" and "x-voc-created"
|
||||
///
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function getKeyValue(req, res) {
|
||||
|
@ -305,30 +301,30 @@ function getKeyValue(req, res) {
|
|||
}
|
||||
|
||||
var collection = req.suffix[0];
|
||||
|
||||
|
||||
if (db._collection(collection) === null) {
|
||||
actions.collectionNotFound(req, res);
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var key = req.suffix[1], i;
|
||||
|
||||
|
||||
for (i = 2; i < req.suffix.length; ++i) {
|
||||
key += "/" + req.suffix[i];
|
||||
}
|
||||
|
||||
var doc = db._collection(collection).firstExample("$key", key);
|
||||
|
||||
|
||||
var doc = db._collection(collection).firstExample("$key", key);
|
||||
|
||||
if (doc === undefined) {
|
||||
actions.resultError(req,
|
||||
res,
|
||||
actions.HTTP_NOT_FOUND,
|
||||
arangodb.ERROR_KEYVALUE_KEY_NOT_FOUND,
|
||||
actions.resultError(req,
|
||||
res,
|
||||
actions.HTTP_NOT_FOUND,
|
||||
arangodb.ERROR_KEYVALUE_KEY_NOT_FOUND,
|
||||
actions.getErrorMessage(arangodb.ERROR_KEYVALUE_KEY_NOT_FOUND));
|
||||
}
|
||||
else {
|
||||
var headers = {};
|
||||
|
||||
|
||||
if (doc.$expires !== undefined) {
|
||||
// format timestamp
|
||||
headers["x-voc-expires"] = formatTimeStamp(doc.$expires);
|
||||
|
@ -341,8 +337,8 @@ function getKeyValue(req, res) {
|
|||
// format timestamp
|
||||
headers["x-voc-created"] = formatTimeStamp(doc.$created);
|
||||
}
|
||||
|
||||
actions.resultOk(req, res, actions.HTTP_OK, doc.$value, headers);
|
||||
|
||||
actions.resultOk(req, res, actions.HTTP_OK, doc.$value, headers);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -351,30 +347,29 @@ function getKeyValue(req, res) {
|
|||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief key value pair actions gateway
|
||||
/// @brief key value pair actions gateway
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : "_api/key",
|
||||
context : "api",
|
||||
|
||||
callback : function (req, res) {
|
||||
try {
|
||||
switch (req.requestType) {
|
||||
case (actions.POST) :
|
||||
postKeyValue(req, res);
|
||||
postKeyValue(req, res);
|
||||
break;
|
||||
|
||||
case (actions.GET) :
|
||||
getKeyValue(req, res);
|
||||
getKeyValue(req, res);
|
||||
break;
|
||||
|
||||
case (actions.PUT) :
|
||||
putKeyValue(req, res);
|
||||
putKeyValue(req, res);
|
||||
break;
|
||||
|
||||
case (actions.DELETE) :
|
||||
deleteKeyValue(req, res);
|
||||
deleteKeyValue(req, res);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -388,15 +383,6 @@ actions.defineHttp({
|
|||
});
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup ArangoAPI
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -415,24 +401,24 @@ function searchKeyValue(req, res) {
|
|||
}
|
||||
|
||||
var collection = req.suffix[0];
|
||||
|
||||
|
||||
if (db._collection(collection) === null) {
|
||||
actions.collectionNotFound(req, res);
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var prefix = req.suffix[1], i;
|
||||
|
||||
|
||||
for (i = 2; i < req.suffix.length; ++i) {
|
||||
prefix += "/" + req.suffix[i];
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// TODO: build a query which selects the keys
|
||||
//
|
||||
|
||||
|
||||
var cursor = db._collection(collection).all(), result = [ ];
|
||||
|
||||
|
||||
while (cursor.hasNext() ) {
|
||||
var doc = cursor.next();
|
||||
if (doc.$key !== undefined && doc.$key.indexOf(prefix) === 0) {
|
||||
|
@ -448,20 +434,19 @@ function searchKeyValue(req, res) {
|
|||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief key value pair actions gateway
|
||||
/// @brief key value pair actions gateway
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url : "_api/keys",
|
||||
context : "api",
|
||||
|
||||
callback : function (req, res) {
|
||||
try {
|
||||
switch (req.requestType) {
|
||||
case (actions.GET) :
|
||||
searchKeyValue(req, res);
|
||||
searchKeyValue(req, res);
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
actions.resultUnsupported(req, res);
|
||||
}
|
||||
|
@ -472,11 +457,11 @@ actions.defineHttp({
|
|||
}
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @}\\)"
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
(function() {
|
||||
|
||||
"use strict";
|
||||
|
||||
// Initialise a new FoxxController called controller under the urlPrefix: "cluster".
|
||||
|
@ -51,7 +50,7 @@
|
|||
res.json(!cluster.dispatcherDisabled());
|
||||
});
|
||||
|
||||
if (!cluster.dispatcherDisabled()) {
|
||||
if (! cluster.dispatcherDisabled()) {
|
||||
var Plans = require("./repositories/plans.js"),
|
||||
plans = new Plans.Repository(
|
||||
require("internal").db._collection(
|
||||
|
@ -162,6 +161,7 @@
|
|||
p = body.passwd;
|
||||
plans.saveCredentials(u, p);
|
||||
});
|
||||
|
||||
controller.get("/plan", function(req, res) {
|
||||
res.json(plans.loadConfig());
|
||||
});
|
||||
|
@ -229,7 +229,8 @@
|
|||
|
||||
controller.get("/relaunch", function(req, res) {
|
||||
var k = getStarter();
|
||||
var r = k.relaunch();
|
||||
var u = plans.getCredentials();
|
||||
var r = k.relaunch(u.name, u.passwd);
|
||||
if (r.error) {
|
||||
res.json("Unable to relaunch cluster");
|
||||
res.status(409);
|
||||
|
|
|
@ -24,20 +24,18 @@
|
|||
var planVersion = window.versionHelper.fromString(
|
||||
window.App.clusterPlan.getVersion()
|
||||
);
|
||||
var currentVersion = window.App.footerView.system.version;
|
||||
if (!currentVersion) {
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
cache: false,
|
||||
url: "/_api/version",
|
||||
contentType: "application/json",
|
||||
processData: false,
|
||||
async: false,
|
||||
success: function(data) {
|
||||
currentVersion = data.version;
|
||||
}
|
||||
});
|
||||
}
|
||||
var currentVersion;
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
cache: false,
|
||||
url: "/_admin/database/target-version",
|
||||
contentType: "application/json",
|
||||
processData: false,
|
||||
async: false,
|
||||
success: function(data) {
|
||||
currentVersion = data.version;
|
||||
}
|
||||
});
|
||||
currentVersion = window.versionHelper.fromString(
|
||||
currentVersion
|
||||
);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*jslint indent: 2, maxlen: 120, vars: true, white: true, plusplus: true, nonpropdel: true, sloppy: true */
|
||||
/*jslint indent: 2, maxlen: 120, vars: true, white: true, plusplus: true, nonpropdel: true, sloppy: true, proto: true */
|
||||
/*global require, SYS_GETLINE, SYS_LOG, jqconsole */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -90,6 +90,40 @@
|
|||
log(level, groupLevel + msg);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief try to prettify
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function prepareArgs (args) {
|
||||
var ShapedJson = require("internal").ShapedJson;
|
||||
var result = [];
|
||||
var i;
|
||||
|
||||
if (0 < args.length && typeof args[0] !== "string") {
|
||||
result.push("%s");
|
||||
}
|
||||
|
||||
for (i = 0; i < args.length; ++i) {
|
||||
var arg = args[i];
|
||||
|
||||
if (typeof arg === "object") {
|
||||
if (ShapedJson !== undefined && arg instanceof ShapedJson) {
|
||||
arg = inspect(arg, {prettyPrint: false});
|
||||
}
|
||||
else if (arg === null) {
|
||||
arg = "null";
|
||||
}
|
||||
else if (arg.__proto__ === Object.prototype || Array.isArray(arg)) {
|
||||
arg = inspect(arg, {prettyPrint: false});
|
||||
}
|
||||
}
|
||||
|
||||
result.push(arg);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -109,7 +143,7 @@
|
|||
var msg;
|
||||
|
||||
try {
|
||||
msg = sprintf.apply(sprintf, args);
|
||||
msg = sprintf.apply(sprintf, prepareArgs(args));
|
||||
}
|
||||
catch (err) {
|
||||
msg = err + ": " + args;
|
||||
|
@ -130,7 +164,7 @@
|
|||
var msg;
|
||||
|
||||
try {
|
||||
msg = sprintf.apply(sprintf, arguments);
|
||||
msg = sprintf.apply(sprintf, prepareArgs(arguments));
|
||||
}
|
||||
catch (err) {
|
||||
msg = err + ": " + arguments;
|
||||
|
@ -149,7 +183,7 @@
|
|||
var msg;
|
||||
|
||||
try {
|
||||
msg = sprintf.apply(sprintf, arguments);
|
||||
msg = sprintf.apply(sprintf, prepareArgs(arguments));
|
||||
}
|
||||
catch (err) {
|
||||
msg = err + ": " + arguments;
|
||||
|
@ -183,7 +217,7 @@
|
|||
var msg;
|
||||
|
||||
try {
|
||||
msg = sprintf.apply(sprintf, arguments);
|
||||
msg = sprintf.apply(sprintf, prepareArgs(arguments));
|
||||
}
|
||||
catch (err) {
|
||||
msg = err + ": " + arguments;
|
||||
|
@ -202,7 +236,7 @@
|
|||
var msg;
|
||||
|
||||
try {
|
||||
msg = sprintf.apply(sprintf, arguments);
|
||||
msg = sprintf.apply(sprintf, prepareArgs(arguments));
|
||||
}
|
||||
catch (err) {
|
||||
msg = err + ": " + arguments;
|
||||
|
@ -235,7 +269,7 @@
|
|||
var msg;
|
||||
|
||||
try {
|
||||
msg = sprintf.apply(sprintf, arguments);
|
||||
msg = sprintf.apply(sprintf, prepareArgs(arguments));
|
||||
}
|
||||
catch (err) {
|
||||
msg = err + ": " + arguments;
|
||||
|
@ -255,7 +289,7 @@
|
|||
var msg;
|
||||
|
||||
try {
|
||||
msg = sprintf.apply(sprintf, arguments);
|
||||
msg = sprintf.apply(sprintf, prepareArgs(arguments));
|
||||
}
|
||||
catch (err) {
|
||||
msg = err + ": " + arguments;
|
||||
|
@ -285,7 +319,7 @@
|
|||
var msg;
|
||||
|
||||
try {
|
||||
msg = sprintf.apply(sprintf, arguments);
|
||||
msg = sprintf.apply(sprintf, prepareArgs(arguments));
|
||||
}
|
||||
catch (err) {
|
||||
msg = err + ": " + arguments;
|
||||
|
@ -304,7 +338,7 @@
|
|||
var msg;
|
||||
|
||||
try {
|
||||
msg = sprintf.apply(sprintf, arguments);
|
||||
msg = sprintf.apply(sprintf, prepareArgs(arguments));
|
||||
}
|
||||
catch (err) {
|
||||
msg = err + ": " + arguments;
|
||||
|
@ -371,7 +405,7 @@
|
|||
exports.trace = function () {
|
||||
var err = new Error();
|
||||
err.name = 'trace';
|
||||
err.message = sprintf.apply(sprintf, arguments);
|
||||
err.message = sprintf.apply(sprintf, prepareArgs(arguments));
|
||||
Error.captureStackTrace(err, exports.trace);
|
||||
logGroup("info", err.stack);
|
||||
};
|
||||
|
@ -386,7 +420,7 @@
|
|||
var msg;
|
||||
|
||||
try {
|
||||
msg = sprintf.apply(sprintf, arguments);
|
||||
msg = sprintf.apply(sprintf, prepareArgs(arguments));
|
||||
}
|
||||
catch (err) {
|
||||
msg = err + ": " + arguments;
|
||||
|
@ -405,7 +439,7 @@
|
|||
var msg;
|
||||
|
||||
try {
|
||||
msg = sprintf.apply(sprintf, arguments);
|
||||
msg = sprintf.apply(sprintf, prepareArgs(arguments));
|
||||
}
|
||||
catch (err) {
|
||||
msg = err + ": " + arguments;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*jslint indent: 2, nomen: true, maxlen: 120, vars: true, white: true, plusplus: true, nonpropdel: true, proto: true */
|
||||
/*jslint sloppy: true, regexp: true */
|
||||
/*global require, module, Module, ArangoError, SleepAndRequeue,
|
||||
CONFIGURE_ENDPOINT, REMOVE_ENDPOINT, LIST_ENDPOINTS,
|
||||
CONFIGURE_ENDPOINT, REMOVE_ENDPOINT, LIST_ENDPOINTS, STARTUP_PATH,
|
||||
SYS_BASE64DECODE, SYS_BASE64ENCODE, SYS_DEBUG_SEGFAULT,
|
||||
SYS_DEBUG_CAN_USE_FAILAT, SYS_DEBUG_SET_FAILAT, SYS_DEBUG_REMOVE_FAILAT, SYS_DEBUG_CLEAR_FAILAT,
|
||||
SYS_DOWNLOAD, SYS_EXECUTE, SYS_GET_CURRENT_REQUEST, SYS_GET_CURRENT_RESPONSE,
|
||||
|
@ -258,6 +258,21 @@
|
|||
delete REQUEST_TIME_DISTRIBUTION;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief startupPath
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
exports.startupPath = "";
|
||||
|
||||
if (typeof STARTUP_PATH !== "undefined") {
|
||||
exports.startupPath = STARTUP_PATH;
|
||||
delete STARTUP_PATH;
|
||||
}
|
||||
|
||||
if (exports.startupPath === "") {
|
||||
exports.startupPath = ".";
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -1427,14 +1442,18 @@
|
|||
limitString: false,
|
||||
names: [],
|
||||
output: "",
|
||||
path: "~",
|
||||
prettyPrint: true,
|
||||
path: "~",
|
||||
seen: [],
|
||||
showFunction: true,
|
||||
useColor: false,
|
||||
useToString: false
|
||||
};
|
||||
|
||||
if (options && options.hasOwnProperty("prettyPrint")) {
|
||||
context.prettyPrint = options.prettyPrint;
|
||||
}
|
||||
|
||||
printRecursive(object, context);
|
||||
|
||||
return context.output;
|
||||
|
|
|
@ -1,32 +1,39 @@
|
|||
/*jslint indent: 2, nomen: true, maxlen: 100, vars: true, white: true, plusplus: true, stupid: true*/
|
||||
/*global require, exports, Backbone, window, ArangoQuery, $, data, _ */
|
||||
/*global require, exports, Backbone, activeUser, window, ArangoQuery, $, data, _ */
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
window.ArangoQueries = Backbone.Collection.extend({
|
||||
|
||||
initialize: function(models, options) {
|
||||
this.fetch();
|
||||
|
||||
if (options.activeUser) {
|
||||
this.activeUser = options.activeUser;
|
||||
var result;
|
||||
$.ajax("whoAmI", {async:false}).done(
|
||||
function(data) {
|
||||
result = data.name;
|
||||
}
|
||||
else {
|
||||
);
|
||||
this.activeUser = result;
|
||||
|
||||
if (this.activeUser === 0 || this.activeUser === undefined || this.activeUser === null) {
|
||||
this.activeUser = "root";
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
url: '/_api/user',
|
||||
url: '/_api/user/',
|
||||
|
||||
model: ArangoQuery,
|
||||
|
||||
activeUser: 0,
|
||||
|
||||
currentExtra: {},
|
||||
|
||||
parse: function(response) {
|
||||
var self = this, toReturn;
|
||||
|
||||
_.each(response.result, function(val) {
|
||||
if (val.user === self.activeUser) {
|
||||
self.currentExtra = val.extra;
|
||||
try {
|
||||
if (val.extra.queries) {
|
||||
toReturn = val.extra.queries;
|
||||
|
@ -39,30 +46,167 @@
|
|||
return toReturn;
|
||||
},
|
||||
|
||||
saveQueries: function(data) {
|
||||
var returnValue = false;
|
||||
saveCollectionQueries: function() {
|
||||
if (this.activeUser === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var queries = [],
|
||||
returnValue1 = false,
|
||||
returnValue2 = false,
|
||||
returnValue3 = false,
|
||||
extraBackup = null,
|
||||
self = this;
|
||||
|
||||
this.each(function(query) {
|
||||
queries.push({
|
||||
value: query.attributes.value,
|
||||
name: query.attributes.name
|
||||
});
|
||||
});
|
||||
|
||||
extraBackup = self.currentExtra;
|
||||
extraBackup.queries = [];
|
||||
|
||||
$.ajax({
|
||||
cache: false,
|
||||
type: "PUT",
|
||||
async: false,
|
||||
url: "/_api/user/" + this.activeUser,
|
||||
data: JSON.stringify({
|
||||
extra: extraBackup
|
||||
}),
|
||||
contentType: "application/json",
|
||||
processData: false,
|
||||
success: function() {
|
||||
returnValue1 = true;
|
||||
},
|
||||
error: function() {
|
||||
returnValue1 = false;
|
||||
}
|
||||
});
|
||||
|
||||
//save current collection
|
||||
$.ajax({
|
||||
cache: false,
|
||||
type: "PATCH",
|
||||
async: false,
|
||||
url: "/_api/user/" + this.activeUser,
|
||||
data: JSON.stringify({
|
||||
extra: {
|
||||
queries: queries
|
||||
}
|
||||
}),
|
||||
contentType: "application/json",
|
||||
processData: false,
|
||||
success: function() {
|
||||
returnValue2 = true;
|
||||
},
|
||||
error: function() {
|
||||
returnValue2 = false;
|
||||
}
|
||||
});
|
||||
|
||||
if (returnValue1 === true && returnValue2 === true) {
|
||||
returnValue3 = true;
|
||||
}
|
||||
else {
|
||||
returnValue3 = false;
|
||||
}
|
||||
return returnValue3;
|
||||
},
|
||||
|
||||
saveImportQueries: function(file) {
|
||||
|
||||
if (this.activeUser === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var queries = [];
|
||||
this.each(function(query) {
|
||||
queries.push({
|
||||
value: query.attributes.value,
|
||||
name: query.attributes.name
|
||||
});
|
||||
});
|
||||
|
||||
var self = this,
|
||||
returnValue1 = false,
|
||||
returnValue2 = false,
|
||||
returnValue3 = false;
|
||||
|
||||
var oldQueries = this.currentExtra;
|
||||
|
||||
$.ajax({
|
||||
cache: false,
|
||||
type: "PATCH",
|
||||
async: false,
|
||||
url: "/_api/user/" + this.activeUser,
|
||||
data: {
|
||||
extra: {
|
||||
queries: data
|
||||
}
|
||||
},
|
||||
data: file,
|
||||
contentType: "application/json",
|
||||
processData: false,
|
||||
success: function() {
|
||||
returnValue = true;
|
||||
returnValue1 = true;
|
||||
},
|
||||
error: function() {
|
||||
returnValue = false;
|
||||
returnValue1 = false;
|
||||
}
|
||||
});
|
||||
|
||||
return returnValue;
|
||||
this.fetch({
|
||||
async: false,
|
||||
success: function() {
|
||||
}});
|
||||
|
||||
var newQueries = self.currentExtra;
|
||||
|
||||
var nameTaken = false;
|
||||
|
||||
_.each(oldQueries.queries, function(query) {
|
||||
|
||||
_.each(newQueries.queries, function(newQuery) {
|
||||
if (newQuery.name === query.name) {
|
||||
nameTaken = true;
|
||||
}
|
||||
});
|
||||
|
||||
if (nameTaken === false) {
|
||||
newQueries.queries.push({
|
||||
name: query.name,
|
||||
value: query.value
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
cache: false,
|
||||
type: "PATCH",
|
||||
async: false,
|
||||
url: "/_api/user/" + this.activeUser,
|
||||
data: JSON.stringify({
|
||||
extra: newQueries
|
||||
}),
|
||||
contentType: "application/json",
|
||||
processData: false,
|
||||
success: function() {
|
||||
returnValue2 = true;
|
||||
},
|
||||
error: function() {
|
||||
returnValue2 = false;
|
||||
}
|
||||
});
|
||||
|
||||
this.fetch({
|
||||
async: false
|
||||
});
|
||||
|
||||
if (returnValue1 === true && returnValue2 === true) {
|
||||
returnValue3 = true;
|
||||
}
|
||||
else {
|
||||
returnValue3 = false;
|
||||
}
|
||||
return returnValue3;
|
||||
}
|
||||
|
||||
});
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -9,7 +9,7 @@
|
|||
defaults: {
|
||||
name: "",
|
||||
type: "custom",
|
||||
content: ""
|
||||
value: ""
|
||||
}
|
||||
|
||||
});
|
||||
|
|
|
@ -86,9 +86,7 @@
|
|||
userCollection: this.userCollection
|
||||
});
|
||||
|
||||
this.queryCollection = new window.ArangoQueries([],{
|
||||
activeUser: self.userCollection.activeUser
|
||||
});
|
||||
this.queryCollection = new window.ArangoQueries();
|
||||
|
||||
this.footerView.render();
|
||||
this.naviView.render();
|
||||
|
|
|
@ -5,8 +5,42 @@
|
|||
|
||||
|
||||
<div id="tableDiv" class="innerContent">
|
||||
<div class="document-info">
|
||||
|
||||
<div class="document-type-container">
|
||||
<div id="document-type" class="document-bold-font"></div>
|
||||
<div id="document-id" class="document-thin-font"></div>
|
||||
</div>
|
||||
|
||||
<div class="document-info-container">
|
||||
|
||||
<div class="document-inner-info-container">
|
||||
<div class="document-attribute">
|
||||
<div class="document-bold-font">_rev:</div>
|
||||
<div id="document-rev" class="document-thin-font"></div>
|
||||
</div>
|
||||
<div class="document-attribute">
|
||||
<div class="document-bold-font">_key:</div>
|
||||
<div id="document-key" class="document-thin-font"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="document-inner-info-container edge-info-container">
|
||||
<div class="document-attribute">
|
||||
<div class="document-bold-font">_from:</div>
|
||||
<div id="document-from" class="document-thin-font document-link"></div>
|
||||
</div>
|
||||
<div class="document-attribute">
|
||||
<div class="document-bold-font">_to:</div>
|
||||
<div id="document-to" class="document-thin-font document-link"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div id="documentEditor" class="document-editor"></div>
|
||||
<button id="saveDocumentButton" class="button-success pull-right">Save</button>
|
||||
<button id="saveDocumentButton" class="button-success pull-right">Save</button>
|
||||
<button id="deleteDocumentButton" class="button-danger pull-right">Delete</button>
|
||||
<div class="pull-left shortcuts showHotkeyHelp">
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,25 @@
|
|||
<script id="queryView.ejs" type="text/template">
|
||||
<div class="headerBar">
|
||||
<a class="arangoHeader">AQL Editor</a>
|
||||
|
||||
<div id="queryToolbar" class="headerButtonBar">
|
||||
<ul class="headerButtonList">
|
||||
<li class="enabled">
|
||||
<a id="importQueriesToggle" class="headerButton">
|
||||
<span class="icon_arangodb_import" title="Upload queries from JSON file"></span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="importHeader" class="dropdownImport queryImport">
|
||||
<div class="queryline">
|
||||
<input id="importQueries" name="importQueries" type="file"/>
|
||||
<button id="confirmQueryImport" class="button-success" style="float:right">Import</button>
|
||||
<button id="confirmQueryExport" class="button-success" style="float:right">Export</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="queryContent">
|
||||
|
@ -14,9 +33,6 @@
|
|||
<div id="customsDiv" class="query-div">
|
||||
</div>
|
||||
<div class="queryMethods">
|
||||
<input id="importQueries" name="importQueries" type="file" accept="application/json" />
|
||||
<button id="confirmQueryImport" class="button-success" style="float:right">Import</button>
|
||||
<button id="confirmQueryExport" class="button-success" style="float:right">Export</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, white: true, plusplus: true */
|
||||
/*global Backbone, $, window, arangoHelper, templateEngine, _*/
|
||||
/*global Backbone, $, window, arangoHelper, templateEngine, Joi, _*/
|
||||
|
||||
window.ApplicationsView = Backbone.View.extend({
|
||||
el: '#content',
|
||||
|
@ -28,12 +28,21 @@ window.ApplicationsView = Backbone.View.extend({
|
|||
tableContent.push(
|
||||
window.modalView.createTextEntry(
|
||||
'github-url',
|
||||
'Github Url',
|
||||
'Github information',
|
||||
'',
|
||||
'Your Github URL comes here: username/application-name',
|
||||
'Your Github link comes here: username/application-name',
|
||||
undefined,
|
||||
false,
|
||||
/[<>&'"]/
|
||||
[
|
||||
{
|
||||
rule: Joi.string().required(),
|
||||
msg: "No github link given."
|
||||
},
|
||||
{
|
||||
rule: Joi.string().regex(/^[a-zA-Z0-9]+[\/]/),
|
||||
msg: "No valid github link given."
|
||||
}
|
||||
]
|
||||
));
|
||||
tableContent.push(
|
||||
window.modalView.createTextEntry(
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*jslint indent: 2, nomen: true, maxlen: 100, vars: true, white: true, plusplus: true */
|
||||
/*global require, window, exports, Backbone, EJS, $, templateEngine, arangoHelper*/
|
||||
/*global require, window, exports, Backbone, EJS, $, templateEngine, arangoHelper, Joi*/
|
||||
|
||||
(function() {
|
||||
"use strict";
|
||||
|
@ -92,10 +92,6 @@
|
|||
}
|
||||
else {
|
||||
newname = $('#change-collection-name').val();
|
||||
if (newname === '') {
|
||||
arangoHelper.arangoError('No collection name entered!');
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
var status = this.model.get('status');
|
||||
|
@ -169,8 +165,23 @@
|
|||
if (! window.isCoordinator()) {
|
||||
tableContent.push(
|
||||
window.modalView.createTextEntry(
|
||||
"change-collection-name", "Name", this.model.get('name'), false, "", true
|
||||
)
|
||||
"change-collection-name",
|
||||
"Name",
|
||||
this.model.get('name'),
|
||||
false,
|
||||
"",
|
||||
true,
|
||||
[
|
||||
{
|
||||
rule: Joi.string().required(),
|
||||
msg: "No collection name given."
|
||||
},
|
||||
{
|
||||
rule: Joi.string().regex(/^[a-zA-Z]/),
|
||||
msg: "Collection name must always start with a letter."
|
||||
}
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -186,7 +197,17 @@
|
|||
journalSize,
|
||||
"The maximal size of a journal or datafile (in MB). Must be at least 1.",
|
||||
"",
|
||||
true
|
||||
true,
|
||||
[
|
||||
{
|
||||
rule: Joi.string().required(),
|
||||
msg: "No journal size given."
|
||||
},
|
||||
{
|
||||
rule: Joi.string().regex(/^[0-9]*$/),
|
||||
msg: "Must be a number."
|
||||
}
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*jslint indent: 2, nomen: true, maxlen: 100, vars: true, white: true, plusplus: true */
|
||||
/*global _, Backbone, templateEngine, window, setTimeout, clearTimeout, arangoHelper, $*/
|
||||
/*global _, Backbone, templateEngine, window, setTimeout, clearTimeout, arangoHelper, Joi, $*/
|
||||
|
||||
(function() {
|
||||
"use strict";
|
||||
|
@ -298,7 +298,17 @@
|
|||
"",
|
||||
false,
|
||||
"",
|
||||
true
|
||||
true,
|
||||
[
|
||||
{
|
||||
rule: Joi.string().regex(/^[a-zA-Z]/),
|
||||
msg: "Collection name must always start with a letter."
|
||||
},
|
||||
{
|
||||
rule: Joi.string().required(),
|
||||
msg: "No collection name given."
|
||||
}
|
||||
]
|
||||
)
|
||||
);
|
||||
tableContent.push(
|
||||
|
@ -347,8 +357,18 @@
|
|||
"",
|
||||
"The maximal size of a journal or datafile (in MB). Must be at least 1.",
|
||||
"",
|
||||
false
|
||||
)
|
||||
false,
|
||||
[
|
||||
{
|
||||
rule: Joi.string().required(),
|
||||
msg: "No journal size given."
|
||||
},
|
||||
{
|
||||
rule: Joi.string().regex(/^[0-9]*$/),
|
||||
msg: "Must be a number."
|
||||
}
|
||||
]
|
||||
)
|
||||
);
|
||||
advancedTableContent.push(
|
||||
window.modalView.createSelectEntry(
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*jslint indent: 2, nomen: true, maxlen: 100, vars: true, white: true, plusplus: true */
|
||||
/*global window, document, Backbone, EJS, SwaggerUi, hljs, $, arangoHelper, templateEngine */
|
||||
/*global window, document, Backbone, EJS, SwaggerUi, hljs, $, arangoHelper, templateEngine, Joi*/
|
||||
(function() {
|
||||
|
||||
"use strict";
|
||||
|
@ -242,7 +242,18 @@
|
|||
"",
|
||||
false,
|
||||
"Database Name",
|
||||
true
|
||||
true,
|
||||
[
|
||||
{
|
||||
rule: Joi.string().regex(/^[a-zA-Z]/),
|
||||
msg: "Database name must always start with a letter."
|
||||
},
|
||||
{
|
||||
rule: Joi.string().required(),
|
||||
msg: "No database name given."
|
||||
}
|
||||
]
|
||||
|
||||
)
|
||||
);
|
||||
tableContent.push(
|
||||
|
|
|
@ -13,28 +13,119 @@
|
|||
|
||||
events: {
|
||||
"click #saveDocumentButton" : "saveDocument",
|
||||
"click #deleteDocumentButton" : "deleteDocumentModal",
|
||||
"click #confirmDeleteDocument" : "deleteDocument",
|
||||
"click #document-from" : "navigateToDocument",
|
||||
"click #document-to" : "navigateToDocument",
|
||||
"dblclick #documentEditor tr" : "addProperty"
|
||||
},
|
||||
|
||||
editor: 0,
|
||||
|
||||
typeCheck: function (type) {
|
||||
var result;
|
||||
var result, type2;
|
||||
if (type === 'edge') {
|
||||
result = this.collection.getEdge(this.colid, this.docid);
|
||||
type2 = "Edge: ";
|
||||
}
|
||||
else if (type === 'document') {
|
||||
result = this.collection.getDocument(this.colid, this.docid);
|
||||
type2 = "Document: ";
|
||||
}
|
||||
if (result === true) {
|
||||
this.fillInfo(type2);
|
||||
this.fillEditor();
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
deleteDocumentModal: function() {
|
||||
var buttons = [], tableContent = [];
|
||||
tableContent.push(
|
||||
window.modalView.createReadOnlyEntry(
|
||||
'doc-delete-button',
|
||||
'Delete',
|
||||
'Delete this ' + this.type + '?',
|
||||
undefined,
|
||||
undefined,
|
||||
false,
|
||||
/[<>&'"]/
|
||||
)
|
||||
);
|
||||
buttons.push(
|
||||
window.modalView.createDeleteButton('Delete', this.deleteDocument.bind(this))
|
||||
);
|
||||
window.modalView.show('modalTable.ejs', 'Delete Document', buttons, tableContent, undefined,
|
||||
null);
|
||||
},
|
||||
|
||||
deleteDocument: function() {
|
||||
|
||||
var result;
|
||||
|
||||
if (this.type === 'document') {
|
||||
result = this.collection.deleteDocument(this.colid, this.docid);
|
||||
if (result === false) {
|
||||
arangoHelper.arangoError('Document error:','Could not delete');
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (this.type === 'edge') {
|
||||
result = this.collection.deleteEdge(this.colid, this.docid);
|
||||
if (result === false) {
|
||||
arangoHelper.arangoError('Edge error:', 'Could not delete');
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (result === true) {
|
||||
var navigateTo = "collection/" + encodeURIComponent(this.colid) + '/documents/1';
|
||||
window.modalView.hide();
|
||||
window.App.navigate(navigateTo, {trigger: true});
|
||||
}
|
||||
},
|
||||
|
||||
navigateToDocument: function(e) {
|
||||
var navigateTo = $(e.target).attr("documentLink");
|
||||
if (navigateTo) {
|
||||
window.App.navigate(navigateTo, {trigger: true});
|
||||
}
|
||||
},
|
||||
|
||||
fillInfo: function(type) {
|
||||
var _id = this.collection.first().get("_id"),
|
||||
_key = this.collection.first().get("_key"),
|
||||
_rev = this.collection.first().get("_rev"),
|
||||
_from = this.collection.first().get("_from"),
|
||||
_to = this.collection.first().get("_to");
|
||||
|
||||
$('#document-type').text(type);
|
||||
$('#document-id').text(_id);
|
||||
$('#document-key').text(_key);
|
||||
$('#document-rev').text(_rev);
|
||||
|
||||
if (_from && _to) {
|
||||
|
||||
var hrefFrom = "collection/"
|
||||
+ encodeURIComponent(_from.split("/")[0]) + "/"
|
||||
+ encodeURIComponent(_from.split("/")[1]);
|
||||
var hrefTo = "collection/"
|
||||
+ encodeURIComponent(_to.split("/")[0]) + "/"
|
||||
+ encodeURIComponent(_to.split("/")[1]);
|
||||
|
||||
$('#document-from').text(_from);
|
||||
$('#document-from').attr("documentLink", hrefFrom);
|
||||
$('#document-to').text(_to);
|
||||
$('#document-to').attr("documentLink", hrefTo);
|
||||
}
|
||||
else {
|
||||
$('.edge-info-container').hide();
|
||||
}
|
||||
},
|
||||
|
||||
fillEditor: function() {
|
||||
var toFill = this.removeReadonlyKeys(this.collection.first().attributes);
|
||||
this.editor.set(toFill);
|
||||
$('.ace_content').attr('font-size','11pt');
|
||||
},
|
||||
|
||||
jsonContentChanged: function() {
|
||||
|
@ -113,6 +204,7 @@
|
|||
}
|
||||
catch (e) {
|
||||
this.errorConfirmation();
|
||||
this.disableSaveButton();
|
||||
}
|
||||
|
||||
model = JSON.stringify(model);
|
||||
|
|
|
@ -388,8 +388,8 @@
|
|||
this.alreadyClicked = true;
|
||||
$("#confirmDeleteBtn").attr("disabled", false);
|
||||
$('#docDeleteModal').modal('show');
|
||||
|
||||
},
|
||||
|
||||
confirmDelete: function () {
|
||||
$("#confirmDeleteBtn").attr("disabled", true);
|
||||
var hash = window.location.hash.split("/");
|
||||
|
@ -399,6 +399,7 @@
|
|||
this.reallyDelete();
|
||||
}
|
||||
},
|
||||
|
||||
reallyDelete: function () {
|
||||
var self = this;
|
||||
var row = $(self.target).closest("tr").get(0);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*jslint indent: 2, nomen: true, maxlen: 100, vars: true, white: true, plusplus: true */
|
||||
/*global Backbone, $, window, _ */
|
||||
/*global Backbone, $, window, setTimeout, Joi, _ */
|
||||
/*global templateEngine*/
|
||||
|
||||
(function () {
|
||||
|
@ -46,7 +46,8 @@
|
|||
if (regexp){
|
||||
// returns true if the string contains the match
|
||||
obj.validateInput = function(el){
|
||||
return regexp.test(el.val());
|
||||
//return regexp.test(el.val());
|
||||
return regexp;
|
||||
};
|
||||
}
|
||||
return obj;
|
||||
|
@ -299,12 +300,54 @@
|
|||
|
||||
self.testInput = (function(){
|
||||
_.each(tableContent,function(r){
|
||||
if(r.validateInput){
|
||||
|
||||
if(r.validateInput) {
|
||||
//catch result of validation and act
|
||||
$('#' + r.id).on('keyup', function(){
|
||||
if(r.validateInput($('#' + r.id))){
|
||||
|
||||
var validation = r.validateInput($('#' + r.id));
|
||||
var error = false, msg;
|
||||
|
||||
_.each(validation, function(validator, key) {
|
||||
|
||||
var schema = Joi.object().keys({
|
||||
toCheck: validator.rule
|
||||
});
|
||||
|
||||
Joi.validate({
|
||||
toCheck: $('#' + r.id).val()
|
||||
},
|
||||
schema,
|
||||
function (err, value) {
|
||||
|
||||
if (err) {
|
||||
msg = validator.msg;
|
||||
error = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
var errorElement = $('#'+r.id).next()[0];
|
||||
|
||||
if(error === true){
|
||||
// if validation throws an error
|
||||
$('#' + r.id).addClass('invalid-input');
|
||||
} else {
|
||||
|
||||
if (errorElement) {
|
||||
//error element available
|
||||
$(errorElement).text(msg);
|
||||
}
|
||||
else {
|
||||
//render error element
|
||||
$('#' + r.id).after('<p class="errorMessage">' + msg+ '</p>');
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
//validation throws success
|
||||
$('#' + r.id).removeClass('invalid-input');
|
||||
if (errorElement) {
|
||||
$(errorElement).remove();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -325,6 +368,13 @@
|
|||
if (this.enableHotKeys) {
|
||||
this.createModalHotkeys();
|
||||
}
|
||||
|
||||
//if input-field is available -> autofocus first one
|
||||
var focus = $('#modal-dialog').find('input');
|
||||
if (focus) {
|
||||
setTimeout(function() {$(focus[0]).focus();}, 800);
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
|
|
|
@ -40,7 +40,13 @@
|
|||
'click #arangoQueryTable .table-cell1': 'editCustomQuery',
|
||||
'click #arangoQueryTable .table-cell2 a': 'deleteAQL',
|
||||
'click #confirmQueryImport': 'importCustomQueries',
|
||||
'click #confirmQueryExport': 'renderExportCustomQueries'
|
||||
'click #confirmQueryExport': 'exportCustomQueries',
|
||||
'click #importQueriesToggle': 'showImportMenu'
|
||||
},
|
||||
|
||||
showImportMenu: function(e) {
|
||||
$('#importQueriesToggle').toggleClass('activated');
|
||||
$('#importHeader').slideToggle(200);
|
||||
},
|
||||
|
||||
createCustomQueryModal: function(){
|
||||
|
@ -177,7 +183,6 @@
|
|||
if (typeof Storage) {
|
||||
if (localStorage.getItem("querySize") > 0) {
|
||||
querySize = parseInt(localStorage.getItem("querySize"), 10);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -266,7 +271,6 @@
|
|||
$("#queryDiv").show();
|
||||
$("#customsDiv").show();
|
||||
|
||||
this.renderExportCustomQueries();
|
||||
this.initQueryImport();
|
||||
|
||||
this.switchTab('query-switch');
|
||||
|
@ -275,6 +279,7 @@
|
|||
|
||||
initQueryImport: function () {
|
||||
var self = this;
|
||||
self.allowUpload = false;
|
||||
$('#importQueries').change(function(e) {
|
||||
self.files = e.target.files || e.dataTransfer.files;
|
||||
self.file = self.files[0];
|
||||
|
@ -284,21 +289,34 @@
|
|||
},
|
||||
|
||||
importCustomQueries: function () {
|
||||
var result, fetched, self = this;
|
||||
var result, self = this;
|
||||
if (this.allowUpload === true) {
|
||||
result = self.collection.saveQueries(self.file);
|
||||
result = self.collection.saveImportQueries(self.file);
|
||||
|
||||
if (result === true) {
|
||||
this.updateLocalQueries();
|
||||
this.renderSelectboxes();
|
||||
this.updateTable();
|
||||
$('#customs-switch').click();
|
||||
self.allowUpload = false;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
renderExportCustomQueries: function () {
|
||||
var toExport = [];
|
||||
exportCustomQueries: function () {
|
||||
var toExport = {}, exportArray = [];
|
||||
_.each(this.customQueries, function(value, key) {
|
||||
toExport.push({name: value.name, value: value.value});
|
||||
exportArray.push({name: value.name, value: value.value});
|
||||
});
|
||||
var data = "text/json;charset=utf-8,"+ encodeURIComponent(JSON.stringify(toExport));
|
||||
toExport = {
|
||||
"extra": {
|
||||
"queries": exportArray
|
||||
}
|
||||
};
|
||||
|
||||
$('#confirmQueryExport').html('<a id="downloadQueryAsJson" href="data:'+
|
||||
data+'"download="queries.json">Export</a>');
|
||||
var exportData = 'data:plain/text;charset=utf-8,';
|
||||
exportData += JSON.stringify(toExport);
|
||||
window.open(encodeURI(exportData));
|
||||
},
|
||||
|
||||
deselect: function (editor) {
|
||||
|
@ -331,26 +349,40 @@
|
|||
},
|
||||
|
||||
getAQL: function () {
|
||||
var self = this, result;
|
||||
|
||||
this.collection.fetch({
|
||||
async: false
|
||||
});
|
||||
|
||||
//old storage method
|
||||
if (localStorage.getItem("customQueries")) {
|
||||
this.customQueries = JSON.parse(localStorage.getItem("customQueries"));
|
||||
|
||||
var queries = JSON.parse(localStorage.getItem("customQueries"));
|
||||
//save queries in user collections extra attribute
|
||||
_.each(queries, function(oldQuery) {
|
||||
self.collection.add({
|
||||
value: oldQuery.value,
|
||||
name: oldQuery.name
|
||||
});
|
||||
});
|
||||
result = self.collection.saveCollectionQueries();
|
||||
|
||||
if (result === true) {
|
||||
//and delete them from localStorage
|
||||
localStorage.removeItem("customQueries");
|
||||
}
|
||||
}
|
||||
|
||||
this.updateLocalQueries();
|
||||
},
|
||||
|
||||
deleteAQL: function (e) {
|
||||
|
||||
var deleteName = $(e.target).parent().parent().parent().children().first().text();
|
||||
var tempArray = [];
|
||||
|
||||
$.each(this.customQueries, function (k, v) {
|
||||
if (deleteName !== v.name) {
|
||||
tempArray.push({
|
||||
name: v.name,
|
||||
value: v.value
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
this.customQueries = tempArray;
|
||||
var toDelete = this.collection.findWhere({name: deleteName});
|
||||
this.collection.remove(toDelete);
|
||||
this.collection.saveCollectionQueries();
|
||||
|
||||
this.updateLocalQueries();
|
||||
this.renderSelectboxes();
|
||||
|
@ -358,8 +390,16 @@
|
|||
},
|
||||
|
||||
updateLocalQueries: function () {
|
||||
localStorage.setItem("customQueries", JSON.stringify(this.customQueries));
|
||||
this.renderExportCustomQueries();
|
||||
var self = this;
|
||||
//localStorage.setItem("customQueries", JSON.stringify(this.customQueries));
|
||||
this.customQueries = [];
|
||||
|
||||
this.collection.each(function(model) {
|
||||
self.customQueries.push({
|
||||
name: model.attributes.name,
|
||||
value: model.attributes.value
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
saveAQL: function (e) {
|
||||
|
@ -378,7 +418,6 @@
|
|||
}
|
||||
|
||||
var content = inputEditor.getValue();
|
||||
|
||||
//check for already existing entry
|
||||
var quit = false;
|
||||
$.each(this.customQueries, function (k, v) {
|
||||
|
@ -396,11 +435,20 @@
|
|||
}
|
||||
|
||||
if (!isUpdate) {
|
||||
this.customQueries.push({
|
||||
//this.customQueries.push({
|
||||
// name: saveName,
|
||||
// value: content
|
||||
//});
|
||||
this.collection.add({
|
||||
name: saveName,
|
||||
value: content
|
||||
});
|
||||
}
|
||||
else {
|
||||
var toModifiy = this.collection.findWhere({name: saveName});
|
||||
toModifiy.set("value", content);
|
||||
}
|
||||
this.collection.saveCollectionQueries();
|
||||
|
||||
window.modalView.hide();
|
||||
|
||||
|
@ -502,9 +550,9 @@
|
|||
var self = this;
|
||||
var inputEditor = ace.edit("aqlEditor");
|
||||
var selectedText = inputEditor.session.getTextRange(inputEditor.getSelectionRange());
|
||||
|
||||
|
||||
this.switchTab("result-switch");
|
||||
|
||||
|
||||
var sizeBox = $('#querySize');
|
||||
var data = {
|
||||
query: selectedText || inputEditor.getValue(),
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
.document-info {
|
||||
|
||||
background-color: #ffffff;
|
||||
border: 1px solid rgba(0, 0, 0, 0.2);
|
||||
margin-bottom: 8px;
|
||||
margin-top: -10px;
|
||||
min-height: 65px;
|
||||
padding: 5px;
|
||||
|
||||
.document-info-container {
|
||||
clear: both;
|
||||
width: 100%;
|
||||
|
||||
.document-inner-info-container {
|
||||
float: left;
|
||||
margin-top: 5px;
|
||||
margin-left: 10px;
|
||||
|
||||
.document-attribute {
|
||||
margin-right: 20px;
|
||||
@extend %clear-float;
|
||||
div {
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.document-bold-font {
|
||||
font-family: droid sans mono, monospace, courier new, courier, sans-serif;
|
||||
font-size: 11pt;
|
||||
min-width: 55px;
|
||||
}
|
||||
|
||||
.document-thin-font {
|
||||
color: green;
|
||||
font-family: droid sans mono, monospace, courier new, courier, sans-serif;
|
||||
font-size: 11pt;
|
||||
}
|
||||
|
||||
.document-type-container {
|
||||
div {
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.document-link:hover {
|
||||
cursor: pointer;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.jsoneditor {
|
||||
.tree {
|
||||
div {
|
||||
font-size: 11pt;
|
||||
}
|
||||
}
|
||||
|
||||
.ace_layer {
|
||||
div {
|
||||
font-size: 11pt;
|
||||
}
|
||||
}
|
||||
|
||||
.ace_text-layer {
|
||||
div {
|
||||
font-size: 11pt;
|
||||
}
|
||||
}
|
||||
|
||||
.ace_line_group {
|
||||
div {
|
||||
font-size: 11pt;
|
||||
}
|
||||
}
|
||||
|
||||
.outer {
|
||||
.tree > table > tbody > tr:first-of-type {
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -162,6 +162,14 @@
|
|||
.tab-content {
|
||||
min-height: 200px;
|
||||
}
|
||||
|
||||
.errorMessage {
|
||||
color: red;
|
||||
font-size: 9pt;
|
||||
margin-bottom: 5px;
|
||||
margin-top: -5px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.modal-text {
|
||||
|
|
|
@ -324,3 +324,7 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.queryImport {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
|
|
@ -1375,7 +1375,7 @@ ul.link-dropdown-menu, ul.user-dropdown-menu, ul.gv-dropdown-menu, div.navlogo,
|
|||
div.navmenu, div.footer-right, div.footer-right p, ul.headerButtonList li, div .tile div.iconSet span, div .bigtile div.iconSet span, div.headerBar > div.headerButtonBar, .fixedDropdown button, .dashboard-sub-bar-menu, .query-button, .arango-tab li, .show-save-state, div.gv_colour_list, .docsThirdCol {
|
||||
float: right; }
|
||||
|
||||
div.tileList:after, div.resizecontainer:after, div.headerBar > div.headerButtonBar:after, .detail-chart:after, .dashboard-sub-bar:after, .dashboard-medium-chart .dashboard-medium-chart-menu:after, .dashboard-medium-chart .dashboard-medium-chart-inner:after, .dashboard-tendency-container .dashboard-tendency-chart:after, .dashboard-bar-chart-container .dashboard-bar-chart:after, .dashboard-row:after, #distributionChartDiv:after, .lineChartDiv:after, .arango-tab:after, .pagination-line li:after {
|
||||
div.tileList:after, div.resizecontainer:after, div.headerBar > div.headerButtonBar:after, .detail-chart:after, .dashboard-sub-bar:after, .dashboard-medium-chart .dashboard-medium-chart-menu:after, .dashboard-medium-chart .dashboard-medium-chart-inner:after, .dashboard-tendency-container .dashboard-tendency-chart:after, .dashboard-bar-chart-container .dashboard-bar-chart:after, .dashboard-row:after, #distributionChartDiv:after, .lineChartDiv:after, .arango-tab:after, .pagination-line li:after, .document-info .document-info-container .document-inner-info-container .document-attribute:after {
|
||||
clear: both;
|
||||
content: '.';
|
||||
display: block;
|
||||
|
@ -4458,6 +4458,11 @@ div.breadcrumb a.disabledBread {
|
|||
width: 398px; }
|
||||
.modal-body .tab-content {
|
||||
min-height: 200px; }
|
||||
.modal-body .errorMessage {
|
||||
color: red;
|
||||
font-size: 9pt;
|
||||
margin-bottom: 5px;
|
||||
margin-top: -5px; }
|
||||
|
||||
.modal-text {
|
||||
font-weight: 300;
|
||||
|
@ -5167,6 +5172,9 @@ pre.gv-object-view {
|
|||
white-space: nowrap !important;
|
||||
width: 40px; }
|
||||
|
||||
.queryImport {
|
||||
margin-bottom: 10px; }
|
||||
|
||||
.display-none {
|
||||
display: none; }
|
||||
|
||||
|
@ -5786,6 +5794,50 @@ input.gv-radio-button {
|
|||
@media (min-width: 1042px) and (max-width: 1284px) {
|
||||
.arango-collection-ul a {
|
||||
font-size: 13px; } }
|
||||
.document-info {
|
||||
background-color: #ffffff;
|
||||
border: 1px solid rgba(0, 0, 0, 0.2);
|
||||
margin-bottom: 8px;
|
||||
margin-top: -10px;
|
||||
min-height: 65px;
|
||||
padding: 5px; }
|
||||
.document-info .document-info-container {
|
||||
clear: both;
|
||||
width: 100%; }
|
||||
.document-info .document-info-container .document-inner-info-container {
|
||||
float: left;
|
||||
margin-top: 5px;
|
||||
margin-left: 10px; }
|
||||
.document-info .document-info-container .document-inner-info-container .document-attribute {
|
||||
margin-right: 20px; }
|
||||
.document-info .document-info-container .document-inner-info-container .document-attribute div {
|
||||
float: left; }
|
||||
.document-info .document-bold-font {
|
||||
font-family: droid sans mono, monospace, courier new, courier, sans-serif;
|
||||
font-size: 11pt;
|
||||
min-width: 55px; }
|
||||
.document-info .document-thin-font {
|
||||
color: green;
|
||||
font-family: droid sans mono, monospace, courier new, courier, sans-serif;
|
||||
font-size: 11pt; }
|
||||
.document-info .document-type-container div {
|
||||
float: left; }
|
||||
|
||||
.document-link:hover {
|
||||
cursor: pointer;
|
||||
text-decoration: underline; }
|
||||
|
||||
.jsoneditor .tree div {
|
||||
font-size: 11pt; }
|
||||
.jsoneditor .ace_layer div {
|
||||
font-size: 11pt; }
|
||||
.jsoneditor .ace_text-layer div {
|
||||
font-size: 11pt; }
|
||||
.jsoneditor .ace_line_group div {
|
||||
font-size: 11pt; }
|
||||
.jsoneditor .outer .tree > table > tbody > tr:first-of-type {
|
||||
visibility: hidden; }
|
||||
|
||||
.hotkeysList .hotkeysLabel {
|
||||
clear: both;
|
||||
color: #000;
|
||||
|
|
|
@ -61,6 +61,8 @@
|
|||
@import 'snippet';
|
||||
// screen sizes
|
||||
@import 'screenSizes';
|
||||
// document view
|
||||
@import 'documentView';
|
||||
|
||||
// screen hotkeys
|
||||
@import 'hotkeys';
|
||||
|
|
|
@ -202,6 +202,7 @@
|
|||
"frontend/js/lib/swagger.js",
|
||||
"frontend/js/lib/swagger-ui.js",
|
||||
"frontend/js/lib/highlight.7.3.pack.js",
|
||||
"frontend/js/lib/joi.browser.js",
|
||||
"frontend/js/lib/md5.js"
|
||||
]
|
||||
},
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
var _ = require("underscore"),
|
||||
Foxx = require("org/arangodb/foxx"),
|
||||
version = require("internal").version,
|
||||
version = require("org/arangodb/database-version").CURRENT_VERSION + "", // do not use new String, there is bug in update
|
||||
Plans;
|
||||
|
||||
Plans = Foxx.Repository.extend({
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*jslint indent: 2, maxlen: 120, vars: true, white: true, plusplus: true, nonpropdel: true, sloppy: true */
|
||||
/*jslint indent: 2, maxlen: 120, vars: true, white: true, plusplus: true, nonpropdel: true, sloppy: true, proto: true */
|
||||
/*global require, SYS_GETLINE, SYS_LOG, jqconsole */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -90,6 +90,40 @@
|
|||
log(level, groupLevel + msg);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief try to prettify
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function prepareArgs (args) {
|
||||
var ShapedJson = require("internal").ShapedJson;
|
||||
var result = [];
|
||||
var i;
|
||||
|
||||
if (0 < args.length && typeof args[0] !== "string") {
|
||||
result.push("%s");
|
||||
}
|
||||
|
||||
for (i = 0; i < args.length; ++i) {
|
||||
var arg = args[i];
|
||||
|
||||
if (typeof arg === "object") {
|
||||
if (ShapedJson !== undefined && arg instanceof ShapedJson) {
|
||||
arg = inspect(arg, {prettyPrint: false});
|
||||
}
|
||||
else if (arg === null) {
|
||||
arg = "null";
|
||||
}
|
||||
else if (arg.__proto__ === Object.prototype || Array.isArray(arg)) {
|
||||
arg = inspect(arg, {prettyPrint: false});
|
||||
}
|
||||
}
|
||||
|
||||
result.push(arg);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -109,7 +143,7 @@
|
|||
var msg;
|
||||
|
||||
try {
|
||||
msg = sprintf.apply(sprintf, args);
|
||||
msg = sprintf.apply(sprintf, prepareArgs(args));
|
||||
}
|
||||
catch (err) {
|
||||
msg = err + ": " + args;
|
||||
|
@ -130,7 +164,7 @@
|
|||
var msg;
|
||||
|
||||
try {
|
||||
msg = sprintf.apply(sprintf, arguments);
|
||||
msg = sprintf.apply(sprintf, prepareArgs(arguments));
|
||||
}
|
||||
catch (err) {
|
||||
msg = err + ": " + arguments;
|
||||
|
@ -149,7 +183,7 @@
|
|||
var msg;
|
||||
|
||||
try {
|
||||
msg = sprintf.apply(sprintf, arguments);
|
||||
msg = sprintf.apply(sprintf, prepareArgs(arguments));
|
||||
}
|
||||
catch (err) {
|
||||
msg = err + ": " + arguments;
|
||||
|
@ -183,7 +217,7 @@
|
|||
var msg;
|
||||
|
||||
try {
|
||||
msg = sprintf.apply(sprintf, arguments);
|
||||
msg = sprintf.apply(sprintf, prepareArgs(arguments));
|
||||
}
|
||||
catch (err) {
|
||||
msg = err + ": " + arguments;
|
||||
|
@ -202,7 +236,7 @@
|
|||
var msg;
|
||||
|
||||
try {
|
||||
msg = sprintf.apply(sprintf, arguments);
|
||||
msg = sprintf.apply(sprintf, prepareArgs(arguments));
|
||||
}
|
||||
catch (err) {
|
||||
msg = err + ": " + arguments;
|
||||
|
@ -235,7 +269,7 @@
|
|||
var msg;
|
||||
|
||||
try {
|
||||
msg = sprintf.apply(sprintf, arguments);
|
||||
msg = sprintf.apply(sprintf, prepareArgs(arguments));
|
||||
}
|
||||
catch (err) {
|
||||
msg = err + ": " + arguments;
|
||||
|
@ -255,7 +289,7 @@
|
|||
var msg;
|
||||
|
||||
try {
|
||||
msg = sprintf.apply(sprintf, arguments);
|
||||
msg = sprintf.apply(sprintf, prepareArgs(arguments));
|
||||
}
|
||||
catch (err) {
|
||||
msg = err + ": " + arguments;
|
||||
|
@ -285,7 +319,7 @@
|
|||
var msg;
|
||||
|
||||
try {
|
||||
msg = sprintf.apply(sprintf, arguments);
|
||||
msg = sprintf.apply(sprintf, prepareArgs(arguments));
|
||||
}
|
||||
catch (err) {
|
||||
msg = err + ": " + arguments;
|
||||
|
@ -304,7 +338,7 @@
|
|||
var msg;
|
||||
|
||||
try {
|
||||
msg = sprintf.apply(sprintf, arguments);
|
||||
msg = sprintf.apply(sprintf, prepareArgs(arguments));
|
||||
}
|
||||
catch (err) {
|
||||
msg = err + ": " + arguments;
|
||||
|
@ -371,7 +405,7 @@
|
|||
exports.trace = function () {
|
||||
var err = new Error();
|
||||
err.name = 'trace';
|
||||
err.message = sprintf.apply(sprintf, arguments);
|
||||
err.message = sprintf.apply(sprintf, prepareArgs(arguments));
|
||||
Error.captureStackTrace(err, exports.trace);
|
||||
logGroup("info", err.stack);
|
||||
};
|
||||
|
@ -386,7 +420,7 @@
|
|||
var msg;
|
||||
|
||||
try {
|
||||
msg = sprintf.apply(sprintf, arguments);
|
||||
msg = sprintf.apply(sprintf, prepareArgs(arguments));
|
||||
}
|
||||
catch (err) {
|
||||
msg = err + ": " + arguments;
|
||||
|
@ -405,7 +439,7 @@
|
|||
var msg;
|
||||
|
||||
try {
|
||||
msg = sprintf.apply(sprintf, arguments);
|
||||
msg = sprintf.apply(sprintf, prepareArgs(arguments));
|
||||
}
|
||||
catch (err) {
|
||||
msg = err + ": " + arguments;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*jslint indent: 2, nomen: true, maxlen: 120, vars: true, white: true, plusplus: true, nonpropdel: true, proto: true */
|
||||
/*jslint sloppy: true, regexp: true */
|
||||
/*global require, module, Module, ArangoError, SleepAndRequeue,
|
||||
CONFIGURE_ENDPOINT, REMOVE_ENDPOINT, LIST_ENDPOINTS,
|
||||
CONFIGURE_ENDPOINT, REMOVE_ENDPOINT, LIST_ENDPOINTS, STARTUP_PATH,
|
||||
SYS_BASE64DECODE, SYS_BASE64ENCODE, SYS_DEBUG_SEGFAULT,
|
||||
SYS_DEBUG_CAN_USE_FAILAT, SYS_DEBUG_SET_FAILAT, SYS_DEBUG_REMOVE_FAILAT, SYS_DEBUG_CLEAR_FAILAT,
|
||||
SYS_DOWNLOAD, SYS_EXECUTE, SYS_GET_CURRENT_REQUEST, SYS_GET_CURRENT_RESPONSE,
|
||||
|
@ -258,6 +258,21 @@
|
|||
delete REQUEST_TIME_DISTRIBUTION;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief startupPath
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
exports.startupPath = "";
|
||||
|
||||
if (typeof STARTUP_PATH !== "undefined") {
|
||||
exports.startupPath = STARTUP_PATH;
|
||||
delete STARTUP_PATH;
|
||||
}
|
||||
|
||||
if (exports.startupPath === "") {
|
||||
exports.startupPath = ".";
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -1427,14 +1442,18 @@
|
|||
limitString: false,
|
||||
names: [],
|
||||
output: "",
|
||||
path: "~",
|
||||
prettyPrint: true,
|
||||
path: "~",
|
||||
seen: [],
|
||||
showFunction: true,
|
||||
useColor: false,
|
||||
useToString: false
|
||||
};
|
||||
|
||||
if (options && options.hasOwnProperty("prettyPrint")) {
|
||||
context.prettyPrint = options.prettyPrint;
|
||||
}
|
||||
|
||||
printRecursive(object, context);
|
||||
|
||||
return context.output;
|
||||
|
|
|
@ -106,7 +106,6 @@ function require (path) {
|
|||
|
||||
if (typeof STARTUP_PATH !== "undefined") {
|
||||
startupPath = STARTUP_PATH;
|
||||
delete STARTUP_PATH;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
../mkdirp/bin/cmd.js
|
|
@ -1 +0,0 @@
|
|||
../ncp/bin/ncp
|
|
@ -1 +0,0 @@
|
|||
../rimraf/bin.js
|
|
@ -5,7 +5,8 @@
|
|||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2004-2012 triAGENS GmbH, Cologne, Germany
|
||||
/// Copyright 2014 ArangoDB GmbH, Cologne, Germany
|
||||
/// Copyright 2004-2014 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.
|
||||
|
@ -19,9 +20,10 @@
|
|||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Dr. Frank Celler
|
||||
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
|
||||
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -150,7 +152,7 @@ function PrintEntries (entries, amount) {
|
|||
|
||||
if (amount > 0) {
|
||||
start = 0;
|
||||
end = amount;
|
||||
end = amount;
|
||||
if (end > entries.length) {
|
||||
end = entries.length;
|
||||
}
|
||||
|
@ -238,7 +240,7 @@ function CheckDatafile (collection, type, datafile, issues, details) {
|
|||
printf(" isSealed: %s\n", scan.isSealed ? "yes" : "no");
|
||||
|
||||
// set default value to unknown
|
||||
var statusMessage = "UNKNOWN (" + scan.status + ")";
|
||||
var statusMessage = "UNKNOWN (" + scan.status + ")";
|
||||
var color = internal.COLORS.COLOR_YELLOW;
|
||||
|
||||
switch (scan.status) {
|
||||
|
@ -276,13 +278,13 @@ function CheckDatafile (collection, type, datafile, issues, details) {
|
|||
printf(internal.COLORS.COLOR_RESET);
|
||||
|
||||
if (scan.status !== 1) {
|
||||
issues.push({
|
||||
collection: collection.name(),
|
||||
path: datafile,
|
||||
type: type,
|
||||
status: scan.status,
|
||||
message: statusMessage,
|
||||
color: color
|
||||
issues.push({
|
||||
collection: collection.name(),
|
||||
path: datafile,
|
||||
type: type,
|
||||
status: scan.status,
|
||||
message: statusMessage,
|
||||
color: color
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -291,12 +293,12 @@ function CheckDatafile (collection, type, datafile, issues, details) {
|
|||
color = internal.COLORS.COLOR_YELLOW;
|
||||
|
||||
issues.push({
|
||||
collection: collection.name(),
|
||||
path: datafile,
|
||||
type: type,
|
||||
status: scan.status,
|
||||
collection: collection.name(),
|
||||
path: datafile,
|
||||
type: type,
|
||||
status: scan.status,
|
||||
message: statusMessage,
|
||||
color: color
|
||||
color: color
|
||||
});
|
||||
|
||||
printf(color);
|
||||
|
@ -312,12 +314,12 @@ function CheckDatafile (collection, type, datafile, issues, details) {
|
|||
color = internal.COLORS.COLOR_YELLOW;
|
||||
|
||||
issues.push({
|
||||
collection: collection.name(),
|
||||
path: datafile,
|
||||
type: type,
|
||||
status: scan.status,
|
||||
collection: collection.name(),
|
||||
path: datafile,
|
||||
type: type,
|
||||
status: scan.status,
|
||||
message: statusMessage,
|
||||
color: color
|
||||
color: color
|
||||
});
|
||||
|
||||
printf(color);
|
||||
|
@ -333,10 +335,10 @@ function CheckDatafile (collection, type, datafile, issues, details) {
|
|||
color = internal.COLORS.COLOR_YELLOW;
|
||||
|
||||
issues.push({
|
||||
collection: collection.name(),
|
||||
path: datafile,
|
||||
type: type,
|
||||
status: scan.status,
|
||||
collection: collection.name(),
|
||||
path: datafile,
|
||||
type: type,
|
||||
status: scan.status,
|
||||
message: statusMessage,
|
||||
color: color
|
||||
});
|
||||
|
@ -347,17 +349,17 @@ function CheckDatafile (collection, type, datafile, issues, details) {
|
|||
RemoveDatafile(collection, type, datafile);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (type !== "journal" && scan.entries.length === 3 && scan.entries[2].type === 0) {
|
||||
// got the two initial header markers but nothing else...
|
||||
statusMessage = "datafile is empty but not sealed";
|
||||
color = internal.COLORS.COLOR_YELLOW;
|
||||
|
||||
issues.push({
|
||||
collection: collection.name(),
|
||||
path: datafile,
|
||||
type: type,
|
||||
status: scan.status,
|
||||
collection: collection.name(),
|
||||
path: datafile,
|
||||
type: type,
|
||||
status: scan.status,
|
||||
message: statusMessage,
|
||||
color: color
|
||||
});
|
||||
|
@ -368,7 +370,7 @@ function CheckDatafile (collection, type, datafile, issues, details) {
|
|||
RemoveDatafile(collection, type, datafile);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (details) {
|
||||
// print details
|
||||
printf("Entries\n");
|
||||
|
@ -426,7 +428,7 @@ function CheckCollection (collection, issues, details) {
|
|||
function main (argv) {
|
||||
var databases = internal.db._listDatabases();
|
||||
var i;
|
||||
|
||||
|
||||
var collectionSorter = function (l, r) {
|
||||
var lName = l.name().toLowerCase();
|
||||
var rName = r.name().toLowerCase();
|
||||
|
@ -437,7 +439,7 @@ function main (argv) {
|
|||
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
||||
printf("%s\n", " ___ _ __ _ _ ___ ___ ___ ");
|
||||
printf("%s\n", " / \\__ _| |_ __ _ / _(_) | ___ / \\/ __\\ / _ \\");
|
||||
printf("%s\n", " / /\\ / _` | __/ _` | |_| | |/ _ \\ / /\\ /__\\// / /_\\/");
|
||||
|
@ -449,20 +451,20 @@ function main (argv) {
|
|||
printf("No databases available. Exiting\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
databases.sort();
|
||||
printf("Available databases:\n");
|
||||
|
||||
for (i = 0; i < databases.length; ++i) {
|
||||
printf(" %d: %s\n", i, databases[i]);
|
||||
}
|
||||
|
||||
|
||||
var line;
|
||||
|
||||
|
||||
printf("Database to check: ");
|
||||
while (true) {
|
||||
line = console.getline();
|
||||
|
||||
|
||||
if (line == "") {
|
||||
printf("Exiting. Please wait.\n");
|
||||
return;
|
||||
|
@ -504,7 +506,7 @@ function main (argv) {
|
|||
|
||||
printf("Collection to check: ");
|
||||
var a = [];
|
||||
|
||||
|
||||
while (true) {
|
||||
line = console.getline();
|
||||
|
||||
|
@ -532,7 +534,7 @@ function main (argv) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
printf("\n");
|
||||
printf("Prints details (Y/N)? ");
|
||||
|
||||
|
@ -567,7 +569,7 @@ function main (argv) {
|
|||
CheckCollection(collection, issues, details);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (issues.length > 0) {
|
||||
// report issues
|
||||
printf("\n%d issue(s) found:\n------------------------------------------\n", issues.length);
|
||||
|
@ -597,5 +599,5 @@ function main (argv) {
|
|||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @}\\)"
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
/*jslint indent: 2, nomen: true, maxlen: 120, sloppy: true, vars: true, white: true, plusplus: true */
|
||||
/*global require */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief autoload modules
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014 ArangoDB 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 ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Dr. Frank Celler
|
||||
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- autoload modules
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief autoload modules
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
(function () {
|
||||
return {
|
||||
startup: function () {
|
||||
var internal = require("internal");
|
||||
var db = internal.db;
|
||||
|
||||
db._useDatabase("_system");
|
||||
|
||||
var databases = db._listDatabases();
|
||||
var i;
|
||||
|
||||
try {
|
||||
for (i = 0; i < databases.length; ++i) {
|
||||
db._useDatabase(databases[i]);
|
||||
|
||||
internal.autoloadModules();
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
db._useDatabase("_system");
|
||||
throw err;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}());
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
|
@ -0,0 +1,59 @@
|
|||
/*jslint indent: 2, nomen: true, maxlen: 120, sloppy: true, vars: true, white: true, plusplus: true */
|
||||
/*global require, UPGRADE_ARGS: true */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief initialise a new database
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014 ArangoDB 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 ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Dr. Frank Celler
|
||||
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- initialise a new database
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief initialise a new database
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
(function () {
|
||||
var internal = require("internal");
|
||||
|
||||
UPGRADE_ARGS = {
|
||||
isCluster: true,
|
||||
isCoordinator: true,
|
||||
isRelaunch: false
|
||||
};
|
||||
|
||||
// run the local upgrade-database script
|
||||
return internal.loadStartup("server/bootstrap/local-database.js");
|
||||
}());
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
|
@ -0,0 +1,67 @@
|
|||
/*jslint indent: 2, nomen: true, maxlen: 120, sloppy: true, vars: true, white: true, plusplus: true */
|
||||
/*global require, ArangoServerState */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief initialise a new database
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014 ArangoDB 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 ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Dr. Frank Celler
|
||||
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- initialise a new database
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief initialise a new database
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
(function () {
|
||||
return function () {
|
||||
var internal = require("internal");
|
||||
var console = require("console");
|
||||
|
||||
// statistics can be turned off
|
||||
if (internal.enableStatistics) {
|
||||
require("org/arangodb/statistics").startup();
|
||||
}
|
||||
|
||||
// load all foxxes
|
||||
internal.loadStartup("server/bootstrap/foxxes.js").foxxes();
|
||||
|
||||
// autoload all modules and reload routing information in all threads
|
||||
internal.executeGlobalContextFunction("bootstrapCoordinator");
|
||||
|
||||
console.info("bootstraped coordinator %s", ArangoServerState.id());
|
||||
return true;
|
||||
};
|
||||
}());
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
|
@ -0,0 +1,72 @@
|
|||
/*jslint indent: 2, nomen: true, maxlen: 120, sloppy: true, vars: true, white: true, plusplus: true, nonpropdel: true */
|
||||
/*global require, UPGRADE_ARGS: true, UPGRADE_STARTED: true, ArangoServerState */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief initialise a new database
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014 ArangoDB 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 ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Dr. Frank Celler
|
||||
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- initialise a new database
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief initialise a new database
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
(function () {
|
||||
return function () {
|
||||
var internal = require("internal");
|
||||
var console = require("console");
|
||||
|
||||
// run the local upgrade-database script (UPGRADE_ARGS has been set)
|
||||
var result = internal.loadStartup("server/upgrade-database.js");
|
||||
|
||||
result = UPGRADE_STARTED && result;
|
||||
delete UPGRADE_STARTED;
|
||||
delete UPGRADE_ARGS;
|
||||
|
||||
if (! result) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// statistics can be turned off
|
||||
if (internal.enableStatistics) {
|
||||
require("org/arangodb/statistics").startup();
|
||||
}
|
||||
|
||||
console.info("bootstraped DB server %s", ArangoServerState.id());
|
||||
return true;
|
||||
};
|
||||
}());
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
|
@ -0,0 +1,76 @@
|
|||
/*jslint indent: 2, nomen: true, maxlen: 120, sloppy: true, vars: true, white: true, plusplus: true */
|
||||
/*global require */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief initialise foxxes for a database
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014 ArangoDB 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 ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Dr. Frank Celler
|
||||
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- initialise foxxes
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief initialise foxxes
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
(function () {
|
||||
var internal = require("internal");
|
||||
var db = internal.db;
|
||||
|
||||
return {
|
||||
foxx: function () {
|
||||
require("org/arangodb/foxx/manager").initializeFoxx();
|
||||
},
|
||||
|
||||
foxxes: function () {
|
||||
try {
|
||||
db._useDatabase("_system");
|
||||
|
||||
var databases = db._listDatabases();
|
||||
var i;
|
||||
|
||||
for (i = 0; i < databases.length; ++i) {
|
||||
db._useDatabase(databases[i]);
|
||||
|
||||
require("org/arangodb/foxx/manager").initializeFoxx();
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
db._useDatabase("_system");
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
};
|
||||
}());
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
|
@ -0,0 +1,69 @@
|
|||
/*jslint indent: 2, nomen: true, maxlen: 120, sloppy: true, vars: true, white: true, plusplus: true, nonpropdel: true */
|
||||
/*global require, UPGRADE_STARTED: true, UPGRADE_ARGS: true */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief initialise a new database
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014 ArangoDB 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 ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Dr. Frank Celler
|
||||
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- initialise a new database
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief initialise a new database
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
(function () {
|
||||
var internal = require("internal");
|
||||
var console = require("console");
|
||||
var db = internal.db;
|
||||
|
||||
// run the upgrade-database script
|
||||
var result = internal.loadStartup("server/upgrade-database.js");
|
||||
|
||||
result = UPGRADE_STARTED && result;
|
||||
delete UPGRADE_STARTED;
|
||||
delete UPGRADE_ARGS;
|
||||
|
||||
// set-up foxx routes for this database
|
||||
if (result) {
|
||||
internal.loadStartup("server/bootstrap/foxxes.js").foxx();
|
||||
}
|
||||
else {
|
||||
console.error("cannot initialise database '%s', upgrade script failed", db._name());
|
||||
}
|
||||
|
||||
return result;
|
||||
}());
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
|
@ -4,7 +4,8 @@
|
|||
AHUACATL_RUN, AHUACATL_PARSE, AHUACATL_EXPLAIN, WAL_FLUSH, WAL_PROPERTIES,
|
||||
REPLICATION_LOGGER_STATE, REPLICATION_LOGGER_CONFIGURE, REPLICATION_SERVER_ID,
|
||||
REPLICATION_APPLIER_CONFIGURE, REPLICATION_APPLIER_START, REPLICATION_APPLIER_SHUTDOWN,
|
||||
REPLICATION_APPLIER_FORGET, REPLICATION_APPLIER_STATE, REPLICATION_SYNCHRONISE */
|
||||
REPLICATION_APPLIER_FORGET, REPLICATION_APPLIER_STATE, REPLICATION_SYNCHRONISE,
|
||||
ENABLE_STATISTICS */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief module "internal"
|
||||
|
@ -39,29 +40,57 @@
|
|||
|
||||
(function () {
|
||||
var internal = require("internal");
|
||||
var fs = require("fs");
|
||||
var console = require("console");
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private variables
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief hide global variables
|
||||
/// @brief db
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.db = db;
|
||||
delete db;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief ArangoCollection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.ArangoCollection = ArangoCollection;
|
||||
delete ArangoCollection;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief ArangoDatabase
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.ArangoDatabase = ArangoDatabase;
|
||||
delete ArangoDatabase;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief ArangoCursor
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.ArangoCursor = ArangoCursor;
|
||||
delete ArangoCursor;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief ShapedJson
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.ShapedJson = ShapedJson;
|
||||
delete ShapedJson;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief enableStatistics
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.enableStatistics = ENABLE_STATISTICS;
|
||||
delete ENABLE_STATISTICS;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private variables
|
||||
// --SECTION-- private functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -85,10 +114,6 @@
|
|||
internal.AQL_EXPLAIN = AHUACATL_EXPLAIN;
|
||||
delete AHUACATL_EXPLAIN;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief resets engine in development mode
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -125,70 +150,73 @@
|
|||
/// @brief defines an action
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
if (typeof SYS_DEFINE_ACTION === "undefined") {
|
||||
internal.defineAction = function() {
|
||||
console.error("SYS_DEFINE_ACTION not available");
|
||||
};
|
||||
if (typeof SYS_DEFINE_ACTION !== "undefined") {
|
||||
internal.defineAction = SYS_DEFINE_ACTION;
|
||||
delete SYS_DEFINE_ACTION;
|
||||
}
|
||||
|
||||
internal.actionLoaded = function() {
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief autoload modules from database
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// autoload specific modules
|
||||
internal.autoloadModules = function () {
|
||||
'use strict';
|
||||
|
||||
console.debug("autoloading actions");
|
||||
|
||||
var modules = internal.db._collection("_modules");
|
||||
|
||||
if (modules !== null) {
|
||||
modules = modules.byExample({ autoload: true }).toArray();
|
||||
|
||||
modules.forEach(function(module) {
|
||||
|
||||
// this module is only meant to be executed in one thread
|
||||
if (internal.threadNumber !== 0 && ! module.perThread) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.debug("autoloading module: %s", module.path);
|
||||
|
||||
try {
|
||||
|
||||
// require a module
|
||||
if (module.path !== undefined) {
|
||||
require(module.path);
|
||||
}
|
||||
|
||||
// execute a user function
|
||||
else if (module.func !== undefined) {
|
||||
/*jslint evil: true */
|
||||
var func = new Function(module.func);
|
||||
/*jslint evil: false */
|
||||
func();
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
console.error("error while loading startup module '%s': %s", module.name || module.path, String(err));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
console.debug("autoloading actions finished");
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief executes a string in all V8 contexts
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
if (typeof SYS_EXECUTE_GLOBAL_CONTEXT_FUNCTION === "undefined") {
|
||||
internal.executeGlobalContextFunction = function() {
|
||||
// nothing to do. we're probably in --console mode
|
||||
};
|
||||
}
|
||||
else {
|
||||
internal.defineAction = SYS_DEFINE_ACTION;
|
||||
delete SYS_DEFINE_ACTION;
|
||||
|
||||
// autoload specific actions
|
||||
internal.actionLoaded = function () {
|
||||
'use strict';
|
||||
|
||||
console.debug("autoloading actions");
|
||||
|
||||
var modules = internal.db._collection("_modules");
|
||||
|
||||
if (modules !== null) {
|
||||
modules = modules.byExample({ autoload: true }).toArray();
|
||||
|
||||
modules.forEach(function(module) {
|
||||
if (internal.threadNumber !== 0 && ! module.perThread) {
|
||||
// module is only meant to be executed in one thread
|
||||
return;
|
||||
}
|
||||
|
||||
console.debug("autoloading module: %s", module.path);
|
||||
|
||||
try {
|
||||
if (module.path !== undefined) {
|
||||
// require a module
|
||||
require(module.path);
|
||||
}
|
||||
else if (module.func !== undefined) {
|
||||
// execute a user function
|
||||
/*jslint evil: true */
|
||||
var func = new Function(module.func);
|
||||
/*jslint evil: false */
|
||||
func();
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
console.error("error while loading startup module '%s': %s", module.name || module.path, String(err));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
console.debug("autoloading actions finished");
|
||||
};
|
||||
internal.executeGlobalContextFunction = SYS_EXECUTE_GLOBAL_CONTEXT_FUNCTION;
|
||||
delete SYS_EXECUTE_GLOBAL_CONTEXT_FUNCTION;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief initialize foxx applications
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.initializeFoxx = function () {
|
||||
'use strict';
|
||||
|
||||
require("org/arangodb/foxx/manager").initializeFoxx();
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief reloads the AQL user functions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -205,20 +233,6 @@
|
|||
};
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief executes a string in all V8 contexts
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
if (typeof SYS_EXECUTE_GLOBAL_CONTEXT_FUNCTION === "undefined") {
|
||||
internal.executeGlobalContextFunction = function() {
|
||||
// nothing to do. we're probably in --console mode
|
||||
};
|
||||
}
|
||||
else {
|
||||
internal.executeGlobalContextFunction = SYS_EXECUTE_GLOBAL_CONTEXT_FUNCTION;
|
||||
delete SYS_EXECUTE_GLOBAL_CONTEXT_FUNCTION;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief getStateReplicationLogger
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -300,6 +314,14 @@
|
|||
delete REPLICATION_SERVER_ID;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief loadStartup
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
internal.loadStartup = function (path) {
|
||||
return internal.load(fs.join(internal.startupPath, path));
|
||||
};
|
||||
|
||||
}());
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
/*jslint indent: 2, nomen: true, maxlen: 120, sloppy: true, vars: true, white: true, plusplus: true */
|
||||
/*global require */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief initialize routing
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014 ArangoDB 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 ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Dr. Frank Celler
|
||||
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- initialize routing
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief initialize routing
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
(function () {
|
||||
return {
|
||||
startup: function () {
|
||||
var internal = require("internal");
|
||||
var db = internal.db;
|
||||
|
||||
db._useDatabase("_system");
|
||||
|
||||
var databases = db._listDatabases();
|
||||
var i;
|
||||
|
||||
try {
|
||||
for (i = 0; i < databases.length; ++i) {
|
||||
db._useDatabase(databases[i]);
|
||||
|
||||
require("org/arangodb/actions").reloadRouting();
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
db._useDatabase("_system");
|
||||
throw err;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}());
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
|
@ -2,16 +2,17 @@
|
|||
/*global require, exports, module, UPGRADE_ARGS */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief upgrade check
|
||||
/// @brief check if the version of database is a match
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
///
|
||||
/// Version check at the start of the server, will optionally perform necessary
|
||||
/// upgrades.
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014 triAGENS GmbH, Cologne, Germany
|
||||
/// Copyright 2014 ArangoDB GmbH, Cologne, Germany
|
||||
/// Copyright 2004-2014 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.
|
||||
|
@ -25,14 +26,14 @@
|
|||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Dr. Frank Celler
|
||||
/// @author Copyright 2014, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- upgrade check
|
||||
// --SECTION-- database version check
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
(function() {
|
||||
|
@ -45,5 +46,5 @@
|
|||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @}\\)"
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
|
@ -0,0 +1,71 @@
|
|||
/*jslint indent: 2, nomen: true, maxlen: 120, sloppy: true, vars: true, white: true, plusplus: true */
|
||||
/*global require, STARTUP_PATH, SYS_LOAD */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief basic initialisation
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014 ArangoDB GmbH, Cologne, Germany
|
||||
/// Copyright 2004-2014 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 ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Dr. Frank Celler
|
||||
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
|
||||
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
|
||||
/// @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- load files required during startup
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
(function () {
|
||||
var startupPath = STARTUP_PATH;
|
||||
var load = SYS_LOAD;
|
||||
|
||||
if (startupPath === "") {
|
||||
startupPath = ".";
|
||||
}
|
||||
|
||||
load(startupPath + "/common/bootstrap/modules.js");
|
||||
load(startupPath + "/common/bootstrap/module-internal.js");
|
||||
load(startupPath + "/common/bootstrap/module-fs.js");
|
||||
load(startupPath + "/common/bootstrap/module-console.js");
|
||||
load(startupPath + "/common/bootstrap/errors.js");
|
||||
load(startupPath + "/common/bootstrap/monkeypatches.js");
|
||||
load(startupPath + "/server/bootstrap/module-internal.js");
|
||||
}());
|
||||
|
||||
// global Buffer
|
||||
var Buffer = require("buffer").Buffer;
|
||||
|
||||
// extend prototypes for internally defined classes
|
||||
require("org/arangodb");
|
||||
|
||||
// load the actions from the actions directory
|
||||
require("org/arangodb/actions").startup();
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
|
@ -887,6 +887,33 @@ function flattenRouting (routes, path, urlParameters, depth, prefix) {
|
|||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief loads all actions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function startup () {
|
||||
if (internal.defineAction === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
var actionPath = fs.join(internal.startupPath, "actions");
|
||||
var actions = fs.list(actionPath);
|
||||
var i;
|
||||
|
||||
for (i = 0; i < actions.length; ++i) {
|
||||
var file = actions[i];
|
||||
|
||||
if (file.match(/api-.*\.js$/)) {
|
||||
var full = fs.join(actionPath, file);
|
||||
var content = fs.read(full);
|
||||
|
||||
content = "(function () {\n" + content + "\n}());";
|
||||
|
||||
internal.executeScript(content, undefined, full);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -986,16 +1013,11 @@ function routeRequest (req, res) {
|
|||
/// *options.url* is a prefix of the given url and no longer definition
|
||||
/// matches.
|
||||
///
|
||||
/// *options.prefix}
|
||||
/// `options.prefix`
|
||||
///
|
||||
/// If *false*, then only use the action for exact matches. The default is
|
||||
/// *true*.
|
||||
///
|
||||
/// `options.context`
|
||||
///
|
||||
/// The context to which this actions belongs. Possible values are "admin"
|
||||
/// and "user".
|
||||
///
|
||||
/// `options.callback(request, response)`
|
||||
///
|
||||
/// The request argument contains a description of the request. A request
|
||||
|
@ -1020,31 +1042,28 @@ function defineHttp (options) {
|
|||
'use strict';
|
||||
|
||||
var url = options.url;
|
||||
var context = options.context;
|
||||
var callback = options.callback;
|
||||
var prefix = true;
|
||||
|
||||
if (typeof context === "undefined") {
|
||||
context = "user";
|
||||
}
|
||||
|
||||
if (typeof callback !== "function") {
|
||||
console.error("callback for '%s' must be a function, got '%s'", url, (typeof callback));
|
||||
return;
|
||||
}
|
||||
|
||||
if (options.hasOwnProperty("prefix")) {
|
||||
prefix = options.prefix;
|
||||
}
|
||||
|
||||
var parameter = {
|
||||
prefix : prefix
|
||||
prefix: true,
|
||||
allowUseDatabase: false
|
||||
};
|
||||
|
||||
console.debug("defining action '%s' in context '%s'", url, context);
|
||||
if (options.hasOwnProperty("prefix")) {
|
||||
parameter.prefix = options.prefix;
|
||||
}
|
||||
|
||||
if (options.hasOwnProperty("allowUseDatabase")) {
|
||||
parameter.allowUseDatabase = options.allowUseDatabase;
|
||||
}
|
||||
|
||||
try {
|
||||
internal.defineAction(url, callback, parameter, [context]);
|
||||
internal.defineAction(url, callback, parameter);
|
||||
}
|
||||
catch (err) {
|
||||
console.error("action '%s' encountered error: %s", url, err);
|
||||
|
@ -1186,7 +1205,7 @@ function reloadRouting () {
|
|||
// .............................................................................
|
||||
|
||||
// work with a local variable first
|
||||
var routingCache = { };
|
||||
var routingCache = {};
|
||||
|
||||
routingCache.flat = {};
|
||||
routingCache.routes = {};
|
||||
|
@ -1813,6 +1832,7 @@ function resultException (req, res, err, headers, verbose) {
|
|||
|
||||
if (verbose || verbose === undefined) {
|
||||
msg = String(err.stack || err);
|
||||
verbose = true;
|
||||
}
|
||||
else {
|
||||
msg = String(err);
|
||||
|
@ -2099,6 +2119,9 @@ function stringifyRequestAddress (req) {
|
|||
// --SECTION-- MODULE EXPORTS
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// load all actions from the actions directory
|
||||
exports.startup = startup;
|
||||
|
||||
// public functions
|
||||
exports.routeRequest = routeRequest;
|
||||
exports.defineHttp = defineHttp;
|
||||
|
|
|
@ -963,27 +963,80 @@ var dispatcherDisabled = function () {
|
|||
/// @brief coordinatorId
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var coordinatorId= function () {
|
||||
var coordinatorId = function () {
|
||||
if (! isCoordinator()) {
|
||||
console.error("not a coordinator");
|
||||
}
|
||||
return ArangoServerState.id();
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief bootstrap db servers
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var bootstrapDbServers = function (isRelaunch) {
|
||||
ArangoClusterInfo.reloadDBServers();
|
||||
|
||||
var dbServers = ArangoClusterInfo.getDBServers();
|
||||
var ops = [];
|
||||
var i;
|
||||
|
||||
var options = {
|
||||
coordTransactionID: ArangoClusterInfo.uniqid(),
|
||||
timeout: 90
|
||||
};
|
||||
|
||||
for (i = 0; i < dbServers.length; ++i) {
|
||||
var server = dbServers[i];
|
||||
|
||||
var op = ArangoClusterComm.asyncRequest(
|
||||
"POST",
|
||||
"server:" + server,
|
||||
"_system",
|
||||
"/_admin/cluster/bootstrapDbServer",
|
||||
'{"isRelaunch": ' + (isRelaunch ? "true" : "false") + '}',
|
||||
{},
|
||||
options);
|
||||
|
||||
ops.push(op);
|
||||
}
|
||||
|
||||
var result = true;
|
||||
|
||||
for (i = 0; i < ops.length; ++i) {
|
||||
var r = ArangoClusterComm.wait(ops[i]);
|
||||
|
||||
if (r.status === "RECEIVED") {
|
||||
console.info("bootstraped DB server %s", dbServers[i]);
|
||||
}
|
||||
else if (r.status === "TIMEOUT") {
|
||||
console.error("cannot bootstrap DB server %s: operation timed out", dbServers[i]);
|
||||
result = false;
|
||||
}
|
||||
else {
|
||||
console.error("cannot bootstrap DB server %s: %s", dbServers[i], JSON.stringify(r));
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- MODULE EXPORTS
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
exports.coordinatorId = coordinatorId;
|
||||
exports.dispatcherDisabled = dispatcherDisabled;
|
||||
exports.handlePlanChange = handlePlanChange;
|
||||
exports.isCluster = isCluster;
|
||||
exports.isCoordinator = isCoordinator;
|
||||
exports.isCoordinatorRequest = isCoordinatorRequest;
|
||||
exports.role = role;
|
||||
exports.shardList = shardList;
|
||||
exports.status = status;
|
||||
exports.wait = wait;
|
||||
exports.bootstrapDbServers = bootstrapDbServers;
|
||||
exports.coordinatorId = coordinatorId;
|
||||
exports.dispatcherDisabled = dispatcherDisabled;
|
||||
exports.handlePlanChange = handlePlanChange;
|
||||
exports.isCluster = isCluster;
|
||||
exports.isCoordinator = isCoordinator;
|
||||
exports.isCoordinatorRequest = isCoordinatorRequest;
|
||||
exports.role = role;
|
||||
exports.shardList = shardList;
|
||||
exports.status = status;
|
||||
exports.wait = wait;
|
||||
|
||||
exports.Kickstarter = Kickstarter;
|
||||
exports.Planner = Planner;
|
||||
|
|
|
@ -56,6 +56,45 @@ var getAddrPort = require("org/arangodb/cluster/planner").getAddrPort;
|
|||
var getPort = require("org/arangodb/cluster/planner").getPort;
|
||||
var endpointToURL = require("org/arangodb/cluster/planner").endpointToURL;
|
||||
|
||||
function extractErrorMessage (result) {
|
||||
if (result === undefined) {
|
||||
return "unknown error";
|
||||
}
|
||||
|
||||
if (result.hasOwnProperty("body") && result.body !== undefined) {
|
||||
try {
|
||||
var e = JSON.parse(result.body);
|
||||
|
||||
if (e.hasOwnProperty("errorMessage")) {
|
||||
return e.errorMessage;
|
||||
}
|
||||
|
||||
if (e.hasOwnProperty("errorNum")) {
|
||||
return e.errorNum;
|
||||
}
|
||||
|
||||
if (result.body !== "") {
|
||||
return result.body;
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
if (result.body !== "") {
|
||||
return result.body;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result.hasOwnProperty("message")) {
|
||||
return result.message;
|
||||
}
|
||||
|
||||
if (result.hasOwnProperty("code")) {
|
||||
return String(result.code);
|
||||
}
|
||||
|
||||
return "unknown error";
|
||||
}
|
||||
|
||||
function makePath (path) {
|
||||
return fs.join.apply(null,path.split("/"));
|
||||
}
|
||||
|
@ -363,38 +402,71 @@ launchActions.startServers = function (dispatchers, cmd, isRelaunch) {
|
|||
"pids": pids, "endpoints": endpoints, "roles": roles};
|
||||
};
|
||||
|
||||
launchActions.createSystemColls = function (dispatchers, cmd, isRelaunch) {
|
||||
if (isRelaunch) {
|
||||
return {"error":false, "isCreateSystemColls":true};
|
||||
launchActions.bootstrapServers = function (dispatchers, cmd, isRelaunch,
|
||||
username, password) {
|
||||
var coordinators = cmd.coordinators;
|
||||
|
||||
if (username === undefined && password === undefined) {
|
||||
username = "root";
|
||||
password = "";
|
||||
}
|
||||
|
||||
// We wait another half second (we have already waited for all servers
|
||||
// until they responded!), just to be on the safe side:
|
||||
wait(0.5);
|
||||
// we need at least one coordinator
|
||||
if (0 === coordinators.length) {
|
||||
return {"error": true, "bootstrapServers": true};
|
||||
}
|
||||
|
||||
// autorization header for coordinator
|
||||
var hdrs = {
|
||||
Authorization: getAuthorizationHeader("root", "")
|
||||
// default username and passwd, this will work just after cluster creation
|
||||
Authorization: getAuthorizationHeader(username, password)
|
||||
};
|
||||
|
||||
console.info("Creating system collections...");
|
||||
var url = cmd.url + "/_admin/execute?returnAsJSON=true";
|
||||
var body = 'load=require("internal").load;\n'+
|
||||
'UPGRADE_ARGS=undefined;\n'+
|
||||
'return load('+JSON.stringify(
|
||||
fs.join(ArangoServerState.javaScriptPath(),
|
||||
makePath("server/version-check.js")))+
|
||||
');\n';
|
||||
var o = { method: "POST", timeout: 90, headers: hdrs };
|
||||
var r = download(url, body, o);
|
||||
if (r.code === 200) {
|
||||
r = JSON.parse(r.body);
|
||||
r.isCreateSystemColls = true;
|
||||
return r;
|
||||
// default options
|
||||
var options = {
|
||||
method: "POST",
|
||||
timeout: 90,
|
||||
headers: hdrs,
|
||||
returnBodyOnError: true
|
||||
};
|
||||
|
||||
// execute bootstrap command on first server
|
||||
var url = coordinators[0] + "/_admin/cluster/bootstrapDbServers";
|
||||
var body = '{"isRelaunch": ' + (isRelaunch ? "true" : "false") + '}';
|
||||
|
||||
var result = download(url, body, options);
|
||||
|
||||
if (result.code !== 200) {
|
||||
console.error("bootstrapping DB servers failed: %s", extractErrorMessage(result));
|
||||
return {"error": true, "bootstrapServers": true};
|
||||
}
|
||||
r.error = true;
|
||||
r.isCreateSystemColls = true;
|
||||
return r;
|
||||
|
||||
// execute cluster database upgrade
|
||||
url = coordinators[0] + "/_admin/cluster/upgradeClusterDatabase";
|
||||
|
||||
result = download(url, body, options);
|
||||
|
||||
if (result.code !== 200) {
|
||||
console.error("upgrading cluster database failed: %s", extractErrorMessage(result));
|
||||
return {"error": true, "bootstrapServers": true};
|
||||
}
|
||||
|
||||
// bootstrap coordinators
|
||||
var i;
|
||||
|
||||
for (i = 0; i < coordinators.length; ++i) {
|
||||
url = coordinators[i] + "/_admin/cluster/bootstrapCoordinator";
|
||||
|
||||
result = download(url, body, options);
|
||||
|
||||
if (result.code !== 200) {
|
||||
console.error("bootstrapping coordinator %s failed: %s",
|
||||
coordinators[i],
|
||||
extractErrorMessage(result));
|
||||
return {"error": true, "bootstrapServers": true};
|
||||
}
|
||||
}
|
||||
|
||||
return {"error": false, "bootstrapServers": true};
|
||||
};
|
||||
|
||||
shutdownActions.startAgent = function (dispatchers, cmd, run) {
|
||||
|
@ -720,38 +792,74 @@ upgradeActions.startServers = function (dispatchers, cmd, isRelaunch) {
|
|||
};
|
||||
|
||||
|
||||
// Upgrade for the version-check as in launch:
|
||||
// Upgrade for the upgrade-database as in launch:
|
||||
|
||||
upgradeActions.createSystemColls = function (dispatchers, cmd, isRelaunch,
|
||||
upgradeActions.bootstrapServers = function (dispatchers, cmd, isRelaunch,
|
||||
username, password) {
|
||||
var coordinators = cmd.coordinators;
|
||||
|
||||
// we need at least one coordinator
|
||||
if (0 === coordinators.length) {
|
||||
return {"error": true, "bootstrapServers": true};
|
||||
}
|
||||
|
||||
// We wait another half second (we have already waited for all servers
|
||||
// until they responded!), just to be on the safe side:
|
||||
wait(0.5);
|
||||
|
||||
// autorization header for coordinator
|
||||
var hdrs = {
|
||||
Authorization: getAuthorizationHeader(username, password)
|
||||
// default username and passwd, this will work just after cluster creation
|
||||
// for upgrade we document that this credentials have to work
|
||||
};
|
||||
|
||||
console.info("Running upgrade script on whole cluster...");
|
||||
var url = cmd.url + "/_admin/execute?returnAsJSON=true";
|
||||
var body = 'load=require("internal").load;\n'+
|
||||
'UPGRADE_ARGS=undefined;\n'+
|
||||
'return load('+JSON.stringify(
|
||||
fs.join(ArangoServerState.javaScriptPath(),
|
||||
makePath("server/version-check.js")))+
|
||||
');\n';
|
||||
var o = { method: "POST", timeout: 90, headers: hdrs };
|
||||
var r = download(url, body, o);
|
||||
if (r.code === 200) {
|
||||
r = JSON.parse(r.body);
|
||||
r.isCreateSystemColls = true;
|
||||
return r;
|
||||
// default options
|
||||
var options = {
|
||||
method: "POST",
|
||||
timeout: 90,
|
||||
headers: hdrs,
|
||||
returnBodyOnError: true
|
||||
};
|
||||
|
||||
// execute bootstrap command on first server
|
||||
var url = coordinators[0] + "/_admin/cluster/bootstrapDbServers";
|
||||
var body = '{"isRelaunch": false, "upgrade": true}';
|
||||
|
||||
var result = download(url, body, options);
|
||||
|
||||
if (result.code !== 200) {
|
||||
console.error("bootstrapping DB servers failed: %s", extractErrorMessage(result));
|
||||
return {"error": true, "bootstrapServers": true};
|
||||
}
|
||||
r.error = true;
|
||||
r.isCreateSystemColls = true;
|
||||
return r;
|
||||
|
||||
// execute cluster database upgrade
|
||||
console.info("Running upgrade script on whole cluster...");
|
||||
|
||||
url = coordinators[0] + "/_admin/cluster/upgradeClusterDatabase";
|
||||
|
||||
result = download(url, body, options);
|
||||
|
||||
if (result.code !== 200) {
|
||||
console.error("upgrading cluster database failed: %s", extractErrorMessage(result));
|
||||
return {"error": true, "bootstrapServers": true};
|
||||
}
|
||||
|
||||
// bootstrap coordinators
|
||||
var i;
|
||||
|
||||
for (i = 0; i < coordinators.length; ++i) {
|
||||
url = coordinators[i] + "/_admin/cluster/bootstrapCoordinator";
|
||||
|
||||
result = download(url, body, options);
|
||||
|
||||
if (result.code !== 200) {
|
||||
console.error("bootstrapping coordinator %s failed: %s",
|
||||
coordinators[i],
|
||||
extractErrorMessage(result));
|
||||
return {"error": true, "bootstrapServers": true};
|
||||
}
|
||||
}
|
||||
|
||||
return {"error": false, "bootstrapServers": true};
|
||||
};
|
||||
|
||||
|
||||
|
@ -906,7 +1014,7 @@ Kickstarter.prototype.launch = function () {
|
|||
/// @endDocuBlock
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Kickstarter.prototype.relaunch = function () {
|
||||
Kickstarter.prototype.relaunch = function (username, password) {
|
||||
var clusterPlan = this.clusterPlan;
|
||||
var myname = this.myname;
|
||||
var dispatchers = clusterPlan.dispatchers;
|
||||
|
@ -914,6 +1022,11 @@ Kickstarter.prototype.relaunch = function () {
|
|||
var results = [];
|
||||
var cmd;
|
||||
|
||||
if (username === undefined && password === undefined) {
|
||||
username = "root";
|
||||
password = "";
|
||||
}
|
||||
|
||||
var error = false;
|
||||
var i;
|
||||
var res;
|
||||
|
@ -921,7 +1034,8 @@ Kickstarter.prototype.relaunch = function () {
|
|||
cmd = cmds[i];
|
||||
if (cmd.dispatcher === undefined || cmd.dispatcher === myname) {
|
||||
if (launchActions.hasOwnProperty(cmd.action)) {
|
||||
res = launchActions[cmd.action](dispatchers, cmd, true);
|
||||
res = launchActions[cmd.action](dispatchers, cmd, true,
|
||||
username, password);
|
||||
results.push(res);
|
||||
if (res.error === true) {
|
||||
error = true;
|
||||
|
@ -938,7 +1052,9 @@ Kickstarter.prototype.relaunch = function () {
|
|||
"clusterPlan": {
|
||||
"dispatchers": dispatchers,
|
||||
"commands": [cmd] },
|
||||
"myname": cmd.dispatcher });
|
||||
"myname": cmd.dispatcher,
|
||||
"username": username,
|
||||
"password": password});
|
||||
var url = endpointToURL(ep) + "/_admin/clusterDispatch";
|
||||
var hdrs = {};
|
||||
if (dispatchers[cmd.dispatcher].username !== undefined &&
|
||||
|
@ -1218,7 +1334,7 @@ Kickstarter.prototype.isHealthy = function() {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @startDocuBlock JSF_Kickstarter_prototype_upgrade
|
||||
///
|
||||
/// `Kickstarter.upgrade()`
|
||||
/// `Kickstarter.upgrade(username, passwd)`
|
||||
///
|
||||
/// This performs an upgrade procedure on a cluster as described in
|
||||
/// the plan which was given to the constructor. To this end, other
|
||||
|
@ -1227,7 +1343,7 @@ Kickstarter.prototype.isHealthy = function() {
|
|||
/// upgrade is as follows: The agency is started first (exactly as
|
||||
/// in relaunch), no configuration is sent there (exactly as in the
|
||||
/// relaunch action), all servers are first started with the option
|
||||
/// "--upgrade" and then normally. In the end, the version-check.js
|
||||
/// "--upgrade" and then normally. In the end, the upgrade-database.js
|
||||
/// script is run on one of the coordinators, as in the launch action.
|
||||
///
|
||||
/// The result is an object that contains information about the started
|
||||
|
|
|
@ -637,11 +637,33 @@ Planner.prototype.makePlan = function() {
|
|||
"useSSLonDBservers": config.useSSLonDBservers,
|
||||
"useSSLonCoordinators": config.useSSLonCoordinators } );
|
||||
}
|
||||
var c = coordinators[0];
|
||||
var e = exchangePort(dispatchers[c.dispatcher].endpoint,c.port);
|
||||
e = exchangeProtocol(e, config.useSSLonCoordinators);
|
||||
tmp.push( { "action": "createSystemColls",
|
||||
"url": endpointToURL(e) });
|
||||
|
||||
var cc = [];
|
||||
var c;
|
||||
var e;
|
||||
|
||||
for (i = 0; i < coordinators.length; i++) {
|
||||
c = coordinators[i];
|
||||
e = exchangePort(dispatchers[c.dispatcher].endpoint, c.port);
|
||||
e = exchangeProtocol(e, config.useSSLonCoordinators);
|
||||
|
||||
cc.push(endpointToURL(e));
|
||||
}
|
||||
|
||||
var dd = [];
|
||||
|
||||
for (i = 0; i < DBservers.length; i++) {
|
||||
c = DBservers[i];
|
||||
e = exchangePort(dispatchers[c.dispatcher].endpoint, c.port);
|
||||
e = exchangeProtocol(e, config.useSSLonDBservers);
|
||||
|
||||
dd.push(endpointToURL(e));
|
||||
}
|
||||
|
||||
tmp.push( { "action": "bootstrapServers",
|
||||
"dbServers": dd,
|
||||
"coordinators": cc });
|
||||
|
||||
this.myname = "me";
|
||||
};
|
||||
|
||||
|
|
|
@ -61,6 +61,20 @@ var logger = {
|
|||
// --SECTION-- public constants
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief CURRENT_VERSION
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
exports.CURRENT_VERSION = (function() {
|
||||
var v = db._version().replace(/-[a-zA-Z0-9_\-]*$/g, '').split('.');
|
||||
|
||||
var major = parseFloat(v[0], 10) || 0;
|
||||
var minor = parseFloat(v[1], 10) || 0;
|
||||
var patch = parseFloat(v[2], 10) || 0;
|
||||
|
||||
return (((major * 100) + minor) * 100) + patch;
|
||||
}());
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief VERSION_MATCH
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -151,18 +165,10 @@ exports.databaseVersion = function () {
|
|||
}
|
||||
|
||||
// extract server version
|
||||
var currentServerVersion = db._version().match(/^(\d+\.\d+).*$/);
|
||||
|
||||
// server version is invalid for some reason
|
||||
if (! currentServerVersion) {
|
||||
logger.error("Unexpected ArangoDB server version: " + db._version());
|
||||
return { result: exports.NO_SERVER_VERSION };
|
||||
}
|
||||
|
||||
var currentVersion = parseFloat(currentServerVersion[1]);
|
||||
var currentVersion = exports.CURRENT_VERSION;
|
||||
|
||||
// version match!
|
||||
if (lastVersion === currentVersion) {
|
||||
if (Math.floor(lastVersion / 100) === Math.floor(currentVersion / 100)) {
|
||||
return {
|
||||
result: exports.VERSION_MATCH,
|
||||
serverVersion: currentVersion,
|
||||
|
|
|
@ -1036,6 +1036,11 @@ exports.scanAppDirectory = function () {
|
|||
|
||||
var aal = getStorage();
|
||||
|
||||
// only initialize global collections
|
||||
if (aal === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// remove all loaded apps first
|
||||
aal.removeByExample({ type: "app" });
|
||||
|
||||
|
@ -1726,7 +1731,7 @@ exports.initializeFoxx = function () {
|
|||
exports.scanAppDirectory();
|
||||
}
|
||||
catch (err) {
|
||||
console.error("cannot initialize Foxx application: %s", String(err));
|
||||
console.errorLines("cannot initialize Foxx application: %s", String(err.stack || err));
|
||||
}
|
||||
|
||||
var aal = getStorage();
|
||||
|
|
|
@ -85,37 +85,6 @@ function createStatisticsCollection (name) {
|
|||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief createCollections
|
||||
///
|
||||
/// This cannot be called during version check, because the collections are
|
||||
/// system wide and the version checks might not yet know, that it is running
|
||||
/// on a cluster coordinate.
|
||||
///
|
||||
/// TODO need to fix this
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function createStatisticsCollections () {
|
||||
'use strict';
|
||||
|
||||
if (initialized) {
|
||||
return true;
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
|
||||
var names = [ "_statisticsRaw", "_statistics", "_statistics15" ];
|
||||
var i;
|
||||
|
||||
for (i = 0; i < names.length; ++i) {
|
||||
if (! createStatisticsCollection(names[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief collectGarbage
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -483,6 +452,35 @@ exports.STATISTICS_HISTORY_INTERVAL = 15 * 60;
|
|||
// --SECTION-- public functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief createCollections
|
||||
///
|
||||
/// This cannot be called during version check, because the collections are
|
||||
/// system wide and the version checks might not yet know, that it is running
|
||||
/// on a cluster coordinate.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
exports.createStatisticsCollections = function () {
|
||||
'use strict';
|
||||
|
||||
if (initialized) {
|
||||
return true;
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
|
||||
var names = [ "_statisticsRaw", "_statistics", "_statistics15" ];
|
||||
var i;
|
||||
|
||||
for (i = 0; i < names.length; ++i) {
|
||||
if (! createStatisticsCollection(names[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief creates a statistics entry
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -490,7 +488,7 @@ exports.STATISTICS_HISTORY_INTERVAL = 15 * 60;
|
|||
exports.historian = function () {
|
||||
"use strict";
|
||||
|
||||
if (! createStatisticsCollections()) {
|
||||
if (! exports.createStatisticsCollections()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -551,7 +549,7 @@ exports.historian = function () {
|
|||
exports.historianAverage = function () {
|
||||
"use strict";
|
||||
|
||||
if (! createStatisticsCollections()) {
|
||||
if (! exports.createStatisticsCollections()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -605,7 +603,7 @@ exports.historianAverage = function () {
|
|||
exports.garbageCollector = function () {
|
||||
'use strict';
|
||||
|
||||
if (! createStatisticsCollections()) {
|
||||
if (! exports.createStatisticsCollections()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -616,6 +614,45 @@ exports.garbageCollector = function () {
|
|||
collectGarbage("_statistics15", time - 30 * 24 * 60 * 60);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief initialise the module
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
exports.startup = function () {
|
||||
'use strict';
|
||||
|
||||
if (typeof internal.registerTask !== "function") {
|
||||
return;
|
||||
}
|
||||
|
||||
var interval = exports.STATISTICS_INTERVAL;
|
||||
var interval15 = exports.STATISTICS_HISTORY_INTERVAL;
|
||||
|
||||
internal.registerTask({
|
||||
id: "statistics-collector",
|
||||
name: "statistics-collector",
|
||||
offset: interval / 10,
|
||||
period: interval,
|
||||
command: "require('org/arangodb/statistics').historian();"
|
||||
});
|
||||
|
||||
internal.registerTask({
|
||||
id: "statistics-average-collector",
|
||||
name: "statistics-average-collector",
|
||||
offset: 2 * interval,
|
||||
period: interval15,
|
||||
command: "require('org/arangodb/statistics').historianAverage();"
|
||||
});
|
||||
|
||||
internal.registerTask({
|
||||
id: "statistics-gc",
|
||||
name: "statistics-gc",
|
||||
offset: Math.random() * interval15 / 2,
|
||||
period: interval15 / 2,
|
||||
command: "require('org/arangodb/statistics').garbageCollector();"
|
||||
});
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
|
@ -1,14 +1,15 @@
|
|||
/*jslint indent: 2, nomen: true, maxlen: 120, sloppy: true, vars: true, white: true, plusplus: true */
|
||||
/*global require, ENABLE_STATISTICS */
|
||||
/*global require, ArangoAgency */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief JavaScript server functions
|
||||
/// @brief server initialisation
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2004-2013 triAGENS GmbH, Cologne, Germany
|
||||
/// Copyright 2014 ArangoDB GmbH, Cologne, Germany
|
||||
/// Copyright 2011-2014 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.
|
||||
|
@ -22,68 +23,50 @@
|
|||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Dr. Frank Celler
|
||||
/// @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany
|
||||
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
|
||||
/// @author Copyright 2011-2014, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// extend prototypes for internally defined classes
|
||||
require("org/arangodb");
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- global functions
|
||||
// --SECTION-- server initialisation
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief global 'Buffer'
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var Buffer = require("buffer").Buffer;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- statistics
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief installs a period statistics handler
|
||||
/// @brief server start
|
||||
///
|
||||
/// Note that all the initialisation has been done. E. g. "upgrade-database.js"
|
||||
/// has been executed.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
(function () {
|
||||
if (! ENABLE_STATISTICS) {
|
||||
// statistics are turned off
|
||||
return;
|
||||
}
|
||||
|
||||
var internal = require("internal");
|
||||
var interval = require('org/arangodb/statistics').STATISTICS_INTERVAL;
|
||||
var interval15 = require('org/arangodb/statistics').STATISTICS_HISTORY_INTERVAL;
|
||||
var db = internal.db;
|
||||
|
||||
if (internal.threadNumber === 0 && typeof internal.registerTask === "function") {
|
||||
internal.registerTask({
|
||||
id: "statistics-collector",
|
||||
name: "statistics-collector",
|
||||
offset: interval / 10,
|
||||
period: interval,
|
||||
command: "require('org/arangodb/statistics').historian();"
|
||||
});
|
||||
|
||||
internal.registerTask({
|
||||
id: "statistics-average-collector",
|
||||
name: "statistics-average-collector",
|
||||
offset: 2 * interval,
|
||||
period: interval15,
|
||||
command: "require('org/arangodb/statistics').historianAverage();"
|
||||
});
|
||||
|
||||
internal.registerTask({
|
||||
id: "statistics-gc",
|
||||
name: "statistics-gc",
|
||||
offset: Math.random() * interval15 / 2,
|
||||
period: interval15 / 2,
|
||||
command: "require('org/arangodb/statistics').garbageCollector();"
|
||||
});
|
||||
// one the cluster the kickstarter will call boostrap-role.js
|
||||
if (ArangoAgency.prefix() !== "") {
|
||||
return true;
|
||||
}
|
||||
|
||||
// statistics can be turned off
|
||||
if (internal.enableStatistics && internal.threadNumber === 0) {
|
||||
require("org/arangodb/statistics").startup();
|
||||
}
|
||||
|
||||
// load all foxxes
|
||||
if (internal.threadNumber === 0) {
|
||||
internal.loadStartup("server/bootstrap/foxxes.js").foxxes();
|
||||
}
|
||||
|
||||
// autoload all modules
|
||||
internal.loadStartup("server/bootstrap/autoload.js").startup();
|
||||
|
||||
// reload routing information
|
||||
internal.loadStartup("server/bootstrap/routing.js").startup();
|
||||
|
||||
return true;
|
||||
}());
|
||||
|
||||
|
||||
|
@ -93,5 +76,5 @@ var Buffer = require("buffer").Buffer;
|
|||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @\\}\\)"
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
||||
|
|
|
@ -540,7 +540,7 @@ function ahuacatlQueryGeneralPathsTestSuite() {
|
|||
actual = getQueryResults(
|
||||
"FOR e IN GRAPH_PATHS('bla3') "
|
||||
+ "LET length = LENGTH(e.edges) "
|
||||
+ "SORT e.source._key, e.destination._key "
|
||||
+ "SORT e.source._key, e.destination._key, length "
|
||||
+ "RETURN {src: e.source._key, dest: e.destination._key, edges: e.edges, length: length}"
|
||||
);
|
||||
assertEqual(actual.length, 12);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue