1
0
Fork 0

Merge branch 'devel' of github.com:arangodb/arangodb into devel

This commit is contained in:
Willi Goesgens 2015-04-27 16:49:30 +02:00
commit 1ce4432321
27 changed files with 415 additions and 86 deletions

View File

@ -305,6 +305,8 @@ v2.6.0 (XXXX-XX-XX)
v2.5.3 (XXXX-XX-XX) v2.5.3 (XXXX-XX-XX)
------------------- -------------------
* issue #1318: Inconsistent db._create() syntax
* issue #1315: queries to a collection fail with an empty response if the * issue #1315: queries to a collection fail with an empty response if the
collection contains specific JSON data collection contains specific JSON data

View File

@ -4,7 +4,7 @@ Welcome to the ArangoDB documentation!
The documentation introduces ArangoDB for you as an user, developer and administrator and describes all of its functions in detail. The documentation introduces ArangoDB for you as an user, developer and administrator and describes all of its functions in detail.
ArangoDB is a multi-purpose, open-source database with flexible data models for documents, graphs, and key-values. Build high performance applications using a convenient SQL-like query language or JavaScript extensions. Use ACID transactions if you require them. Scale horizontally and vertically with a few mouse clicks. ArangoDB is a multi-model, open-source database with flexible data models for documents, graphs, and key-values. Build high performance applications using a convenient SQL-like query language or JavaScript extensions. Use ACID transactions if you require them. Scale horizontally and vertically with a few mouse clicks.
Key features include: Key features include:
@ -34,4 +34,3 @@ If you have any questions don't hesitate to ask on:
- [stackoverflow](http://stackoverflow.com/questions/tagged/arangodb) - [stackoverflow](http://stackoverflow.com/questions/tagged/arangodb)
We will respond as soon as possible. We will respond as soon as possible.

View File

@ -62,6 +62,8 @@ namespace triagens {
class AqlItemBlock { class AqlItemBlock {
friend class AqlItemBlockManager;
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- constructors / destructors // --SECTION-- constructors / destructors
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View File

@ -0,0 +1,97 @@
////////////////////////////////////////////////////////////////////////////////
/// @brief Aql, item block manager
///
/// @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 Jan Steemann
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
/// @author Copyright 2012-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#include "AqlItemBlockManager.h"
#include "Aql/AqlItemBlock.h"
using namespace triagens::aql;
// -----------------------------------------------------------------------------
// --SECTION-- constructors / destructors
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief create the manager
////////////////////////////////////////////////////////////////////////////////
AqlItemBlockManager::AqlItemBlockManager ()
: _last(nullptr) {
}
////////////////////////////////////////////////////////////////////////////////
/// @brief destroy the manager
////////////////////////////////////////////////////////////////////////////////
AqlItemBlockManager::~AqlItemBlockManager () {
delete _last;
}
// -----------------------------------------------------------------------------
// --SECTION-- public methods
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief request a block with the specified size
////////////////////////////////////////////////////////////////////////////////
AqlItemBlock* AqlItemBlockManager::requestBlock (size_t nrItems,
RegisterId nrRegs) {
if (_last != nullptr &&
_last->size() == nrItems &&
_last->getNrRegs() == nrRegs) {
auto block = _last;
_last = nullptr;
return block;
}
return new AqlItemBlock(nrItems, nrRegs);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return a block to the manager
////////////////////////////////////////////////////////////////////////////////
void AqlItemBlockManager::returnBlock (AqlItemBlock*& block) {
TRI_ASSERT(block != nullptr);
block->destroy();
delete _last;
_last = block;
block = nullptr;
}
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------
// Local Variables:
// mode: outline-minor
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
// End:

View File

@ -0,0 +1,111 @@
////////////////////////////////////////////////////////////////////////////////
/// @brief Aql, item block manager
///
/// @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 Jan Steemann
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
/// @author Copyright 2012-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#ifndef ARANGODB_AQL_ITEM_BLOCK_MANAGER_H
#define ARANGODB_AQL_ITEM_BLOCK_MANAGER_H 1
#include "Basics/Common.h"
#include "Aql/types.h"
namespace triagens {
namespace aql {
class AqlItemBlock;
// -----------------------------------------------------------------------------
// --SECTION-- class AqlItemBlockManager
// -----------------------------------------------------------------------------
class AqlItemBlockManager {
// -----------------------------------------------------------------------------
// --SECTION-- constructors / destructors
// -----------------------------------------------------------------------------
public:
////////////////////////////////////////////////////////////////////////////////
/// @brief create the manager
////////////////////////////////////////////////////////////////////////////////
AqlItemBlockManager ();
////////////////////////////////////////////////////////////////////////////////
/// @brief destroy the manager
////////////////////////////////////////////////////////////////////////////////
~AqlItemBlockManager ();
// -----------------------------------------------------------------------------
// --SECTION-- public methods
// -----------------------------------------------------------------------------
public:
////////////////////////////////////////////////////////////////////////////////
/// @brief request a block with the specified size
////////////////////////////////////////////////////////////////////////////////
AqlItemBlock* requestBlock (size_t,
RegisterId);
////////////////////////////////////////////////////////////////////////////////
/// @brief return a block to the manager
////////////////////////////////////////////////////////////////////////////////
void returnBlock (AqlItemBlock*&);
// -----------------------------------------------------------------------------
// --SECTION-- private variables
// -----------------------------------------------------------------------------
private:
////////////////////////////////////////////////////////////////////////////////
/// @brief last block handed back to the manager
/// this is the block that may be recycled
////////////////////////////////////////////////////////////////////////////////
AqlItemBlock* _last;
};
}
}
#endif
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------
// Local Variables:
// mode: outline-minor
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
// End:

View File

@ -72,7 +72,7 @@ namespace triagens {
// --SECTION-- struct RandomCollectionScanner // --SECTION-- struct RandomCollectionScanner
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
struct RandomCollectionScanner : public CollectionScanner { struct RandomCollectionScanner final : public CollectionScanner {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- constructors / destructors // --SECTION-- constructors / destructors
@ -82,9 +82,9 @@ namespace triagens {
TRI_transaction_collection_t*); TRI_transaction_collection_t*);
int scan (std::vector<TRI_doc_mptr_copy_t>&, int scan (std::vector<TRI_doc_mptr_copy_t>&,
size_t); size_t) override;
void reset (); void reset () override;
uint32_t initialPosition; uint32_t initialPosition;
uint32_t step; uint32_t step;
@ -94,7 +94,7 @@ namespace triagens {
// --SECTION-- struct LinearCollectionScanner // --SECTION-- struct LinearCollectionScanner
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
struct LinearCollectionScanner : public CollectionScanner { struct LinearCollectionScanner final : public CollectionScanner {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- constructors / destructors // --SECTION-- constructors / destructors
@ -104,9 +104,9 @@ namespace triagens {
TRI_transaction_collection_t*); TRI_transaction_collection_t*);
int scan (std::vector<TRI_doc_mptr_copy_t>&, int scan (std::vector<TRI_doc_mptr_copy_t>&,
size_t); size_t) override;
void reset (); void reset () override;
}; };
} }

View File

@ -351,6 +351,23 @@ AqlItemBlock* ExecutionBlock::getSome (size_t atLeast, size_t atMost) {
// --SECTION-- protected methods // --SECTION-- protected methods
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief request an AqlItemBlock from the memory manager
////////////////////////////////////////////////////////////////////////////////
AqlItemBlock* ExecutionBlock::requestBlock (size_t nrItems,
RegisterId nrRegs) {
return _engine->_itemBlockManager.requestBlock(nrItems, nrRegs);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return an AqlItemBlock to the memory manager
////////////////////////////////////////////////////////////////////////////////
void ExecutionBlock::returnBlock (AqlItemBlock* block) {
_engine->_itemBlockManager.returnBlock(block);
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief resolve a collection name and return cid and document key /// @brief resolve a collection name and return cid and document key
/// this is used for parsing _from, _to and _id values /// this is used for parsing _from, _to and _id values
@ -887,12 +904,13 @@ AqlItemBlock* EnumerateCollectionBlock::getSome (size_t, // atLeast,
size_t available = _documents.size() - _posInDocuments; size_t available = _documents.size() - _posInDocuments;
size_t toSend = (std::min)(atMost, available); size_t toSend = (std::min)(atMost, available);
RegisterId nrRegs = getPlanNode()->getRegisterPlan()->nrRegs[getPlanNode()->getDepth()];
unique_ptr<AqlItemBlock> res(new AqlItemBlock(toSend, getPlanNode()->getRegisterPlan()->nrRegs[getPlanNode()->getDepth()])); unique_ptr<AqlItemBlock> res(requestBlock(toSend, nrRegs));
// automatically freed if we throw // automatically freed if we throw
TRI_ASSERT(curRegs <= res->getNrRegs()); TRI_ASSERT(curRegs <= res->getNrRegs());
// only copy 1st row of registers inherited from previous frame(s) // only copy 1st row of registers inherited from previous frame(s)1
inheritRegisters(cur, res.get(), _pos); inheritRegisters(cur, res.get(), _pos);
// set our collection for our output register // set our collection for our output register
@ -928,15 +946,18 @@ AqlItemBlock* EnumerateCollectionBlock::getSome (size_t, // atLeast,
if (! moreDocuments(atMost)) { if (! moreDocuments(atMost)) {
// nothing more to read, re-initialize fetching of documents // nothing more to read, re-initialize fetching of documents
initializeDocuments(); initializeDocuments();
if (++_pos >= cur->size()) { if (++_pos >= cur->size()) {
_buffer.pop_front(); // does not throw _buffer.pop_front(); // does not throw
delete cur; returnBlock(cur);
_pos = 0; _pos = 0;
} }
} }
} }
// Clear out registers no longer needed later: // Clear out registers no longer needed later:
clearRegisters(res.get()); clearRegisters(res.get());
return res.release(); return res.release();
} }
@ -1080,7 +1101,6 @@ void IndexRangeBlock::buildExpressions () {
// The following are needed to evaluate expressions with local data from // The following are needed to evaluate expressions with local data from
// the current incoming item: // the current incoming item:
AqlItemBlock* cur = _buffer.front(); AqlItemBlock* cur = _buffer.front();
vector<TRI_document_collection_t const*>& docColls(cur->getDocumentCollections());
IndexOrCondition* newCondition = nullptr; IndexOrCondition* newCondition = nullptr;
@ -2692,8 +2712,6 @@ void CalculationBlock::fillBlockWithReference (AqlItemBlock* result) {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void CalculationBlock::executeExpression (AqlItemBlock* result) { void CalculationBlock::executeExpression (AqlItemBlock* result) {
std::vector<TRI_document_collection_t const*>& docColls(result->getDocumentCollections());
result->setDocumentCollection(_outReg, nullptr); result->setDocumentCollection(_outReg, nullptr);
bool const hasCondition = (static_cast<CalculationNode const*>(_exeNode)->_conditionVariable != nullptr); bool const hasCondition = (static_cast<CalculationNode const*>(_exeNode)->_conditionVariable != nullptr);
@ -3531,6 +3549,7 @@ int HashedAggregateBlock::getOrSkipSome (size_t atLeast,
size_t& skipped) { size_t& skipped) {
TRI_ASSERT(result == nullptr && skipped == 0); TRI_ASSERT(result == nullptr && skipped == 0);
if (_done) { if (_done) {
return TRI_ERROR_NO_ERROR; return TRI_ERROR_NO_ERROR;
} }
@ -3658,23 +3677,21 @@ int HashedAggregateBlock::getOrSkipSome (size_t atLeast,
++skipped; ++skipped;
result = buildResult(cur); result = buildResult(cur);
delete cur; returnBlock(cur);
cur = nullptr;
_done = true; _done = true;
return TRI_ERROR_NO_ERROR; return TRI_ERROR_NO_ERROR;
} }
catch (...) { catch (...) {
delete cur; returnBlock(cur);
cur = nullptr;
throw; throw;
} }
} }
// hasMore // hasMore
delete cur; returnBlock(cur);
cur = _buffer.front(); cur = _buffer.front();
} }
} }

View File

@ -102,6 +102,10 @@ namespace triagens {
class ExecutionBlock { class ExecutionBlock {
// -----------------------------------------------------------------------------
// --SECTION-- constructors / destructors
// -----------------------------------------------------------------------------
public: public:
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -116,6 +120,10 @@ namespace triagens {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
virtual ~ExecutionBlock (); virtual ~ExecutionBlock ();
// -----------------------------------------------------------------------------
// --SECTION-- public methods
// -----------------------------------------------------------------------------
public: public:
@ -234,6 +242,19 @@ namespace triagens {
protected: protected:
////////////////////////////////////////////////////////////////////////////////
/// @brief request an AqlItemBlock from the memory manager
////////////////////////////////////////////////////////////////////////////////
AqlItemBlock* requestBlock (size_t,
RegisterId);
////////////////////////////////////////////////////////////////////////////////
/// @brief return an AqlItemBlock to the memory manager
////////////////////////////////////////////////////////////////////////////////
void returnBlock (AqlItemBlock*);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief resolve a collection name and return cid and document key /// @brief resolve a collection name and return cid and document key
/// this is used for parsing _from, _to and _id values /// this is used for parsing _from, _to and _id values

View File

@ -1094,7 +1094,6 @@ void ExecutionEngine::addBlock (ExecutionBlock* block) {
_blocks.emplace_back(block); _blocks.emplace_back(block);
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE // --SECTION-- END-OF-FILE
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View File

@ -31,12 +31,12 @@
#define ARANGODB_AQL_EXECUTION_ENGINE_H 1 #define ARANGODB_AQL_EXECUTION_ENGINE_H 1
#include "Basics/Common.h" #include "Basics/Common.h"
#include "Aql/AqlItemBlock.h"
#include "arangod/Aql/AqlItemBlock.h" #include "Aql/AqlItemBlockManager.h"
#include "arangod/Aql/ExecutionBlock.h" #include "Aql/ExecutionBlock.h"
#include "arangod/Aql/ExecutionPlan.h" #include "Aql/ExecutionPlan.h"
#include "arangod/Aql/ExecutionStats.h" #include "Aql/ExecutionStats.h"
#include "arangod/Aql/QueryRegistry.h" #include "Aql/QueryRegistry.h"
#include "Utils/AqlTransaction.h" #include "Utils/AqlTransaction.h"
namespace triagens { namespace triagens {
@ -206,6 +206,22 @@ namespace triagens {
void addBlock (ExecutionBlock*); void addBlock (ExecutionBlock*);
////////////////////////////////////////////////////////////////////////////////
/// @brief _lockedShards
////////////////////////////////////////////////////////////////////////////////
void setLockedShards (std::unordered_set<std::string>* lockedShards) {
_lockedShards = lockedShards;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief _lockedShards
////////////////////////////////////////////////////////////////////////////////
std::unordered_set<std::string>* lockedShards () const {
return _lockedShards;
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- public variables // --SECTION-- public variables
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -220,21 +236,11 @@ namespace triagens {
ExecutionStats _stats; ExecutionStats _stats;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief _lockedShards /// @brief memory recycler for AqlItemBlocks
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
std::unordered_set<std::string>* lockedShards () { AqlItemBlockManager _itemBlockManager;
return _lockedShards;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief _lockedShards
////////////////////////////////////////////////////////////////////////////////
void setLockedShards (std::unordered_set<std::string>* lockedShards) {
_lockedShards = lockedShards;
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- private variables // --SECTION-- private variables
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View File

@ -44,6 +44,7 @@ add_executable(
Actions/RestActionHandler.cpp Actions/RestActionHandler.cpp
Aql/AggregationOptions.cpp Aql/AggregationOptions.cpp
Aql/AqlItemBlock.cpp Aql/AqlItemBlock.cpp
Aql/AqlItemBlockManager.cpp
Aql/AqlValue.cpp Aql/AqlValue.cpp
Aql/Ast.cpp Aql/Ast.cpp
Aql/AstNode.cpp Aql/AstNode.cpp

View File

@ -17,6 +17,7 @@ arangod_libarangod_a_SOURCES = \
arangod/Actions/RestActionHandler.cpp \ arangod/Actions/RestActionHandler.cpp \
arangod/Aql/AggregationOptions.cpp \ arangod/Aql/AggregationOptions.cpp \
arangod/Aql/AqlItemBlock.cpp \ arangod/Aql/AqlItemBlock.cpp \
arangod/Aql/AqlItemBlockManager.cpp \
arangod/Aql/AqlValue.cpp \ arangod/Aql/AqlValue.cpp \
arangod/Aql/Ast.cpp \ arangod/Aql/Ast.cpp \
arangod/Aql/AstNode.cpp \ arangod/Aql/AstNode.cpp \

View File

@ -41,7 +41,7 @@ struct TRI_transaction_s;
namespace triagens { namespace triagens {
namespace arango { namespace arango {
class StandaloneTransactionContext : public TransactionContext { class StandaloneTransactionContext final : public TransactionContext {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- class StandaloneTransactionContext // --SECTION-- class StandaloneTransactionContext

View File

@ -39,7 +39,7 @@ struct TRI_transaction_s;
namespace triagens { namespace triagens {
namespace arango { namespace arango {
class V8TransactionContext : public TransactionContext { class V8TransactionContext final : public TransactionContext {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- class V8TransactionContext // --SECTION-- class V8TransactionContext
@ -61,7 +61,7 @@ namespace triagens {
/// @brief destroy the context /// @brief destroy the context
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
virtual ~V8TransactionContext (); ~V8TransactionContext ();
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- public functions // --SECTION-- public functions

View File

@ -563,7 +563,7 @@ static HttpResponse* ResponseV8ToCpp (v8::Isolate* isolate,
((int) (TRI_ObjectToDouble(res->Get(ResponseCodeKey)))); ((int) (TRI_ObjectToDouble(res->Get(ResponseCodeKey))));
} }
HttpResponse* response = new HttpResponse(code, compatibility); std::unique_ptr<HttpResponse> response(new HttpResponse(code, compatibility));
TRI_GET_GLOBAL_STRING(ContentTypeKey); TRI_GET_GLOBAL_STRING(ContentTypeKey);
if (res->Has(ContentTypeKey)) { if (res->Has(ContentTypeKey)) {
@ -578,6 +578,7 @@ static HttpResponse* ResponseV8ToCpp (v8::Isolate* isolate,
TRI_GET_GLOBAL_STRING(BodyFromFileKey); TRI_GET_GLOBAL_STRING(BodyFromFileKey);
TRI_GET_GLOBAL_STRING(HeadersKey); TRI_GET_GLOBAL_STRING(HeadersKey);
TRI_GET_GLOBAL_STRING(CookiesKey); TRI_GET_GLOBAL_STRING(CookiesKey);
if (res->Has(BodyKey)) { if (res->Has(BodyKey)) {
// check if we should apply result transformations // check if we should apply result transformations
// transformations turn the result from one type into another // transformations turn the result from one type into another
@ -624,7 +625,8 @@ static HttpResponse* ResponseV8ToCpp (v8::Isolate* isolate,
} }
else { else {
// treat body as a string // treat body as a string
response->body().appendText(TRI_ObjectToString(res->Get(BodyKey))); std::string&& obj(TRI_ObjectToString(res->Get(BodyKey)));
response->body().appendText(obj);
} }
} }
} }
@ -685,17 +687,17 @@ static HttpResponse* ResponseV8ToCpp (v8::Isolate* isolate,
for (uint32_t i = 0; i < v8Array->Length(); i++) { for (uint32_t i = 0; i < v8Array->Length(); i++) {
v8::Handle<v8::Value> v8Cookie = v8Array->Get(i); v8::Handle<v8::Value> v8Cookie = v8Array->Get(i);
if (v8Cookie->IsObject()) { if (v8Cookie->IsObject()) {
AddCookie(isolate, v8g, response, v8Cookie.As<v8::Object>()); AddCookie(isolate, v8g, response.get(), v8Cookie.As<v8::Object>());
} }
} }
} }
else if (v8Cookies->IsObject()) { else if (v8Cookies->IsObject()) {
// one cookie // one cookie
AddCookie(isolate, v8g, response, v8Cookies); AddCookie(isolate, v8g, response.get(), v8Cookies);
} }
} }
return response; return response.release();
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -3142,8 +3142,7 @@ static void InsertEdgeColCoordinator (TRI_vocbase_col_t* collection,
/// `collection.insert(data)` /// `collection.insert(data)`
/// ///
/// Creates a new document in the *collection* from the given *data*. The /// Creates a new document in the *collection* from the given *data*. The
/// *data* must be an object. It must not contain attributes starting /// *data* must be an object.
/// with *_*.
/// ///
/// The method returns a document with the attributes *_id* and *_rev*. /// The method returns a document with the attributes *_id* and *_rev*.
/// The attribute *_id* contains the document handle of the newly created /// The attribute *_id* contains the document handle of the newly created

View File

@ -1589,14 +1589,26 @@ static void CreateVocBase (const v8::FunctionCallbackInfo<v8::Value>& args,
// We require exactly 1 or exactly 2 arguments -- anything else is an error // We require exactly 1 or exactly 2 arguments -- anything else is an error
// ........................................................................... // ...........................................................................
if (args.Length() < 1 || args.Length() > 2) { if (args.Length() < 1 || args.Length() > 3) {
TRI_V8_THROW_EXCEPTION_USAGE("_create(<name>, <properties>)"); TRI_V8_THROW_EXCEPTION_USAGE("_create(<name>, <properties>, <type>)");
} }
if (TRI_GetOperationModeServer() == TRI_VOCBASE_MODE_NO_CREATE) { if (TRI_GetOperationModeServer() == TRI_VOCBASE_MODE_NO_CREATE) {
TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_READ_ONLY); TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_READ_ONLY);
} }
// optional, third parameter can override collection type
if (args.Length() == 3 && args[2]->IsString()) {
std::string typeString = TRI_ObjectToString(args[2]);
if (typeString == "edge") {
collectionType = TRI_COL_TYPE_EDGE;
}
else if (typeString == "document") {
collectionType = TRI_COL_TYPE_DOCUMENT;
}
}
PREVENT_EMBEDDED_TRANSACTION(); PREVENT_EMBEDDED_TRANSACTION();

View File

@ -216,20 +216,20 @@ class TraditionalKeyGenerator : public KeyGenerator {
/// @brief generate a key /// @brief generate a key
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
std::string generate (TRI_voc_tick_t); std::string generate (TRI_voc_tick_t) override;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief validate a key /// @brief validate a key
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
int validate (std::string const&, int validate (std::string const&,
bool); bool) override;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief track usage of a key /// @brief track usage of a key
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void track (TRI_voc_key_t); void track (TRI_voc_key_t) override;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief return the generator name /// @brief return the generator name
@ -243,7 +243,7 @@ class TraditionalKeyGenerator : public KeyGenerator {
/// @brief return a JSON representation of the generator /// @brief return a JSON representation of the generator
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
struct TRI_json_t* toJson (TRI_memory_zone_t*) const; struct TRI_json_t* toJson (TRI_memory_zone_t*) const override;
}; };
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -294,20 +294,20 @@ class AutoIncrementKeyGenerator : public KeyGenerator {
/// @brief generate a key /// @brief generate a key
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
std::string generate (TRI_voc_tick_t); std::string generate (TRI_voc_tick_t) override;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief validate a key /// @brief validate a key
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
int validate (std::string const&, int validate (std::string const&,
bool); bool) override;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief track usage of a key /// @brief track usage of a key
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void track (TRI_voc_key_t); void track (TRI_voc_key_t) override;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief return the generator name /// @brief return the generator name
@ -321,7 +321,7 @@ class AutoIncrementKeyGenerator : public KeyGenerator {
/// @brief return a JSON representation of the generator /// @brief return a JSON representation of the generator
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
struct TRI_json_t* toJson (TRI_memory_zone_t*) const; struct TRI_json_t* toJson (TRI_memory_zone_t*) const override;
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- private variables // --SECTION-- private variables

View File

@ -479,6 +479,55 @@ function CollectionSuite () {
db._drop(cn); db._drop(cn);
}, },
////////////////////////////////////////////////////////////////////////////////
/// @brief creating with type
////////////////////////////////////////////////////////////////////////////////
testCreatingTypeDocument : function () {
var cn = "example";
db._drop(cn);
var c1 = db._create(cn, { }, "document");
assertTypeOf("string", c1._id);
assertEqual(cn, c1.name());
assertEqual(ArangoCollection.TYPE_DOCUMENT, c1.type());
db._drop(cn);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief creating with type
////////////////////////////////////////////////////////////////////////////////
testCreatingTypeEdge : function () {
var cn = "example";
db._drop(cn);
var c1 = db._create(cn, { }, "edge");
assertTypeOf("string", c1._id);
assertEqual(cn, c1.name());
assertEqual(ArangoCollection.TYPE_EDGE, c1.type());
db._drop(cn);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief creating with type
////////////////////////////////////////////////////////////////////////////////
testCreatingTypeInvalid : function () {
var cn = "example";
db._drop(cn);
// invalid type defaults to type "document"
var c1 = db._create(cn, { }, "foobar");
assertTypeOf("string", c1._id);
assertEqual(cn, c1.name());
assertEqual(ArangoCollection.TYPE_DOCUMENT, c1.type());
db._drop(cn);
},
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief drop new-born /// @brief drop new-born
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -61,6 +61,7 @@ var optionsDocumentation = [
' - `skipTimeCritical`: if set to true, time critical tests will be skipped.', ' - `skipTimeCritical`: if set to true, time critical tests will be skipped.',
' - `skipSsl`: ommit the ssl_server rspec tests.', ' - `skipSsl`: ommit the ssl_server rspec tests.',
' - `skipLogAnalysis`: don\'t try to crawl the server logs', ' - `skipLogAnalysis`: don\'t try to crawl the server logs',
' - `skipConfig`: ommit the noisy configuration tests',
'', '',
' - `cluster`: if set to true the tests are run with the coordinator', ' - `cluster`: if set to true the tests are run with the coordinator',
' of a small local cluster', ' of a small local cluster',
@ -836,6 +837,7 @@ function runInArangosh (options, instanceInfo, file, addArgs) {
} }
var arangosh = fs.join("bin","arangosh"); var arangosh = fs.join("bin","arangosh");
var result; var result;
print(toArgv(args));
var rc = executeAndWait(arangosh, toArgv(args)); var rc = executeAndWait(arangosh, toArgv(args));
try { try {
result = JSON.parse(fs.read("testresult.json")); result = JSON.parse(fs.read("testresult.json"));
@ -1154,7 +1156,10 @@ testFuncs.shell_client = function(options) {
return results; return results;
}; };
testFuncs.config = function () { testFuncs.config = function (options) {
if (options.skipConfig) {
return {};
}
var topDir = findTopDir(); var topDir = findTopDir();
var results = {}; var results = {};
var ts = ["arangod", var ts = ["arangod",

View File

@ -71,7 +71,7 @@ namespace triagens {
/// @brief destroys an endpoint /// @brief destroys an endpoint
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
virtual ~EndpointUnixDomain (); ~EndpointUnixDomain ();
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- public methods // --SECTION-- public methods
@ -89,13 +89,13 @@ namespace triagens {
/// @brief disconnect the endpoint /// @brief disconnect the endpoint
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
virtual void disconnect (); void disconnect () override;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief init an incoming connection /// @brief init an incoming connection
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
virtual bool initIncoming (TRI_socket_t); bool initIncoming (TRI_socket_t) override;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief get endpoint domain /// @brief get endpoint domain

View File

@ -177,11 +177,11 @@ namespace triagens {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief deletes a http response /// @brief deletes a http response
/// ///
/// The descrutor will free the string buffers used. After the http response /// The destructor will free the string buffers used. After the http response
/// is deleted, the string buffers returned by body() become invalid. /// is deleted, the string buffers returned by body() become invalid.
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
virtual ~HttpResponse (); ~HttpResponse ();
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- public methods // --SECTION-- public methods

View File

@ -163,7 +163,7 @@ void ClientConnection::disconnectSocket () {
/// @brief prepare connection for read/write I/O /// @brief prepare connection for read/write I/O
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool ClientConnection::prepare (const double timeout, const bool isWrite) const { bool ClientConnection::prepare (double timeout, bool isWrite) const {
struct timeval tv; struct timeval tv;
fd_set fdset; fd_set fdset;
int res; int res;

View File

@ -46,7 +46,7 @@ namespace triagens {
/// @brief client connection /// @brief client connection
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
class ClientConnection : public GeneralClientConnection { class ClientConnection final : public GeneralClientConnection {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- constructors / destructors // --SECTION-- constructors / destructors
@ -72,7 +72,7 @@ namespace triagens {
/// @brief destroys a client connection /// @brief destroys a client connection
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
virtual ~ClientConnection (); ~ClientConnection ();
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- private methods // --SECTION-- private methods
@ -94,38 +94,38 @@ namespace triagens {
/// @brief connect /// @brief connect
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool connectSocket (); bool connectSocket () override;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief disconnect /// @brief disconnect
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void disconnectSocket (); void disconnectSocket () override;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief prepare connection for read/write I/O /// @brief prepare connection for read/write I/O
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool prepare (const double, const bool) const; bool prepare (double, bool) const override;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief write data to the connection /// @brief write data to the connection
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool writeClientConnection (void*, size_t, size_t*); bool writeClientConnection (void*, size_t, size_t*) override;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief read data from the connection /// @brief read data from the connection
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool readClientConnection (triagens::basics::StringBuffer&, bool readClientConnection (triagens::basics::StringBuffer&,
bool& connectionClosed); bool& connectionClosed) override;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief return whether the connection is readable /// @brief return whether the connection is readable
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool readable (); bool readable () override;
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- private variables // --SECTION-- private variables

View File

@ -106,7 +106,7 @@ namespace triagens {
/// @brief return the endpoint /// @brief return the endpoint
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
const triagens::rest::Endpoint* getEndpoint () const { triagens::rest::Endpoint const* getEndpoint () const {
return _endpoint; return _endpoint;
} }
@ -114,7 +114,7 @@ namespace triagens {
/// @brief returns a string representation of the connection endpoint /// @brief returns a string representation of the connection endpoint
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
const std::string getEndpointSpecification () const { std::string getEndpointSpecification () const {
return _endpoint->getSpecification(); return _endpoint->getSpecification();
} }
@ -197,7 +197,7 @@ namespace triagens {
/// @brief prepare connection for read/write I/O /// @brief prepare connection for read/write I/O
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
virtual bool prepare (const double, const bool) const = 0; virtual bool prepare (double, bool) const = 0;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief write data to the connection /// @brief write data to the connection

View File

@ -264,7 +264,7 @@ void SslClientConnection::disconnectSocket () {
/// @brief prepare connection for read/write I/O /// @brief prepare connection for read/write I/O
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool SslClientConnection::prepare (const double timeout, const bool isWrite) const { bool SslClientConnection::prepare (double timeout, bool isWrite) const {
struct timeval tv; struct timeval tv;
fd_set fdset; fd_set fdset;
int res; int res;

View File

@ -50,7 +50,7 @@ namespace triagens {
/// @brief client connection /// @brief client connection
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
class SslClientConnection : public GeneralClientConnection { class SslClientConnection final : public GeneralClientConnection {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- constructors / destructors // --SECTION-- constructors / destructors
@ -77,7 +77,7 @@ namespace triagens {
/// @brief destroys a client connection /// @brief destroys a client connection
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
virtual ~SslClientConnection (); ~SslClientConnection ();
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- protected virtual methods // --SECTION-- protected virtual methods
@ -89,38 +89,44 @@ namespace triagens {
/// @brief connect /// @brief connect
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool connectSocket (); bool connectSocket () override;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief disconnect /// @brief disconnect
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void disconnectSocket (); void disconnectSocket () override;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief prepare connection for read/write I/O /// @brief prepare connection for read/write I/O
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool prepare (const double, const bool) const; bool prepare (double, bool) const override;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief write data to the connection /// @brief write data to the connection
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool writeClientConnection (void*, size_t, size_t*); bool writeClientConnection (void*, size_t, size_t*) override;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief read data from the connection /// @brief read data from the connection
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool readClientConnection (triagens::basics::StringBuffer&, bool readClientConnection (triagens::basics::StringBuffer&,
bool& connectionClosed); bool& connectionClosed) override;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief return whether the connection is readable /// @brief return whether the connection is readable
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool readable (); bool readable () override;
// -----------------------------------------------------------------------------
// --SECTION-- private methods
// -----------------------------------------------------------------------------
private:
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief return whether the socket is still workable /// @brief return whether the socket is still workable