mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'devel' into ClustUp1
This commit is contained in:
commit
7a91accb71
|
@ -67,6 +67,8 @@ class Builder {
|
||||||
// open objects/arrays
|
// open objects/arrays
|
||||||
std::vector<std::vector<ValueLength>> _index; // Indices for starts
|
std::vector<std::vector<ValueLength>> _index; // Indices for starts
|
||||||
// of subindex
|
// of subindex
|
||||||
|
bool _keyWritten; // indicates that in the current object the key
|
||||||
|
// has been written but the value not yet
|
||||||
|
|
||||||
// Here are the mechanics of how this building process works:
|
// Here are the mechanics of how this building process works:
|
||||||
// The whole VPack being built starts at where _start points to
|
// The whole VPack being built starts at where _start points to
|
||||||
|
@ -131,7 +133,7 @@ class Builder {
|
||||||
// Constructor and destructor:
|
// Constructor and destructor:
|
||||||
explicit Builder(std::shared_ptr<Buffer<uint8_t>>& buffer,
|
explicit Builder(std::shared_ptr<Buffer<uint8_t>>& buffer,
|
||||||
Options const* options = &Options::Defaults)
|
Options const* options = &Options::Defaults)
|
||||||
: _buffer(buffer), _pos(0), options(options) {
|
: _buffer(buffer), _pos(0), _keyWritten(false), options(options) {
|
||||||
if (_buffer.get() == nullptr) {
|
if (_buffer.get() == nullptr) {
|
||||||
throw Exception(Exception::InternalError, "Buffer cannot be a nullptr");
|
throw Exception(Exception::InternalError, "Buffer cannot be a nullptr");
|
||||||
}
|
}
|
||||||
|
@ -144,7 +146,8 @@ class Builder {
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit Builder(Options const* options = &Options::Defaults)
|
explicit Builder(Options const* options = &Options::Defaults)
|
||||||
: _buffer(new Buffer<uint8_t>()), _pos(0), options(options) {
|
: _buffer(new Buffer<uint8_t>()), _pos(0), _keyWritten(false),
|
||||||
|
options(options) {
|
||||||
_start = _buffer->data();
|
_start = _buffer->data();
|
||||||
_size = _buffer->size();
|
_size = _buffer->size();
|
||||||
|
|
||||||
|
@ -164,6 +167,7 @@ class Builder {
|
||||||
_pos(that._pos),
|
_pos(that._pos),
|
||||||
_stack(that._stack),
|
_stack(that._stack),
|
||||||
_index(that._index),
|
_index(that._index),
|
||||||
|
_keyWritten(that._keyWritten),
|
||||||
options(that.options) {
|
options(that.options) {
|
||||||
if (options == nullptr) {
|
if (options == nullptr) {
|
||||||
throw Exception(Exception::InternalError, "Options cannot be a nullptr");
|
throw Exception(Exception::InternalError, "Options cannot be a nullptr");
|
||||||
|
@ -180,6 +184,7 @@ class Builder {
|
||||||
_pos = that._pos;
|
_pos = that._pos;
|
||||||
_stack = that._stack;
|
_stack = that._stack;
|
||||||
_index = that._index;
|
_index = that._index;
|
||||||
|
_keyWritten = that._keyWritten;
|
||||||
options = that.options;
|
options = that.options;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -197,10 +202,12 @@ class Builder {
|
||||||
_stack.swap(that._stack);
|
_stack.swap(that._stack);
|
||||||
_index.clear();
|
_index.clear();
|
||||||
_index.swap(that._index);
|
_index.swap(that._index);
|
||||||
|
_keyWritten = that._keyWritten;
|
||||||
options = that.options;
|
options = that.options;
|
||||||
that._start = that._buffer->data();
|
that._start = that._buffer->data();
|
||||||
that._size = 0;
|
that._size = 0;
|
||||||
that._pos = 0;
|
that._pos = 0;
|
||||||
|
that._keyWritten = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Builder& operator=(Builder&& that) {
|
Builder& operator=(Builder&& that) {
|
||||||
|
@ -216,10 +223,12 @@ class Builder {
|
||||||
_stack.swap(that._stack);
|
_stack.swap(that._stack);
|
||||||
_index.clear();
|
_index.clear();
|
||||||
_index.swap(that._index);
|
_index.swap(that._index);
|
||||||
|
_keyWritten = that._keyWritten;
|
||||||
options = that.options;
|
options = that.options;
|
||||||
that._start = that._buffer->data();
|
that._start = that._buffer->data();
|
||||||
that._size = 0;
|
that._size = 0;
|
||||||
that._pos = 0;
|
that._pos = 0;
|
||||||
|
that._keyWritten = false;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,6 +247,8 @@ class Builder {
|
||||||
|
|
||||||
std::string toString() const;
|
std::string toString() const;
|
||||||
|
|
||||||
|
std::string toJson() const;
|
||||||
|
|
||||||
static Builder clone(Slice const& slice,
|
static Builder clone(Slice const& slice,
|
||||||
Options const* options = &Options::Defaults) {
|
Options const* options = &Options::Defaults) {
|
||||||
if (options == nullptr) {
|
if (options == nullptr) {
|
||||||
|
@ -246,7 +257,7 @@ class Builder {
|
||||||
|
|
||||||
Builder b(options);
|
Builder b(options);
|
||||||
b.add(slice);
|
b.add(slice);
|
||||||
return std::move(b);
|
return b; // Use return value optimization
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear and start from scratch:
|
// Clear and start from scratch:
|
||||||
|
@ -276,6 +287,22 @@ class Builder {
|
||||||
|
|
||||||
bool isClosed() const throw() { return _stack.empty(); }
|
bool isClosed() const throw() { return _stack.empty(); }
|
||||||
|
|
||||||
|
bool isOpenArray() const throw() {
|
||||||
|
if (_stack.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ValueLength const tos = _stack.back();
|
||||||
|
return _start[tos] == 0x06 || _start[tos] == 0x13;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isOpenObject() const throw() {
|
||||||
|
if (_stack.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ValueLength const tos = _stack.back();
|
||||||
|
return _start[tos] == 0x0b || _start[tos] == 0x14;
|
||||||
|
}
|
||||||
|
|
||||||
// Add a subvalue into an object from a Value:
|
// Add a subvalue into an object from a Value:
|
||||||
uint8_t* add(std::string const& attrName, Value const& sub);
|
uint8_t* add(std::string const& attrName, Value const& sub);
|
||||||
|
|
||||||
|
@ -435,6 +462,25 @@ private:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
inline void checkKeyIsString(bool isString) {
|
||||||
|
if (! _stack.empty()) {
|
||||||
|
ValueLength const tos = _stack.back();
|
||||||
|
if (_start[tos] == 0x0b || _start[tos] == 0x14) {
|
||||||
|
if (! _keyWritten) {
|
||||||
|
if (isString) {
|
||||||
|
_keyWritten = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw Exception(Exception::BuilderKeyMustBeString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_keyWritten = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inline void addArray(bool unindexed = false) {
|
inline void addArray(bool unindexed = false) {
|
||||||
addCompoundValue(unindexed ? 0x13 : 0x06);
|
addCompoundValue(unindexed ? 0x13 : 0x06);
|
||||||
}
|
}
|
||||||
|
@ -447,12 +493,10 @@ private:
|
||||||
uint8_t* addInternal(T const& sub) {
|
uint8_t* addInternal(T const& sub) {
|
||||||
bool haveReported = false;
|
bool haveReported = false;
|
||||||
if (!_stack.empty()) {
|
if (!_stack.empty()) {
|
||||||
ValueLength& tos = _stack.back();
|
if (! _keyWritten) {
|
||||||
if (_start[tos] != 0x06 && _start[tos] != 0x13) {
|
reportAdd();
|
||||||
throw Exception(Exception::BuilderNeedOpenArray);
|
haveReported = true;
|
||||||
}
|
}
|
||||||
reportAdd(tos);
|
|
||||||
haveReported = true;
|
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return set(sub);
|
return set(sub);
|
||||||
|
@ -473,7 +517,10 @@ private:
|
||||||
if (_start[tos] != 0x0b && _start[tos] != 0x14) {
|
if (_start[tos] != 0x0b && _start[tos] != 0x14) {
|
||||||
throw Exception(Exception::BuilderNeedOpenObject);
|
throw Exception(Exception::BuilderNeedOpenObject);
|
||||||
}
|
}
|
||||||
reportAdd(tos);
|
if (_keyWritten) {
|
||||||
|
throw Exception(Exception::BuilderKeyAlreadyWritten);
|
||||||
|
}
|
||||||
|
reportAdd();
|
||||||
haveReported = true;
|
haveReported = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -484,13 +531,19 @@ private:
|
||||||
options->attributeTranslator->translate(attrName);
|
options->attributeTranslator->translate(attrName);
|
||||||
|
|
||||||
if (translated != nullptr) {
|
if (translated != nullptr) {
|
||||||
set(Slice(translated, options));
|
Slice item(translated);
|
||||||
|
ValueLength const l = item.byteSize();
|
||||||
|
reserveSpace(l);
|
||||||
|
memcpy(_start + _pos, translated, checkOverflow(l));
|
||||||
|
_pos += l;
|
||||||
|
_keyWritten = true;
|
||||||
return set(sub);
|
return set(sub);
|
||||||
}
|
}
|
||||||
// otherwise fall through to regular behavior
|
// otherwise fall through to regular behavior
|
||||||
}
|
}
|
||||||
|
|
||||||
set(Value(attrName, ValueType::String));
|
set(Value(attrName, ValueType::String));
|
||||||
|
_keyWritten = true;
|
||||||
return set(sub);
|
return set(sub);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
// clean up in case of an exception
|
// clean up in case of an exception
|
||||||
|
@ -518,11 +571,16 @@ private:
|
||||||
bool haveReported = false;
|
bool haveReported = false;
|
||||||
if (!_stack.empty()) {
|
if (!_stack.empty()) {
|
||||||
ValueLength& tos = _stack.back();
|
ValueLength& tos = _stack.back();
|
||||||
if (_start[tos] != 0x06 && _start[tos] != 0x13) {
|
if (! _keyWritten) {
|
||||||
throw Exception(Exception::BuilderNeedOpenCompound);
|
if (_start[tos] != 0x06 && _start[tos] != 0x13) {
|
||||||
|
throw Exception(Exception::BuilderNeedOpenArray);
|
||||||
|
}
|
||||||
|
reportAdd();
|
||||||
|
haveReported = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_keyWritten = false;
|
||||||
}
|
}
|
||||||
reportAdd(tos);
|
|
||||||
haveReported = true;
|
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
addCompoundValue(type);
|
addCompoundValue(type);
|
||||||
|
@ -547,9 +605,9 @@ private:
|
||||||
_index[depth].pop_back();
|
_index[depth].pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
void reportAdd(ValueLength base) {
|
void reportAdd() {
|
||||||
size_t depth = _stack.size() - 1;
|
size_t depth = _stack.size() - 1;
|
||||||
_index[depth].push_back(_pos - base);
|
_index[depth].push_back(_pos - _stack[depth]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void appendLength(ValueLength v, uint64_t n) {
|
void appendLength(ValueLength v, uint64_t n) {
|
||||||
|
@ -644,7 +702,12 @@ struct ObjectBuilder final : public BuilderContainer, public NoHeapAllocation {
|
||||||
builder->add(attributeName, Value(ValueType::Object, allowUnindexed));
|
builder->add(attributeName, Value(ValueType::Object, allowUnindexed));
|
||||||
}
|
}
|
||||||
~ObjectBuilder() {
|
~ObjectBuilder() {
|
||||||
builder->close();
|
try {
|
||||||
|
builder->close();
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
// destructors must not throw
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -654,7 +717,12 @@ struct ArrayBuilder final : public BuilderContainer, public NoHeapAllocation {
|
||||||
builder->openArray(allowUnindexed);
|
builder->openArray(allowUnindexed);
|
||||||
}
|
}
|
||||||
~ArrayBuilder() {
|
~ArrayBuilder() {
|
||||||
builder->close();
|
try {
|
||||||
|
builder->close();
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
// destructors must not throw
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,8 @@ struct Exception : std::exception {
|
||||||
BuilderUnexpectedValue = 35,
|
BuilderUnexpectedValue = 35,
|
||||||
BuilderNeedSubvalue = 36,
|
BuilderNeedSubvalue = 36,
|
||||||
BuilderExternalsDisallowed = 37,
|
BuilderExternalsDisallowed = 37,
|
||||||
|
BuilderKeyAlreadyWritten = 38,
|
||||||
|
BuilderKeyMustBeString = 39,
|
||||||
|
|
||||||
UnknownError = 999
|
UnknownError = 999
|
||||||
};
|
};
|
||||||
|
@ -133,6 +135,10 @@ struct Exception : std::exception {
|
||||||
return "Unexpected value";
|
return "Unexpected value";
|
||||||
case BuilderExternalsDisallowed:
|
case BuilderExternalsDisallowed:
|
||||||
return "Externals are not allowed in this configuration";
|
return "Externals are not allowed in this configuration";
|
||||||
|
case BuilderKeyAlreadyWritten:
|
||||||
|
return "The key of the next key/value pair is already written";
|
||||||
|
case BuilderKeyMustBeString:
|
||||||
|
return "The key of the next key/value pair must be a string";
|
||||||
|
|
||||||
case UnknownError:
|
case UnknownError:
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -43,6 +43,13 @@ std::string Builder::toString() const {
|
||||||
return std::move(buffer);
|
return std::move(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string Builder::toJson() const {
|
||||||
|
std::string buffer;
|
||||||
|
StringSink sink(&buffer);
|
||||||
|
Dumper::dump(slice(), &sink);
|
||||||
|
return std::move(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
void Builder::doActualSort(std::vector<SortEntry>& entries) {
|
void Builder::doActualSort(std::vector<SortEntry>& entries) {
|
||||||
VELOCYPACK_ASSERT(entries.size() > 1);
|
VELOCYPACK_ASSERT(entries.size() > 1);
|
||||||
std::sort(entries.begin(), entries.end(),
|
std::sort(entries.begin(), entries.end(),
|
||||||
|
@ -401,7 +408,7 @@ Slice Builder::getKey(std::string const& key) const {
|
||||||
if (_stack.empty()) {
|
if (_stack.empty()) {
|
||||||
throw Exception(Exception::BuilderNeedOpenObject);
|
throw Exception(Exception::BuilderNeedOpenObject);
|
||||||
}
|
}
|
||||||
ValueLength const& tos = _stack.back();
|
ValueLength const tos = _stack.back();
|
||||||
if (_start[tos] != 0x0b && _start[tos] != 0x14) {
|
if (_start[tos] != 0x0b && _start[tos] != 0x14) {
|
||||||
throw Exception(Exception::BuilderNeedOpenObject);
|
throw Exception(Exception::BuilderNeedOpenObject);
|
||||||
}
|
}
|
||||||
|
@ -422,6 +429,8 @@ uint8_t* Builder::set(Value const& item) {
|
||||||
auto const oldPos = _start + _pos;
|
auto const oldPos = _start + _pos;
|
||||||
auto ctype = item.cType();
|
auto ctype = item.cType();
|
||||||
|
|
||||||
|
checkKeyIsString(item.valueType() == ValueType::String);
|
||||||
|
|
||||||
// This method builds a single further VPack item at the current
|
// This method builds a single further VPack item at the current
|
||||||
// append position. If this is an array or object, then an index
|
// append position. If this is an array or object, then an index
|
||||||
// table is created and a new ValueLength is pushed onto the stack.
|
// table is created and a new ValueLength is pushed onto the stack.
|
||||||
|
@ -666,6 +675,9 @@ uint8_t* Builder::set(Value const& item) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* Builder::set(Slice const& item) {
|
uint8_t* Builder::set(Slice const& item) {
|
||||||
|
|
||||||
|
checkKeyIsString(item.isString());
|
||||||
|
|
||||||
ValueLength const l = item.byteSize();
|
ValueLength const l = item.byteSize();
|
||||||
reserveSpace(l);
|
reserveSpace(l);
|
||||||
memcpy(_start + _pos, item.start(), checkOverflow(l));
|
memcpy(_start + _pos, item.start(), checkOverflow(l));
|
||||||
|
@ -678,6 +690,9 @@ uint8_t* Builder::set(ValuePair const& pair) {
|
||||||
// append position. This is the case for ValueType::String,
|
// append position. This is the case for ValueType::String,
|
||||||
// ValueType::Binary, or ValueType::Custom, which can be built
|
// ValueType::Binary, or ValueType::Custom, which can be built
|
||||||
// with two pieces of information
|
// with two pieces of information
|
||||||
|
|
||||||
|
checkKeyIsString(pair.valueType() == ValueType::String);
|
||||||
|
|
||||||
if (pair.valueType() == ValueType::Binary) {
|
if (pair.valueType() == ValueType::Binary) {
|
||||||
uint64_t v = pair.getSize();
|
uint64_t v = pair.getSize();
|
||||||
appendUInt(v, 0xbf);
|
appendUInt(v, 0xbf);
|
||||||
|
|
|
@ -49,8 +49,19 @@ ValueLength Parser::parseInternal(bool multi) {
|
||||||
do {
|
do {
|
||||||
bool haveReported = false;
|
bool haveReported = false;
|
||||||
if (!_b->_stack.empty()) {
|
if (!_b->_stack.empty()) {
|
||||||
_b->reportAdd(_b->_stack.back());
|
ValueLength const tos = _b->_stack.back();
|
||||||
haveReported = true;
|
if (_b->_start[tos] == 0x0b || _b->_start[tos] == 0x14) {
|
||||||
|
if (! _b->_keyWritten) {
|
||||||
|
throw Exception(Exception::BuilderKeyMustBeString);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_b->_keyWritten = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_b->reportAdd();
|
||||||
|
haveReported = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
parseJson();
|
parseJson();
|
||||||
|
@ -400,7 +411,6 @@ void Parser::parseString() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::parseArray() {
|
void Parser::parseArray() {
|
||||||
ValueLength base = _b->_pos;
|
|
||||||
_b->addArray();
|
_b->addArray();
|
||||||
|
|
||||||
int i = skipWhiteSpace("Expecting item or ']'");
|
int i = skipWhiteSpace("Expecting item or ']'");
|
||||||
|
@ -415,7 +425,7 @@ void Parser::parseArray() {
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
// parse array element itself
|
// parse array element itself
|
||||||
_b->reportAdd(base);
|
_b->reportAdd();
|
||||||
parseJson();
|
parseJson();
|
||||||
i = skipWhiteSpace("Expecting ',' or ']'");
|
i = skipWhiteSpace("Expecting ',' or ']'");
|
||||||
if (i == ']') {
|
if (i == ']') {
|
||||||
|
@ -437,7 +447,6 @@ void Parser::parseArray() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::parseObject() {
|
void Parser::parseObject() {
|
||||||
ValueLength base = _b->_pos;
|
|
||||||
_b->addObject();
|
_b->addObject();
|
||||||
|
|
||||||
int i = skipWhiteSpace("Expecting item or '}'");
|
int i = skipWhiteSpace("Expecting item or '}'");
|
||||||
|
@ -461,7 +470,7 @@ void Parser::parseObject() {
|
||||||
// get past the initial '"'
|
// get past the initial '"'
|
||||||
++_pos;
|
++_pos;
|
||||||
|
|
||||||
_b->reportAdd(base);
|
_b->reportAdd();
|
||||||
bool excludeAttribute = false;
|
bool excludeAttribute = false;
|
||||||
auto const lastPos = _b->_pos;
|
auto const lastPos = _b->_pos;
|
||||||
if (options->attributeExcludeHandler == nullptr) {
|
if (options->attributeExcludeHandler == nullptr) {
|
||||||
|
|
|
@ -616,8 +616,7 @@ v8::Handle<v8::Value> AqlValue::toV8 (v8::Isolate* isolate,
|
||||||
}
|
}
|
||||||
|
|
||||||
case EMPTY: {
|
case EMPTY: {
|
||||||
return v8::Null(isolate); // TODO: FIXME decide if we really want this...---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
return v8::Null(isolate);
|
||||||
return v8::Undefined(isolate);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -693,8 +692,7 @@ Json AqlValue::toJson (triagens::arango::AqlTransaction* trx,
|
||||||
}
|
}
|
||||||
|
|
||||||
case EMPTY: {
|
case EMPTY: {
|
||||||
return Json(Json::Null); // TODO FIXME: decide if we really want this...--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
return Json(Json::Null);
|
||||||
return triagens::basics::Json();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3085,7 +3085,7 @@ static Json getDocumentByIdentifier (triagens::arango::AqlTransaction* trx,
|
||||||
if (ex.code() == TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND) {
|
if (ex.code() == TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND) {
|
||||||
return Json(Json::Null);
|
return Json(Json::Null);
|
||||||
}
|
}
|
||||||
throw ex;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRI_doc_mptr_copy_t mptr;
|
TRI_doc_mptr_copy_t mptr;
|
||||||
|
@ -3165,7 +3165,7 @@ AqlValue Functions::Document (triagens::aql::Query* query,
|
||||||
catch (triagens::basics::Exception const& ex) {
|
catch (triagens::basics::Exception const& ex) {
|
||||||
// don't throw if collection is not found
|
// don't throw if collection is not found
|
||||||
if (ex.code() != TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND) {
|
if (ex.code() != TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND) {
|
||||||
throw ex;
|
throw;
|
||||||
}
|
}
|
||||||
notFound = true;
|
notFound = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -266,6 +266,10 @@ var unregisterFunctionsGroup = function (group) {
|
||||||
/// The registered function is stored in the selected database's system
|
/// The registered function is stored in the selected database's system
|
||||||
/// collection *_aqlfunctions*.
|
/// collection *_aqlfunctions*.
|
||||||
///
|
///
|
||||||
|
/// The function returns *true* when it updates/replaces an existing AQL
|
||||||
|
/// function of the same name, and *false* otherwise. It will throw an exception
|
||||||
|
/// when it detects syntactially invalid function code.
|
||||||
|
///
|
||||||
/// @EXAMPLES
|
/// @EXAMPLES
|
||||||
///
|
///
|
||||||
/// ```js
|
/// ```js
|
||||||
|
|
|
@ -101,12 +101,12 @@ function createRequire(module) {
|
||||||
// Enable support to add extra extension types
|
// Enable support to add extra extension types
|
||||||
require.extensions = Module._extensions;
|
require.extensions = Module._extensions;
|
||||||
|
|
||||||
require.cache = Module._cache;
|
require.cache = module.cache;
|
||||||
|
|
||||||
return require;
|
return require;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Module(id, parent) {
|
function Module(id, parent, cache) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.exports = {};
|
this.exports = {};
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
|
@ -114,6 +114,8 @@ function Module(id, parent) {
|
||||||
parent.children.push(this);
|
parent.children.push(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.cache = cache || (parent ? parent.cache : Module._cache);
|
||||||
|
|
||||||
this.context = {
|
this.context = {
|
||||||
print: internal.print,
|
print: internal.print,
|
||||||
process: NATIVE_MODULES.process,
|
process: NATIVE_MODULES.process,
|
||||||
|
@ -126,6 +128,7 @@ function Module(id, parent) {
|
||||||
};
|
};
|
||||||
|
|
||||||
if (parent) {
|
if (parent) {
|
||||||
|
this.root = parent.root;
|
||||||
this.preprocess = parent.preprocess;
|
this.preprocess = parent.preprocess;
|
||||||
Object.keys(parent.context).forEach(function (key) {
|
Object.keys(parent.context).forEach(function (key) {
|
||||||
if (!hasOwnProperty(this.context, key)) {
|
if (!hasOwnProperty(this.context, key)) {
|
||||||
|
@ -292,7 +295,7 @@ Module._findPath = function(request, paths) {
|
||||||
};
|
};
|
||||||
|
|
||||||
// 'from' is the __dirname of the module.
|
// 'from' is the __dirname of the module.
|
||||||
Module._nodeModulePaths = function(from) {
|
Module._nodeModulePaths = function(from, root) {
|
||||||
// guarantee that 'from' is absolute.
|
// guarantee that 'from' is absolute.
|
||||||
from = path.resolve(from);
|
from = path.resolve(from);
|
||||||
|
|
||||||
|
@ -302,11 +305,13 @@ Module._nodeModulePaths = function(from) {
|
||||||
var splitRe = (internal.platform === 'win32' || internal.platform === 'win64') ? /[\/\\]/ : /\//;
|
var splitRe = (internal.platform === 'win32' || internal.platform === 'win64') ? /[\/\\]/ : /\//;
|
||||||
var paths = [];
|
var paths = [];
|
||||||
var parts = from.split(splitRe);
|
var parts = from.split(splitRe);
|
||||||
|
var inRoot = root && from.indexOf(root) === 0;
|
||||||
|
|
||||||
for (var tip = parts.length - 1; tip >= 0; tip--) {
|
for (var tip = parts.length - 1; tip >= 0; tip--) {
|
||||||
// don't search in .../node_modules/node_modules
|
// don't search in .../node_modules/node_modules
|
||||||
if (parts[tip] === 'node_modules') continue;
|
if (parts[tip] === 'node_modules') continue;
|
||||||
var dir = parts.slice(0, tip + 1).concat('node_modules').join(path.sep);
|
var dir = parts.slice(0, tip + 1).concat('node_modules').join(path.sep);
|
||||||
|
if (inRoot && dir.indexOf(root) !== 0) break;
|
||||||
paths.push(dir);
|
paths.push(dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -386,6 +391,13 @@ Module._resolveDbModule = function (request) {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function isGlobalModule(filename) {
|
||||||
|
return modulePaths.some(function (modulePath) {
|
||||||
|
return filename.indexOf(modulePath) === 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Check the cache for the requested file.
|
// Check the cache for the requested file.
|
||||||
// 1. If a module already exists in the cache: return its exports object.
|
// 1. If a module already exists in the cache: return its exports object.
|
||||||
// 2. If the module is native: call `NativeModule.require()` with the
|
// 2. If the module is native: call `NativeModule.require()` with the
|
||||||
|
@ -394,6 +406,7 @@ Module._resolveDbModule = function (request) {
|
||||||
// Then have it load the file contents before returning its exports
|
// Then have it load the file contents before returning its exports
|
||||||
// object.
|
// object.
|
||||||
Module._load = function(request, parent, isMain) {
|
Module._load = function(request, parent, isMain) {
|
||||||
|
|
||||||
var filename = request;
|
var filename = request;
|
||||||
var dbModule = false;
|
var dbModule = false;
|
||||||
var match = request.match(/^\/?db:(\/(\/_modules)?)?(\/.+)/);
|
var match = request.match(/^\/?db:(\/(\/_modules)?)?(\/.+)/);
|
||||||
|
@ -420,7 +433,11 @@ Module._load = function(request, parent, isMain) {
|
||||||
filename = dbModule.path;
|
filename = dbModule.path;
|
||||||
}
|
}
|
||||||
|
|
||||||
var cachedModule = Module._cache[filename];
|
var cache;
|
||||||
|
if (parent && (dbModule || !isGlobalModule(filename))) cache = parent.cache;
|
||||||
|
else cache = Module._cache;
|
||||||
|
|
||||||
|
var cachedModule = cache[filename];
|
||||||
if (cachedModule) {
|
if (cachedModule) {
|
||||||
return cachedModule.exports;
|
return cachedModule.exports;
|
||||||
}
|
}
|
||||||
|
@ -435,8 +452,8 @@ Module._load = function(request, parent, isMain) {
|
||||||
module.id = '.';
|
module.id = '.';
|
||||||
}
|
}
|
||||||
|
|
||||||
Module._cache[filename] = module;
|
cache[filename] = module;
|
||||||
LOADING.push(filename);
|
LOADING.push({cache, filename});
|
||||||
|
|
||||||
var hadException = true;
|
var hadException = true;
|
||||||
|
|
||||||
|
@ -449,7 +466,7 @@ Module._load = function(request, parent, isMain) {
|
||||||
hadException = false;
|
hadException = false;
|
||||||
} finally {
|
} finally {
|
||||||
if (hadException) {
|
if (hadException) {
|
||||||
delete Module._cache[filename];
|
delete cache[filename];
|
||||||
}
|
}
|
||||||
var i = LOADING.indexOf(filename);
|
var i = LOADING.indexOf(filename);
|
||||||
if (i !== -1) {
|
if (i !== -1) {
|
||||||
|
@ -462,8 +479,8 @@ Module._load = function(request, parent, isMain) {
|
||||||
|
|
||||||
Module._cleanupCancelation = function () {
|
Module._cleanupCancelation = function () {
|
||||||
while (LOADING.length) {
|
while (LOADING.length) {
|
||||||
var filename = LOADING.pop();
|
let loading = LOADING.pop();
|
||||||
delete Module._cache[filename];
|
delete loading.cache[loading.filename];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -491,7 +508,7 @@ Module._resolveFilename = function(request, parent) {
|
||||||
Module.prototype.load = function(filename) {
|
Module.prototype.load = function(filename) {
|
||||||
assert(!this.loaded);
|
assert(!this.loaded);
|
||||||
this.filename = filename;
|
this.filename = filename;
|
||||||
this.paths = Module._nodeModulePaths(path.dirname(filename));
|
this.paths = Module._nodeModulePaths(path.dirname(filename), this.root);
|
||||||
|
|
||||||
var extension = path.extname(filename) || '.js';
|
var extension = path.extname(filename) || '.js';
|
||||||
if (!Module._extensions[extension]) extension = '.js';
|
if (!Module._extensions[extension]) extension = '.js';
|
||||||
|
@ -526,7 +543,7 @@ Module.prototype._compile = function(content, filename) {
|
||||||
// remove shebang
|
// remove shebang
|
||||||
content = content.replace(/^\#\!.*/, '');
|
content = content.replace(/^\#\!.*/, '');
|
||||||
if (this.preprocess) {
|
if (this.preprocess) {
|
||||||
content = this.preprocess(content);
|
content = this.preprocess(content, filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
// test for parse errors first and fail early if a parse error detected
|
// test for parse errors first and fail early if a parse error detected
|
||||||
|
|
|
@ -265,6 +265,10 @@ var unregisterFunctionsGroup = function (group) {
|
||||||
/// The registered function is stored in the selected database's system
|
/// The registered function is stored in the selected database's system
|
||||||
/// collection *_aqlfunctions*.
|
/// collection *_aqlfunctions*.
|
||||||
///
|
///
|
||||||
|
/// The function returns *true* when it updates/replaces an existing AQL
|
||||||
|
/// function of the same name, and *false* otherwise. It will throw an exception
|
||||||
|
/// when it detects syntactially invalid function code.
|
||||||
|
///
|
||||||
/// @EXAMPLES
|
/// @EXAMPLES
|
||||||
///
|
///
|
||||||
/// ```js
|
/// ```js
|
||||||
|
|
|
@ -27,8 +27,7 @@
|
||||||
/// @author Copyright 2013, triAGENS GmbH, Cologne, Germany
|
/// @author Copyright 2013, triAGENS GmbH, Cologne, Germany
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
var extend = require("underscore").extend,
|
var extend = require('underscore').extend;
|
||||||
coffeeScript = require("coffee-script");
|
|
||||||
|
|
||||||
function ArrayIterator(arr) {
|
function ArrayIterator(arr) {
|
||||||
this.array = arr;
|
this.array = arr;
|
||||||
|
@ -54,7 +53,7 @@ extend(ArrayIterator.prototype, {
|
||||||
},
|
},
|
||||||
|
|
||||||
entireString: function () {
|
entireString: function () {
|
||||||
return this.array.join("\n");
|
return this.array.join('\n');
|
||||||
},
|
},
|
||||||
|
|
||||||
getCurrentLineNumber: function () {
|
getCurrentLineNumber: function () {
|
||||||
|
@ -64,22 +63,21 @@ extend(ArrayIterator.prototype, {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function Preprocessor(input, type) {
|
function Preprocessor(input) {
|
||||||
if (type === 'coffee') {
|
this.iterator = new ArrayIterator(input.replace('\r', '').split('\n'));
|
||||||
input = coffeeScript.compile(input, {bare: true});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.iterator = new ArrayIterator(input.replace('\r', '').split("\n"));
|
|
||||||
this.inJSDoc = false;
|
this.inJSDoc = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
extend(Preprocessor.prototype, {
|
extend(Preprocessor.prototype, {
|
||||||
result: function () {
|
result: function () {
|
||||||
return this.iterator.entireString();
|
return this.iterator.entireString();
|
||||||
},
|
},
|
||||||
|
|
||||||
convert: function () {
|
convert: function (filename) {
|
||||||
while (this.searchNext()) {
|
if (filename && filename.indexOf('node_modules') !== -1) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
while (this.searchNext()) {
|
||||||
this.convertLine();
|
this.convertLine();
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
|
@ -94,8 +92,8 @@ extend(Preprocessor.prototype, {
|
||||||
},
|
},
|
||||||
|
|
||||||
convertLine: function () {
|
convertLine: function () {
|
||||||
this.iterator.replaceWith(
|
this.iterator.replaceWith(
|
||||||
"applicationContext.comment(\"" + this.stripComment(this.iterator.current()) + "\");"
|
`applicationContext.comment("${this.stripComment(this.iterator.current())}");`
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -139,9 +137,9 @@ extend(Preprocessor.prototype, {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function preprocess(input, type) {
|
function preprocess(input, filename) {
|
||||||
var processor = new Preprocessor(input, type);
|
var processor = new Preprocessor(input);
|
||||||
return processor.convert().result();
|
return processor.convert(filename).result();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only Exported for Tests, please use `process`
|
// Only Exported for Tests, please use `process`
|
||||||
|
|
|
@ -627,6 +627,10 @@ var routeApp = function (app, isInstallProcess) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (controllers) {
|
if (controllers) {
|
||||||
|
Object.keys(app.moduleCache).forEach(function (filename) {
|
||||||
|
// Clear the module cache to force re-evaluation
|
||||||
|
delete app.moduleCache[filename];
|
||||||
|
});
|
||||||
Object.keys(controllers).forEach(function (key) {
|
Object.keys(controllers).forEach(function (key) {
|
||||||
mountController(app, routes, key, controllers[key]);
|
mountController(app, routes, key, controllers[key]);
|
||||||
});
|
});
|
||||||
|
|
|
@ -191,8 +191,11 @@ class FoxxService {
|
||||||
}
|
}
|
||||||
|
|
||||||
let lib = this.manifest.lib || '.';
|
let lib = this.manifest.lib || '.';
|
||||||
this.main = new Module(`foxx:${data.mount}`);
|
let moduleRoot = path.resolve(this.root, this.path, lib);
|
||||||
this.main.filename = path.resolve(this.root, this.path, lib, '.foxx');
|
this.moduleCache = {};
|
||||||
|
this.main = new Module(`foxx:${data.mount}`, undefined, this.moduleCache);
|
||||||
|
this.main.root = moduleRoot;
|
||||||
|
this.main.filename = path.resolve(moduleRoot, '.foxx');
|
||||||
this.main.context.applicationContext = new AppContext(this);
|
this.main.context.applicationContext = new AppContext(this);
|
||||||
this.main.context.console = require('org/arangodb/foxx/console')(this.mount);
|
this.main.context.console = require('org/arangodb/foxx/console')(this.mount);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1052,7 +1052,7 @@ function performTests(options, testList, testname, remote) {
|
||||||
print("Skipping, " + te + " server is gone.");
|
print("Skipping, " + te + " server is gone.");
|
||||||
results[te] = {status: false, message: instanceInfo.exitStatus};
|
results[te] = {status: false, message: instanceInfo.exitStatus};
|
||||||
instanceInfo.exitStatus = "server is gone.";
|
instanceInfo.exitStatus = "server is gone.";
|
||||||
continue;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
print("\n" + Date() + " arangod: Trying",te,"...");
|
print("\n" + Date() + " arangod: Trying",te,"...");
|
||||||
|
@ -1290,7 +1290,7 @@ testFuncs.shell_client = function(options) {
|
||||||
print("Skipping, " + te + " server is gone.");
|
print("Skipping, " + te + " server is gone.");
|
||||||
results[te] = {status: false, message: instanceInfo.exitStatus};
|
results[te] = {status: false, message: instanceInfo.exitStatus};
|
||||||
instanceInfo.exitStatus = "server is gone.";
|
instanceInfo.exitStatus = "server is gone.";
|
||||||
continue;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
print("\narangosh: Trying",te,"...");
|
print("\narangosh: Trying",te,"...");
|
||||||
|
@ -1444,7 +1444,7 @@ function rubyTests (options, ssl) {
|
||||||
print("Skipping " + te + " server is gone.");
|
print("Skipping " + te + " server is gone.");
|
||||||
result[te] = {status: false, message: instanceInfo.exitStatus};
|
result[te] = {status: false, message: instanceInfo.exitStatus};
|
||||||
instanceInfo.exitStatus = "server is gone.";
|
instanceInfo.exitStatus = "server is gone.";
|
||||||
continue;
|
break;
|
||||||
}
|
}
|
||||||
print("\n"+ Date() + " rspec Trying ",te,"...");
|
print("\n"+ Date() + " rspec Trying ",te,"...");
|
||||||
|
|
||||||
|
@ -1973,7 +1973,7 @@ testFuncs.arangob = function (options) {
|
||||||
print("Skipping " + benchTodo[i] + ", server is gone.");
|
print("Skipping " + benchTodo[i] + ", server is gone.");
|
||||||
results[i] = {status: false, message: instanceInfo.exitStatus};
|
results[i] = {status: false, message: instanceInfo.exitStatus};
|
||||||
instanceInfo.exitStatus = "server is gone.";
|
instanceInfo.exitStatus = "server is gone.";
|
||||||
continue;
|
break;
|
||||||
}
|
}
|
||||||
var args = benchTodo[i];
|
var args = benchTodo[i];
|
||||||
if (options.hasOwnProperty('benchargs')) {
|
if (options.hasOwnProperty('benchargs')) {
|
||||||
|
@ -2097,7 +2097,7 @@ testFuncs.authentication_parameters = function (options) {
|
||||||
};
|
};
|
||||||
instanceInfo.exitStatus = "server is gone.";
|
instanceInfo.exitStatus = "server is gone.";
|
||||||
all_ok = false;
|
all_ok = false;
|
||||||
continue;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = download(instanceInfo.url + urlsTodo[i],"", downloadOptions);
|
r = download(instanceInfo.url + urlsTodo[i],"", downloadOptions);
|
||||||
|
|
Loading…
Reference in New Issue