1
0
Fork 0

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

This commit is contained in:
Michael Hackstein 2015-10-22 16:23:05 +02:00
commit 3af1f80dc9
27 changed files with 124 additions and 920 deletions

View File

@ -691,7 +691,7 @@ if (OPENSSL_LIB_PATH)
endif ()
################################################################################
### @brief READLINE or LINENOISE
### @brief LINENOISE
################################################################################
if (MSVC)

View File

@ -54,14 +54,14 @@ different usage scenarios:
Geo indexes will only be invoked via special functions.
- full-text index: a full-text index can be used to index all words contained in
- fulltext index: a fulltext index can be used to index all words contained in
a specific attribute of all documents in a collection. Only words with a
(specifiable) minimum length are indexed. Word tokenization is done using
the word boundary analysis provided by libicu, which is taking into account
the selected language provided at server start.
The index supports complete match queries (full words) and prefix queries.
Full-text indexes will only be invoked via special functions.
Fulltext indexes will only be invoked via special functions.
- cap constraint: the cap constraint provided by ArangoDB indexes documents
not to speed up search queries, but to limit (cap) the number or size of
@ -114,7 +114,7 @@ the lookup value cannot be `null`, a sparse index may be used. When uncertain, t
will not make use of a sparse index in a query in order to produce correct results.
For example, the following queries cannot use a sparse index on `attr` because the optimizer
will not know beforehand whether the comparison values for `doc.attr` will include `null`:
will not know beforehand whether the values which are compared to `doc.attr` will include `null`:
FOR doc In collection
FILTER doc.attr == SOME_FUNCTION(...)

View File

@ -19,7 +19,7 @@
### zlib
* free as-is license
* [free as-is license](https://github.com/arangodb/arangodb/blob/devel/3rdParty/zlib-1.2.7/README#L85)
### Valgrind
@ -31,12 +31,6 @@
* http://www.boost.org/
* [boost software license](http://www.boost.org/LICENSE_1_0.txt)
### readline
* http://cnswww.cns.cwru.edu/php/chet/readline/rltop.html
* GNU GPL
* alternatively linenoise can be used
### linenoise
* https://github.com/antirez/linenoise
@ -57,9 +51,8 @@
### Bison
* https://www.gnu.org/software/bison/
* GNU GPL3
* only used to generate code, not part of the distribution
* see https://github.com/arangodb/arangodb/blob/devel/arangod/Aql/grammar.cpp#L20
* parts used see https://github.com/arangodb/arangodb/blob/devel/arangod/Aql/grammar.cpp#L20
### Flex
@ -79,27 +72,27 @@
#### Jasmine
* https://jasmine.github.io
* MIT License
* [MIT License](https://raw.githubusercontent.com/jasmine/jasmine/master/MIT.LICENSE)
#### JSUnity
* https://github.com/atesgoral/jsunity
* MIT License
* [MIT License](http://www.opensource.org/licenses/mit-license.php)
#### ArangoDB Query Builder
* https://github.com/arangodb/aqbjs
* Apache 2
* [Apache 2](https://raw.githubusercontent.com/arangodb/aqbjs/master/LICENSE)
#### Chai
* http://chaijs.com
* MIT License
* [MIT License](https://github.com/chaijs/chai/blob/master/README.md)
#### CoffeeScript
* http://coffeescript.org
* MIT License
* [MIT License](https://www.npmjs.com/package/coffee-script)
#### stacktrace.js
@ -109,72 +102,72 @@
#### expect.js
* https://github.com/Automattic/expect.js
* MIT License
* [MIT License](https://github.com/Automattic/expect.js/blob/master/README.md)
#### extendible
* https://github.com/3rd-Eden/extendible
* MIT License
* [MIT License](https://github.com/bigpipe/extendible/blob/master/README.md)
#### Foxx Generator
* https://github.com/moonglum/foxx_generator
* Apache 2 License
* [Apache 2 License](https://raw.githubusercontent.com/moonglum/foxx_generator/master/LICENSE)
#### highlight.js
* https://highlightjs.org
* BSD 3-Clause License
* [BSD 3-Clause License](https://raw.githubusercontent.com/isagalaev/highlight.js/master/LICENSE)
#### http-errors
* https://github.com/jshttp/http-errors
* MIT License
* [MIT License](https://raw.githubusercontent.com/jshttp/http-errors/master/LICENSE)
#### i
* https://github.com/pksunkara/inflect
* MIT License
* [MIT License](https://raw.githubusercontent.com/pksunkara/inflect/master/LICENSE)
#### Joi
* https://github.com/hapijs/joi
* BSD 3-Clause License
* [BSD 3-Clause License](https://raw.githubusercontent.com/hapijs/joi/master/LICENSE)
#### Ace
* https://github.com/ajaxorg/ace
* BSD 3-Clause License
* [BSD 3-Clause License](https://raw.githubusercontent.com/ajaxorg/ace/master/LICENSE)
#### YAML
* https://github.com/nodeca/js-yaml
* MIT License
* [MIT License](https://raw.githubusercontent.com/nodeca/js-yaml/master/LICENSE)
#### JSHint
* http://jshint.com
* MIT License
* [MIT License](https://raw.githubusercontent.com/jshint/jshint/master/LICENSE)
#### minimatch
* https://github.com/isaacs/minimatch
* MIT License
* [MIT License](https://raw.githubusercontent.com/isaacs/minimatch/master/LICENSE)
#### mocha
* http://mochajs.org
* MIT License
* [MIT License](https://raw.githubusercontent.com/mochajs/mocha/master/LICENSE)
#### qs
* https://github.com/hapijs/qs
* BSD 3-Clause License
* [BSD 3-Clause License](https://raw.githubusercontent.com/hapijs/hapi/master/LICENSE)
#### Ramda
* http://ramdajs.com
* MIT License
* [MIT License](https://raw.githubusercontent.com/ramda/ramda/master/LICENSE.txt)
#### semver
@ -184,109 +177,111 @@
#### Sinon.JS
* http://sinonjs.org
* BSD 3-Clause License
* [BSD 3-Clause License](https://www.npmjs.com/package/sinon)
#### underscore
* http://underscorejs.org
* MIT License
* [MIT License](https://github.com/jashkenas/underscore/blob/master/LICENSE)
### Frontend libraries
#### swagger
* http://swagger.io
* Apache 2 License
* [Apache 2 License](https://raw.githubusercontent.com/swagger-api/swagger-js/master/LICENSE)
#### Backbone.js
* http://backbonejs.org
* MIT License
* [MIT License](https://raw.githubusercontent.com/jashkenas/backbone/master/LICENSE)
#### Bootstrap
* http://getbootstrap.com
* MIT License
* [MIT License](https://github.com/twbs/bootstrap/blob/master/LICENSE)
#### D3js
* http://d3js.org
* BSD 3-Clause License
* [BSD 3-Clause License](https://raw.githubusercontent.com/mbostock/d3/master/LICENSE)
#### dygraph
* http://dygraphs.com
* MIT License
* [MIT License](https://www.npmjs.com/package/dygraphs)
#### EJS
* http://www.embeddedjs.com
* MIT License
* [MIT License](http://www.embeddedjs.com/) under Highlights
#### jqconsole
* https://github.com/replit/jq-console
* MIT License
* [MIT License](https://github.com/replit/jq-console/blob/master/README.md)
#### jQuery
* http://jquery.com
* MIT License
* [MIT License](https://raw.githubusercontent.com/jquery/jquery/master/LICENSE.txt)
#### jQuery UI
* http://jqueryui.com
* MIT License
* [MIT License](https://raw.githubusercontent.com/jquery/jquery-ui/master/LICENSE.txt)
#### jQuery Snippet
* http://steamdev.com/snippet
* MIT License
* [MIT License](https://web.archive.org/web/20150817084109/http://steamdev.com/snippet/) in "section 5"
#### jQuery Hotkeys
* https://github.com/jeresig/jquery.hotkeys
* MIT License or GPL Version 2 License
* https://code.google.com/p/js-hotkeys/
* [MIT License](https://code.google.com/p/js-hotkeys/) under "Code license"
#### jQuery Contextmenu
* https://github.com/swisnl/jQuery-contextMenu
* MIT License
* [MIT License](https://github.com/swisnl/jQuery-contextMenu) under "License"
#### jQuery Form
* https://github.com/malsup/form/
* MIT License or GPL Version 2 License
* [MIT License](https://github.com/malsup/form/) under "Copyright and License"
#### jQuery UploadFile
* https://github.com/hayageek/jquery-upload-file/
* MIT License
* [MIT License](https://raw.githubusercontent.com/hayageek/jquery-upload-file/master/MIT-License.txt)
#### jQuery Textfill
* https://github.com/jquery-textfill/jquery-textfill
* MIT License
* [MIT License](https://raw.githubusercontent.com/jquery-textfill/jquery-textfill/master/COPYING.md)
#### jQuery Strftime
* https://github.com/samsonjs/strftime
* MIT License
* [MIT License](https://github.com/samsonjs/strftime) under "License"
#### nvd3
* https://github.com/novus/nvd3
* Apache 2 License
* [Apache 2 License](https://github.com/novus/nvd3/blob/master/LICENSE.md) under "nvd3.js"
#### jsoneditor.js
* Apache 2 License
* https://github.com/josdejong/jsoneditor/
* [Apache 2 License](https://raw.githubusercontent.com/josdejong/jsoneditor/master/LICENSE)
#### Crypto.js
* https://github.com/brix/crypto-js
* MIT License / BSD 3-Clause License
* [MIT License](https://github.com/brix/crypto-js) under "License"
#### select2
* Apache 2 License
* https://github.com/select2/select2
* [Apache 2 License](https://github.com/select2/select2)

View File

@ -118,7 +118,6 @@ AM_CPPFLAGS = \
@LIBEV_CPPFLAGS@ \
@MATH_CPPFLAGS@ \
@OPENSSL_CPPFLAGS@ \
@READLINE_CPPFLAGS@ \
@ICU_CPPFLAGS@ \
@ZLIB_CPPFLAGS@ \
@V8_CPPFLAGS@
@ -131,7 +130,6 @@ AM_LDFLAGS = \
@LIBEV_LDFLAGS@ \
@MATH_LDFLAGS@ \
@OPENSSL_LDFLAGS@ \
@READLINE_LDFLAGS@ \
@ICU_LDFLAGS@ \
@ZLIB_LDFLAGS@ \
@V8_LDFLAGS@
@ -147,8 +145,7 @@ LIBS = \
@MATH_LIBS@ \
@OPENSSL_LIBS@ \
@ICU_LIBS@ \
@ZLIB_LIBS@ \
@READLINE_LIBS@
@ZLIB_LIBS@
## -----------------------------------------------------------------------------
## --SECTION-- LIBRARIES & PROGRAMS
@ -528,11 +525,6 @@ cmake-setup:
-D OPENSSL_LIBS= \
-D OPENSSL_VERSION= \
\
-D READLINE_INCLUDE= \
-D READLINE_LIB_PATH= \
-D READLINE_LIBS= \
-D READLINE_VERSION= \
\
-D V8_INCLUDE= \
-D V8_LIB_PATH= \
-D V8_LIBS= \

View File

@ -1756,8 +1756,12 @@ AstNode* Ast::clone (AstNode const* node) {
// recursively clone subnodes
size_t const n = node->numMembers();
for (size_t i = 0; i < n; ++i) {
copy->addMember(clone(node->getMemberUnchecked(i)));
if (n > 0) {
copy->members.reserve(n);
for (size_t i = 0; i < n; ++i) {
copy->addMember(clone(node->getMemberUnchecked(i)));
}
}
return copy;

View File

@ -403,7 +403,7 @@ bool IndexBlock::readIndex (size_t atMost) {
size_t lastIndexNr = _indexes.size() - 1;
bool isReverse = (static_cast<IndexNode const*>(getPlanNode()))->_reverse;
bool isLastIndex = (_currentIndex == lastIndexNr && !isReverse) || (_currentIndex == 0 && isReverse);
bool isLastIndex = (_currentIndex == lastIndexNr && ! isReverse) || (_currentIndex == 0 && isReverse);
try {
size_t nrSent = 0;
while (nrSent < atMost && _iterator != nullptr) {

View File

@ -279,7 +279,6 @@ target_link_libraries(
${ICU_LIBS}
${BT_LIBS}
${ZLIB_LIBS}
${READLINE_LIBS}
${OPENSSL_LIBS}
${CMAKE_THREAD_LIBS_INIT}
${MSVC_LIBS}

View File

@ -812,7 +812,7 @@ IndexIterator* HashIndex::iteratorForCondition (IndexIteratorContext* context,
triagens::aql::Ast* ast,
triagens::aql::AstNode const* node,
triagens::aql::Variable const* reference,
bool const reverse) const {
bool reverse) const {
TRI_ASSERT(node->type == aql::NODE_TYPE_OPERATOR_NARY_AND);
SimpleAttributeEqualityMatcher matcher(fields());
@ -825,12 +825,16 @@ IndexIterator* HashIndex::iteratorForCondition (IndexIteratorContext* context,
permutationStates.reserve(n);
size_t maxPermutations = 1;
std::pair<triagens::aql::Variable const*, std::vector<triagens::basics::AttributeName>> paramPair;
for (size_t i = 0; i < n; ++i) {
std::pair<triagens::aql::Variable const*, std::vector<triagens::basics::AttributeName>> paramPair;
auto comp = allVals->getMemberUnchecked(i);
auto attrNode = comp->getMember(0);
auto valNode = comp->getMember(1);
paramPair.first = nullptr;
paramPair.second.clear();
if (! attrNode->isAttributeAccessForVariable(paramPair) || paramPair.first != reference) {
attrNode = comp->getMember(1);
valNode = comp->getMember(0);

View File

@ -192,7 +192,7 @@ namespace triagens {
triagens::aql::Ast*,
triagens::aql::AstNode const*,
triagens::aql::Variable const*,
bool const) const override;
bool) const override;
triagens::aql::AstNode* specializeCondition (triagens::aql::AstNode*,
triagens::aql::Variable const*) const override;

View File

@ -553,7 +553,8 @@ triagens::aql::AstNode* Index::specializeCondition (triagens::aql::AstNode* node
bool Index::canUseConditionPart (triagens::aql::AstNode const* access,
triagens::aql::AstNode const* other,
triagens::aql::AstNode const* op,
triagens::aql::Variable const* reference) const {
triagens::aql::Variable const* reference,
bool isExecution) const {
if (_sparse) {
if (op->type == triagens::aql::NODE_TYPE_OPERATOR_BINARY_NIN) {
@ -614,6 +615,11 @@ bool Index::canUseConditionPart (triagens::aql::AstNode const* access,
}
}
if (isExecution) {
// in execution phase, we do not need to check the variable usage again
return true;
}
// test if the reference variable is contained on both side of the expression
std::unordered_set<aql::Variable const*> variables;
if (op->type == triagens::aql::NODE_TYPE_OPERATOR_BINARY_IN &&

View File

@ -370,7 +370,8 @@ namespace triagens {
bool canUseConditionPart (triagens::aql::AstNode const* access,
triagens::aql::AstNode const* other,
triagens::aql::AstNode const* op,
triagens::aql::Variable const* reference) const;
triagens::aql::Variable const* reference,
bool) const;
// -----------------------------------------------------------------------------
// --SECTION-- protected variables

View File

@ -72,8 +72,8 @@ bool SimpleAttributeEqualityMatcher::matchOne (triagens::arango::Index const* in
if (op->type == triagens::aql::NODE_TYPE_OPERATOR_BINARY_EQ) {
TRI_ASSERT(op->numMembers() == 2);
// EQ is symmetric
if (accessFitsIndex(index, op->getMember(0), op->getMember(1), op, reference) ||
accessFitsIndex(index, op->getMember(1), op->getMember(0), op, reference)) {
if (accessFitsIndex(index, op->getMember(0), op->getMember(1), op, reference, false) ||
accessFitsIndex(index, op->getMember(1), op->getMember(0), op, reference, false)) {
// we can use the index
calculateIndexCosts(index, itemsInIndex, estimatedItems, estimatedCost);
return true;
@ -81,7 +81,7 @@ bool SimpleAttributeEqualityMatcher::matchOne (triagens::arango::Index const* in
}
else if (op->type == triagens::aql::NODE_TYPE_OPERATOR_BINARY_IN) {
TRI_ASSERT(op->numMembers() == 2);
if (accessFitsIndex(index, op->getMember(0), op->getMember(1), op, reference)) {
if (accessFitsIndex(index, op->getMember(0), op->getMember(1), op, reference, false)) {
// we can use the index
// use slightly different cost calculation for IN that for EQ
calculateIndexCosts(index, itemsInIndex, estimatedItems, estimatedCost);
@ -118,8 +118,8 @@ bool SimpleAttributeEqualityMatcher::matchAll (triagens::arango::Index const* in
if (op->type == triagens::aql::NODE_TYPE_OPERATOR_BINARY_EQ) {
TRI_ASSERT(op->numMembers() == 2);
if (accessFitsIndex(index, op->getMember(0), op->getMember(1), op, reference) ||
accessFitsIndex(index, op->getMember(1), op->getMember(0), op, reference)) {
if (accessFitsIndex(index, op->getMember(0), op->getMember(1), op, reference, false) ||
accessFitsIndex(index, op->getMember(1), op->getMember(0), op, reference, false)) {
if (_found.size() == _attributes.size()) {
// got enough attributes
break;
@ -129,7 +129,7 @@ bool SimpleAttributeEqualityMatcher::matchAll (triagens::arango::Index const* in
else if (op->type == triagens::aql::NODE_TYPE_OPERATOR_BINARY_IN) {
TRI_ASSERT(op->numMembers() == 2);
if (accessFitsIndex(index, op->getMember(0), op->getMember(1), op, reference)) {
if (accessFitsIndex(index, op->getMember(0), op->getMember(1), op, reference, false)) {
auto m = op->getMember(1);
if (m->type != triagens::aql::NODE_TYPE_EXPANSION && m->numMembers() > 1) {
// attr IN [ a, b, c ] => this will produce multiple items, so count them!
@ -182,10 +182,10 @@ triagens::aql::AstNode* SimpleAttributeEqualityMatcher::getOne (triagens::aql::A
op->type == triagens::aql::NODE_TYPE_OPERATOR_BINARY_IN) {
TRI_ASSERT(op->numMembers() == 2);
// note: accessFitsIndex will increase _found in case of a condition match
bool matches = accessFitsIndex(index, op->getMember(0), op->getMember(1), op, reference);
bool matches = accessFitsIndex(index, op->getMember(0), op->getMember(1), op, reference, true);
if (! matches && op->type == triagens::aql::NODE_TYPE_OPERATOR_BINARY_EQ) {
matches = accessFitsIndex(index, op->getMember(1), op->getMember(0), op, reference);
matches = accessFitsIndex(index, op->getMember(1), op->getMember(0), op, reference, true);
}
if (matches) {
@ -223,11 +223,11 @@ triagens::aql::AstNode* SimpleAttributeEqualityMatcher::getAll (triagens::aql::A
op->type == triagens::aql::NODE_TYPE_OPERATOR_BINARY_IN) {
TRI_ASSERT(op->numMembers() == 2);
// note: accessFitsIndex will increase _found in case of a condition match
bool matches = accessFitsIndex(index, op->getMember(0), op->getMember(1), op, reference);
bool matches = accessFitsIndex(index, op->getMember(0), op->getMember(1), op, reference, true);
if (! matches && op->type == triagens::aql::NODE_TYPE_OPERATOR_BINARY_EQ) {
// EQ is symmetric
matches = accessFitsIndex(index, op->getMember(1), op->getMember(0), op, reference);
matches = accessFitsIndex(index, op->getMember(1), op->getMember(0), op, reference, true);
}
if (matches) {
@ -238,14 +238,14 @@ triagens::aql::AstNode* SimpleAttributeEqualityMatcher::getAll (triagens::aql::A
if (_found.size() == _attributes.size()) {
// got enough matches
std::unique_ptr<triagens::aql::AstNode> node(ast->createNodeNaryOperator(triagens::aql::NODE_TYPE_OPERATOR_NARY_AND));
auto node = ast->createNodeNaryOperator(triagens::aql::NODE_TYPE_OPERATOR_NARY_AND);
for (auto& it : parts) {
node->addMember(ast->clone(it));
node->addMember(it);
}
// done
return node.release();
return node;
}
}
}
@ -274,8 +274,8 @@ triagens::aql::AstNode* SimpleAttributeEqualityMatcher::specializeOne (triagens:
if (op->type == triagens::aql::NODE_TYPE_OPERATOR_BINARY_EQ) {
TRI_ASSERT(op->numMembers() == 2);
// EQ is symmetric
if (accessFitsIndex(index, op->getMember(0), op->getMember(1), op, reference) ||
accessFitsIndex(index, op->getMember(1), op->getMember(0), op, reference)) {
if (accessFitsIndex(index, op->getMember(0), op->getMember(1), op, reference, false) ||
accessFitsIndex(index, op->getMember(1), op->getMember(0), op, reference, false)) {
// we can use the index
// now return only the child node we need
while (node->numMembers() > 0) {
@ -289,7 +289,7 @@ triagens::aql::AstNode* SimpleAttributeEqualityMatcher::specializeOne (triagens:
else if (op->type == triagens::aql::NODE_TYPE_OPERATOR_BINARY_IN) {
TRI_ASSERT(op->numMembers() == 2);
if (accessFitsIndex(index, op->getMember(0), op->getMember(1), op, reference)) {
if (accessFitsIndex(index, op->getMember(0), op->getMember(1), op, reference, false)) {
// we can use the index
// now return only the child node we need
while (node->numMembers() > 0) {
@ -325,8 +325,8 @@ triagens::aql::AstNode* SimpleAttributeEqualityMatcher::specializeAll (triagens:
if (op->type == triagens::aql::NODE_TYPE_OPERATOR_BINARY_EQ) {
TRI_ASSERT(op->numMembers() == 2);
if (accessFitsIndex(index, op->getMember(0), op->getMember(1), op, reference) ||
accessFitsIndex(index, op->getMember(1), op->getMember(0), op, reference)) {
if (accessFitsIndex(index, op->getMember(0), op->getMember(1), op, reference, false) ||
accessFitsIndex(index, op->getMember(1), op->getMember(0), op, reference, false)) {
children.emplace_back(op);
TRI_IF_FAILURE("SimpleAttributeMatcher::specializeAllChildrenEQ") {
THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG);
@ -339,7 +339,7 @@ triagens::aql::AstNode* SimpleAttributeEqualityMatcher::specializeAll (triagens:
}
else if (op->type == triagens::aql::NODE_TYPE_OPERATOR_BINARY_IN) {
TRI_ASSERT(op->numMembers() == 2);
if (accessFitsIndex(index, op->getMember(0), op->getMember(1), op, reference)) {
if (accessFitsIndex(index, op->getMember(0), op->getMember(1), op, reference, false)) {
children.emplace_back(op);
TRI_IF_FAILURE("SimpleAttributeMatcher::specializeAllChildrenIN") {
THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG);
@ -433,8 +433,9 @@ bool SimpleAttributeEqualityMatcher::accessFitsIndex (triagens::arango::Index co
triagens::aql::AstNode const* access,
triagens::aql::AstNode const* other,
triagens::aql::AstNode const* op,
triagens::aql::Variable const* reference) {
if (! index->canUseConditionPart(access, other, op, reference)) {
triagens::aql::Variable const* reference,
bool isExecution) {
if (! index->canUseConditionPart(access, other, op, reference, isExecution)) {
return false;
}

View File

@ -157,7 +157,8 @@ namespace triagens {
triagens::aql::AstNode const*,
triagens::aql::AstNode const*,
triagens::aql::AstNode const*,
triagens::aql::Variable const*);
triagens::aql::Variable const*,
bool);
// -----------------------------------------------------------------------------
// --SECTION-- private variables

View File

@ -1047,8 +1047,9 @@ bool SkiplistIndex::accessFitsIndex (triagens::aql::AstNode const* access,
triagens::aql::AstNode const* other,
triagens::aql::AstNode const* op,
triagens::aql::Variable const* reference,
std::unordered_map<size_t, std::vector<triagens::aql::AstNode const*>>& found) const {
if (! this->canUseConditionPart(access, other, op, reference)) {
std::unordered_map<size_t, std::vector<triagens::aql::AstNode const*>>& found,
bool isExecution) const {
if (! this->canUseConditionPart(access, other, op, reference, isExecution)) {
return false;
}
@ -1100,7 +1101,8 @@ bool SkiplistIndex::accessFitsIndex (triagens::aql::AstNode const* access,
void SkiplistIndex::matchAttributes (triagens::aql::AstNode const* node,
triagens::aql::Variable const* reference,
std::unordered_map<size_t, std::vector<triagens::aql::AstNode const*>>& found,
size_t& values) const {
size_t& values,
bool isExecution) const {
for (size_t i = 0; i < node->numMembers(); ++i) {
auto op = node->getMember(i);
@ -1111,12 +1113,12 @@ void SkiplistIndex::matchAttributes (triagens::aql::AstNode const* node,
case triagens::aql::NODE_TYPE_OPERATOR_BINARY_GT:
case triagens::aql::NODE_TYPE_OPERATOR_BINARY_GE:
TRI_ASSERT(op->numMembers() == 2);
accessFitsIndex(op->getMember(0), op->getMember(1), op, reference, found);
accessFitsIndex(op->getMember(1), op->getMember(0), op, reference, found);
accessFitsIndex(op->getMember(0), op->getMember(1), op, reference, found, isExecution);
accessFitsIndex(op->getMember(1), op->getMember(0), op, reference, found, isExecution);
break;
case triagens::aql::NODE_TYPE_OPERATOR_BINARY_IN:
if (accessFitsIndex(op->getMember(0), op->getMember(1), op, reference, found)) {
if (accessFitsIndex(op->getMember(0), op->getMember(1), op, reference, found, isExecution)) {
auto m = op->getMember(1);
if (m->type != triagens::aql::NODE_TYPE_EXPANSION && m->numMembers() > 1) {
// attr IN [ a, b, c ] => this will produce multiple items, so count them!
@ -1124,7 +1126,7 @@ void SkiplistIndex::matchAttributes (triagens::aql::AstNode const* node,
}
}
else {
accessFitsIndex(op->getMember(1), op->getMember(0), op, reference, found);
accessFitsIndex(op->getMember(1), op->getMember(0), op, reference, found, isExecution);
}
break;
@ -1141,7 +1143,7 @@ bool SkiplistIndex::supportsFilterCondition (triagens::aql::AstNode const* node,
double& estimatedCost) const {
std::unordered_map<size_t, std::vector<triagens::aql::AstNode const*>> found;
size_t values = 0;
matchAttributes(node, reference, found, values);
matchAttributes(node, reference, found, values, false);
bool lastContainsEquality = true;
size_t attributesCovered = 0;
@ -1276,7 +1278,7 @@ IndexIterator* SkiplistIndex::iteratorForCondition (IndexIteratorContext* contex
triagens::aql::Ast* ast,
triagens::aql::AstNode const* node,
triagens::aql::Variable const* reference,
bool const reverse) const {
bool reverse) const {
// Create the skiplistOperator for the IndexLookup
if (node == nullptr) {
@ -1295,7 +1297,7 @@ IndexIterator* SkiplistIndex::iteratorForCondition (IndexIteratorContext* contex
}
std::unordered_map<size_t, std::vector<triagens::aql::AstNode const*>> found;
size_t unused = 0;
matchAttributes(node, reference, found, unused);
matchAttributes(node, reference, found, unused, true);
// found contains all attributes that are relevant for this node.
// It might be less than fields().
@ -1537,7 +1539,7 @@ triagens::aql::AstNode* SkiplistIndex::specializeCondition (triagens::aql::AstNo
triagens::aql::Variable const* reference) const {
std::unordered_map<size_t, std::vector<triagens::aql::AstNode const*>> found;
size_t values = 0;
matchAttributes(node, reference, found, values);
matchAttributes(node, reference, found, values, false);
std::vector<triagens::aql::AstNode const*> children;
bool lastContainsEquality = true;

View File

@ -319,7 +319,7 @@ namespace triagens {
triagens::aql::Ast*,
triagens::aql::AstNode const*,
triagens::aql::Variable const*,
bool const) const override;
bool) const override;
triagens::aql::AstNode* specializeCondition (triagens::aql::AstNode*,
triagens::aql::Variable const*) const override;
@ -344,12 +344,14 @@ namespace triagens {
triagens::aql::AstNode const*,
triagens::aql::AstNode const*,
triagens::aql::Variable const*,
std::unordered_map<size_t, std::vector<triagens::aql::AstNode const*>>&) const;
std::unordered_map<size_t, std::vector<triagens::aql::AstNode const*>>&,
bool) const;
void matchAttributes (triagens::aql::AstNode const*,
triagens::aql::Variable const*,
std::unordered_map<size_t, std::vector<triagens::aql::AstNode const*>>&,
size_t&) const;
size_t&,
bool) const;
// -----------------------------------------------------------------------------
// --SECTION-- private variables

View File

@ -98,7 +98,6 @@ namespace triagens {
///
/// This sequence must be used before any non-visible characters in the prompt.
///
/// From readline/display.c:
/// \\001 (^A) start non-visible characters
/// \\002 (^B) end non-visible characters
///

View File

@ -48,7 +48,6 @@ target_link_libraries(
${ICU_LIBS}
${BT_LIBS}
${ZLIB_LIBS}
${READLINE_LIBS}
${OPENSSL_LIBS}
${MSVC_LIBS}
)
@ -98,7 +97,6 @@ target_link_libraries(
${ICU_LIBS}
${BT_LIBS}
${ZLIB_LIBS}
${READLINE_LIBS}
${OPENSSL_LIBS}
${MSVC_LIBS}
)
@ -149,7 +147,6 @@ target_link_libraries(
${ICU_LIBS}
${BT_LIBS}
${ZLIB_LIBS}
${READLINE_LIBS}
${OPENSSL_LIBS}
${MSVC_LIBS}
)
@ -198,7 +195,6 @@ target_link_libraries(
${ICU_LIBS}
${BT_LIBS}
${ZLIB_LIBS}
${READLINE_LIBS}
${OPENSSL_LIBS}
${MSVC_LIBS}
)
@ -251,7 +247,6 @@ target_link_libraries(
${BT_LIBS}
${ICU_LIBS}
${ZLIB_LIBS}
${READLINE_LIBS}
${OPENSSL_LIBS}
${MSVC_LIBS}
)

View File

@ -1548,20 +1548,10 @@ static void RunShell (v8::Isolate* isolate, v8::Handle<v8::Context> context, boo
#ifdef TRI_HAVE_LINENOISE
// linenoise doesn't need escape sequences for escape sequences
// TODO: this should be a function defined in "console"
goodPrompt = TRI_SHELL_COLOR_BOLD_GREEN + dynamicPrompt + TRI_SHELL_COLOR_RESET;
badPrompt = TRI_SHELL_COLOR_BOLD_RED + dynamicPrompt + TRI_SHELL_COLOR_RESET;
#else
// readline does...
goodPrompt = string()
+ ArangoClient::PROMPT_IGNORE_START + TRI_SHELL_COLOR_BOLD_GREEN + ArangoClient::PROMPT_IGNORE_END
+ dynamicPrompt
+ ArangoClient::PROMPT_IGNORE_START + TRI_SHELL_COLOR_RESET + ArangoClient::PROMPT_IGNORE_END;
badPrompt = string()
+ ArangoClient::PROMPT_IGNORE_START + TRI_SHELL_COLOR_BOLD_RED + ArangoClient::PROMPT_IGNORE_END
+ dynamicPrompt
+ ArangoClient::PROMPT_IGNORE_START + TRI_SHELL_COLOR_RESET + ArangoClient::PROMPT_IGNORE_END;
#endif
}
else {

View File

@ -207,168 +207,9 @@ dnl ----------------------------------------------------------------------------
m4_include([m4/external.math])
dnl ----------------------------------------------------------------------------
dnl READLINE
dnl REPL
dnl ----------------------------------------------------------------------------
AC_MSG_NOTICE([--------------------------------------------------------------------------------])
AC_MSG_NOTICE([CHECKING FOR READLINE])
AC_MSG_NOTICE([--------------------------------------------------------------------------------])
AC_LANG(C)
AC_ARG_ENABLE(readline,
AS_HELP_STRING([--enable-readline], [enable readline support (default: yes)]),
tr_READLINE="$enableval",
tr_READLINE="maybe"
)
if test "x$tr_DARWIN" = xyes; then
READLINE=/usr/local/opt/readline
READLINE_CPPFLAGS="-I$READLINE/include"
READLINE_INCLUDE="$READLINE/include"
READLINE_LDFLAGS="-L$READLINE/lib"
READLINE_LIB_PATH="$READLINE/lib"
fi
AC_ARG_WITH(readline,
AS_HELP_STRING([--with-readline=DIR], [where the readline library and includes are located]),
[READLINE_CPPFLAGS="-I$withval/include"
READLINE_INCLUDE="$withval/include"
READLINE_LDFLAGS="-L$withval/lib"
READLINE_LIB_PATH="$withval/lib"
READLINE="$withval"]
)
AC_ARG_WITH(readline-lib,
AS_HELP_STRING([--with-readline-lib=DIR], [where the readline library is located]),
[READLINE_LDFLAGS="-L$withval"
READLINE_LIB_PATH="$withval"]
)
dnl checks for the READLINE library
if test "x$READLINE_CPPFLAGS" != x; then
TR_INCLUDE([READLINE_CPPFLAGS])
fi
dnl save flags
SAVE_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $READLINE_CPPFLAGS"
SAVE_LDFLAGS="$LDFLAGS"
LDFLAGS="$LDFLAGS $READLINE_LDFLAGS"
SAVE_LIBS="$LIBS"
dnl check for header and library
if test "x$tr_READLINE" = xyes -o "x$tr_READLINE" = xmaybe; then
ch_READLINE="$tr_READLINE"
AC_CHECK_HEADERS(readline/readline.h, [tr_READLINE="yes"], [tr_READLINE="no"])
if test "x$tr_READLINE" = xyes; then
AC_CHECK_LIB([readline], [readline], [READLINE_LIBS="-lreadline" tr_READLINE="yes"], [tr_READLINE="no"])
fi
AC_MSG_CHECKING([READLINE support])
if test "x$tr_READLINE" != xyes; then
AC_MSG_RESULT([not found])
if test "x$ch_READLINE" = xyes; then
AC_MSG_ERROR([Please install readline support])
fi
else
AC_MSG_RESULT([readline])
fi
else
AC_MSG_CHECKING([READLINE support])
AC_MSG_RESULT([disabled])
fi
dnl grep readline version number
if test "x$tr_READLINE" = xyes; then
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <readline/readline.h>
main () {
#if defined(RL_VERSION_MAJOR) && defined(RL_VERSION_MINOR)
long sdnhg36ed = RL_VERSION_MAJOR RL_VERSION_MINOR ;
#else
long sdnhg36ed = RL_READLINE_VERSION hex ;
#endif
}
_ACEOF
AC_MSG_CHECKING([READLINE version])
eval "$ac_cpp conftest.$ac_ext" | fgrep "long sdnhg36ed" | awk '{print $4 "." $5}' > conftest.output
READLINE_VERSION=`cat conftest.output`
if test -z "$READLINE_VERSION"; then
AC_MSG_ERROR([Readline support is not working. Please re-install readline support])
fi
AC_MSG_RESULT([$READLINE_VERSION])
rm -f conftest*
if test "x$tr_DARWIN" = xyes; then
case "$READLINE_VERSION" in
6.*|5.*)
;;
*)
AC_MSG_ERROR([Please install readline 6 from brew. If you have a non-standard brew location, use "--with-readline".])
;;
esac
fi
fi
dnl restore flags and set readline flags
LIBS="$SAVE_LIBS"
LDFLAGS="$SAVE_LDFLAGS"
CPPFLAGS="$SAVE_CPPFLAGS"
if test "x$tr_READLINE" = xyes; then
CPPFLAGS="$CPPFLAGS -DHAVE_READLINE=1"
READLINE_CPPFLAGS="${READLINE_CPPFLAGS} -DTRI_READLINE_VERSION='\"${READLINE_VERSION}\"'"
fi
AM_CONDITIONAL(ENABLE_READLINE, test "x$tr_READLINE" = xyes)
if test "x$tr_READLINE" = xyes; then
AC_DEFINE_UNQUOTED(TRI_HAVE_READLINE, 1, [true if readline is used])
fi
dnl add substitutions
AC_SUBST(READLINE_VERSION)
AC_SUBST(READLINE_CPPFLAGS)
AC_SUBST(READLINE_INCLUDE)
AC_SUBST(READLINE_LDFLAGS)
AC_SUBST(READLINE_LIB_PATH)
AC_SUBST(READLINE_LIBS)
dnl informational output
if test "x$tr_READLINE" = xyes; then
LIB_INFO="$LIB_INFO|READLINE VERSION: ${READLINE_VERSION}"
LIB_INFO="$LIB_INFO|READLINE_CPPFLAGS: ${READLINE_CPPFLAGS}"
LIB_INFO="$LIB_INFO|READLINE_LDFLAGS: ${READLINE_LDFLAGS}"
LIB_INFO="$LIB_INFO|READLINE_LIBS: ${READLINE_LIBS}"
else
LIB_INFO="$LIB_INFO|READLINE VERSION: disabled"
fi
LIB_INFO="$LIB_INFO|."
dnl ----------------------------------------------------------------------------
dnl OPENSSL
dnl ----------------------------------------------------------------------------

View File

@ -66,12 +66,6 @@
#undef TRI_ENABLE_FAILURE_TESTS
////////////////////////////////////////////////////////////////////////////////
/// @brief enable readline
////////////////////////////////////////////////////////////////////////////////
#undef TRI_HAVE_READLINE
////////////////////////////////////////////////////////////////////////////////
/// @brief enable linenoise
////////////////////////////////////////////////////////////////////////////////

View File

@ -35,7 +35,6 @@ else ()
Basics/terminal-utils-posix.cpp
Basics/threads-posix.cpp
Rest/EndpointUnixDomain.cpp
Utilities/ReadlineShell.cpp
)
endif ()

View File

@ -97,13 +97,6 @@ lib_libarango_a_SOURCES = \
lib/Zip/unzip.cpp \
lib/Zip/zip.cpp
if ENABLE_READLINE
lib_libarango_a_SOURCES += \
lib/Utilities/ReadlineShell.cpp
endif
################################################################################
### @brief library "libarango.a", client part
################################################################################

View File

@ -79,10 +79,6 @@ void Version::initialize () {
Values["maintainer-mode"] = "false";
#endif
#ifdef TRI_READLINE_VERSION
Values["readline-version"] = getReadlineVersion();
#endif
#ifdef TRI_HAVE_TCMALLOC
Values["tcmalloc"] = "true";
#else
@ -182,19 +178,11 @@ std::string Version::getZLibVersion () {
}
////////////////////////////////////////////////////////////////////////////////
/// @brief get readline version
/// @brief get REPL version
////////////////////////////////////////////////////////////////////////////////
std::string Version::getReadlineVersion () {
#ifdef TRI_READLINE_VERSION
std::string const value(TRI_READLINE_VERSION);
if (value.size() >= 2) {
return value;
}
// fallthrough
#endif
return std::string("unknown version");
std::string Version::getReplVersion () {
return std::string("dummy shell");
}
////////////////////////////////////////////////////////////////////////////////
@ -282,9 +270,7 @@ std::string Version::getVerboseVersionString () {
#endif
<< "ICU " << getICUVersion() << ", "
<< "V8 " << getV8Version() << ", "
#ifdef TRI_READLINE_VERSION
<< "Readline " << getReadlineVersion() << ", "
#endif
<< "REPL " << getReplVersion() << ", "
<< getOpenSSLVersion();
return version.str();

View File

@ -112,10 +112,10 @@ namespace triagens {
static std::string getZLibVersion ();
////////////////////////////////////////////////////////////////////////////////
/// @brief get readline version
/// @brief get repl version
////////////////////////////////////////////////////////////////////////////////
static std::string getReadlineVersion ();
static std::string getReplVersion ();
////////////////////////////////////////////////////////////////////////////////
/// @brief get ICU version

View File

@ -1,382 +0,0 @@
////////////////////////////////////////////////////////////////////////////////
/// @brief line editor using readline
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2014-2015 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 Jan Steemann
/// @author Copyright 2014-2015, ArangoDB GmbH, Cologne, Germany
/// @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#include "ReadlineShell.h"
#include "Basics/tri-strings.h"
#include "Utilities/Completer.h"
#include "Utilities/LineEditor.h"
#include <readline/readline.h>
#include <readline/history.h>
#include <v8.h>
using namespace std;
using namespace triagens;
using namespace arangodb;
// -----------------------------------------------------------------------------
// --SECTION-- private functions
// -----------------------------------------------------------------------------
namespace {
Completer* COMPLETER;
}
static char WordBreakCharacters[] = {
' ', '\t', '\n', '"', '\\', '\'', '`', '@',
'<', '>', '=', ';', '|', '&', '{', '}', '(', ')',
'\0'
};
static char* CompletionGenerator (char const* text, int state) {
static size_t currentIndex;
static vector<string> result;
// compute the possible completion
if (state == 0) {
result = COMPLETER->alternatives(text);
LineEditor::sortAlternatives(result);
}
if (currentIndex < result.size()) {
return TRI_SystemDuplicateString(result[currentIndex++].c_str());
}
currentIndex = 0;
result.clear();
return nullptr;
}
static char** AttemptedCompletion (char const* text, int start, int end) {
char** result = rl_completion_matches(text, CompletionGenerator);
rl_attempted_completion_over = true;
if (result != nullptr && result[0] != nullptr && result[1] == nullptr) {
size_t n = strlen(result[0]);
if (result[0][n - 1] == ')') {
result[0][n - 1] = '\0';
}
}
#if RL_READLINE_VERSION >= 0x0500
// issue #289
rl_completion_suppress_append = 1;
#endif
return result;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief callback function that readline calls periodically while waiting
/// for input and being idle
////////////////////////////////////////////////////////////////////////////////
static int ReadlineIdle () {
auto instance = ReadlineShell::instance();
if (instance != nullptr && instance->getLoopState() == 2) {
rl_done = 1;
}
return 0;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief callback function that readline calls when the input is completed
////////////////////////////////////////////////////////////////////////////////
static void ReadlineInputCompleted (char* value) {
// if we don't clear the prompt here, readline will display it instantly
// the user pressed the return key. this is not desired because when we
// wait for input afterwards, readline will display the prompt again
rl_set_prompt("");
auto instance = ReadlineShell::instance();
if (instance != nullptr) {
if (instance->getLoopState() == 2) {
// CTRL-C received
rl_done = 1;
// replace current input with nothing
rl_replace_line("", 0);
instance->setLastInput("");
}
else if (value == nullptr) {
rl_done = 1;
rl_replace_line("", 0);
instance->setLoopState(3);
instance->setLastInput("");
}
else {
instance->setLoopState(1);
instance->setLastInput(value == 0 ? "" : value);
}
}
if (value != nullptr) {
// avoid memleak
TRI_SystemFree(value);
}
}
// -----------------------------------------------------------------------------
// --SECTION-- class ReadlineShell
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// --SECTION-- private variables
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief (sole) instance of a ReadlineShell
////////////////////////////////////////////////////////////////////////////////
std::atomic<ReadlineShell*> ReadlineShell::_instance(nullptr);
// -----------------------------------------------------------------------------
// --SECTION-- constructors and destructors
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief constructs a new editor
////////////////////////////////////////////////////////////////////////////////
ReadlineShell::ReadlineShell (std::string const& history, Completer* completer)
: ShellImplementation(history, completer),
_loopState(0),
_lastInput(),
_lastInputWasEmpty(false) {
COMPLETER = completer;
rl_initialize();
rl_attempted_completion_function = AttemptedCompletion;
rl_completer_word_break_characters = WordBreakCharacters;
// register ourselves
TRI_ASSERT(_instance == nullptr);
_instance = this;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief destructor
////////////////////////////////////////////////////////////////////////////////
ReadlineShell::~ReadlineShell () {
// unregister ourselves
_instance = nullptr;
}
// -----------------------------------------------------------------------------
// --SECTION-- ShellImplementation methods
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief handle a signal
////////////////////////////////////////////////////////////////////////////////
void ReadlineShell::signal () {
// set the global state, so the readline input loop can react on it
setLoopState(2);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief line editor open
////////////////////////////////////////////////////////////////////////////////
bool ReadlineShell::open (bool autoComplete) {
if (autoComplete) {
// issue #289: do not append a space after completion
rl_completion_append_character = '\0';
// works only in Readline 4.2+
#if RL_READLINE_VERSION >= 0x0500
// enable this to turn on the visual bell - evil!
// rl_variable_bind("prefer-visible-bell", "1");
// use this for single-line editing as in mongodb shell
// rl_variable_bind("horizontal-scroll-mode", "1");
// show matching parentheses
rl_set_paren_blink_timeout(300 * 1000);
rl_variable_bind("blink-matching-paren", "1");
// show selection list when completion is ambiguous. not setting this
// variable will turn the selection list off at least on Ubuntu
rl_variable_bind("show-all-if-ambiguous", "1");
// use readline's built-in page-wise completer
rl_variable_bind("page-completions", "1");
#endif
rl_bind_key('\t', rl_complete);
}
using_history();
//stifle_history(MAX_HISTORY_ENTRIES);
stifle_history(1000);
_state = STATE_OPENED;
return read_history(historyPath().c_str()) == 0;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief line editor shutdown
////////////////////////////////////////////////////////////////////////////////
bool ReadlineShell::close () {
if (_state != STATE_OPENED) {
// avoid duplicate saving of history
return true;
}
_state = STATE_CLOSED;
bool res = writeHistory();
clear_history();
HIST_ENTRY** hist = history_list();
if (hist != nullptr) {
TRI_SystemFree(hist);
}
return res;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief get the history file path
////////////////////////////////////////////////////////////////////////////////
string ReadlineShell::historyPath () {
string path;
if (getenv("HOME")) {
path.append(getenv("HOME"));
path += '/';
}
path.append(_historyFilename);
return path;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief add to history
////////////////////////////////////////////////////////////////////////////////
void ReadlineShell::addHistory (const string& str) {
if (str.empty()) {
return;
}
history_set_pos(history_length - 1);
if (current_history()) {
do {
if (strcmp(current_history()->line, str.c_str()) == 0) {
HIST_ENTRY* e = remove_history(where_history());
if (e != nullptr) {
free_history_entry(e);
}
break;
}
}
while (previous_history());
}
add_history(str.c_str());
}
////////////////////////////////////////////////////////////////////////////////
/// @brief save history
////////////////////////////////////////////////////////////////////////////////
bool ReadlineShell::writeHistory () {
return (write_history(historyPath().c_str()) == 0);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief read a line from the input
////////////////////////////////////////////////////////////////////////////////
string ReadlineShell::getLine (const string& prompt, bool& eof) {
setLoopState(0);
rl_event_hook = ReadlineIdle;
rl_callback_handler_install(prompt.c_str(), ReadlineInputCompleted);
int state;
eof = false;
do {
rl_callback_read_char();
state = getLoopState();
}
while (state == 0);
rl_callback_handler_remove();
if (state == 2) {
setLastInput("");
if (_lastInputWasEmpty) {
eof = true;
}
else {
_lastInputWasEmpty = true;
}
}
else if (state == 3) {
setLastInput("");
eof = true;
_lastInputWasEmpty = false;
}
else {
_lastInputWasEmpty = false;
}
return _lastInput;
}
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------

View File

@ -1,210 +0,0 @@
////////////////////////////////////////////////////////////////////////////////
/// @brief a basis class for concrete implementations for a shell
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2014-2015 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 Esteban Lombeyda
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
/// @author Copyright 2011-2014, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#ifndef ARANGODB_UTILITIES_READLINE_SHELL_H
#define ARANGODB_UTILITIES_READLINE_SHELL_H 1
#include "Utilities/ShellImplementation.h"
#include "Utilities/Completer.h"
namespace arangodb {
// -----------------------------------------------------------------------------
// --SECTION-- class ReadlineShell
// -----------------------------------------------------------------------------
class ReadlineShell : public ShellImplementation {
// -----------------------------------------------------------------------------
// --SECTION-- static public methods
// -----------------------------------------------------------------------------
public:
////////////////////////////////////////////////////////////////////////////////
/// @brief return the currently active shell instance
////////////////////////////////////////////////////////////////////////////////
static ReadlineShell* instance () {
return _instance.load();
}
// -----------------------------------------------------------------------------
// --SECTION-- constructors and destructors
// -----------------------------------------------------------------------------
public:
////////////////////////////////////////////////////////////////////////////////
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
ReadlineShell (std::string const& history, Completer*);
////////////////////////////////////////////////////////////////////////////////
/// @brief destructor
////////////////////////////////////////////////////////////////////////////////
~ReadlineShell ();
// -----------------------------------------------------------------------------
// --SECTION-- ShellImplementation methods
// -----------------------------------------------------------------------------
public:
////////////////////////////////////////////////////////////////////////////////
/// @brief line editor open
////////////////////////////////////////////////////////////////////////////////
bool open (bool autoComplete) override final;
////////////////////////////////////////////////////////////////////////////////
/// @brief line editor shutdown
////////////////////////////////////////////////////////////////////////////////
bool close () override final;
////////////////////////////////////////////////////////////////////////////////
/// @brief get the history file path
///
/// The path is "$HOME" plus _historyFilename, if $HOME is set. Else
/// the local file _historyFilename.
////////////////////////////////////////////////////////////////////////////////
std::string historyPath () override final;
////////////////////////////////////////////////////////////////////////////////
/// @brief add to history
////////////////////////////////////////////////////////////////////////////////
void addHistory (const std::string&) override final;
////////////////////////////////////////////////////////////////////////////////
/// @brief save the history
////////////////////////////////////////////////////////////////////////////////
bool writeHistory () override final;
////////////////////////////////////////////////////////////////////////////////
/// @brief read a line from the input
////////////////////////////////////////////////////////////////////////////////
std::string getLine (const std::string& prompt, bool& eof) override final;
////////////////////////////////////////////////////////////////////////////////
/// @brief handle a signal
////////////////////////////////////////////////////////////////////////////////
void signal () override final;
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not the shell implementation supports colors
////////////////////////////////////////////////////////////////////////////////
bool supportsColors () override final {
return true;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not the shell supports a CTRL-C handler
////////////////////////////////////////////////////////////////////////////////
bool supportsCtrlCHandler () override final {
return true;
}
// -----------------------------------------------------------------------------
// --SECTION-- public methods
// -----------------------------------------------------------------------------
public:
////////////////////////////////////////////////////////////////////////////////
/// @brief set the last input value
////////////////////////////////////////////////////////////////////////////////
void setLastInput (const std::string& input) {
_lastInput = input;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief get the current input loop state
////////////////////////////////////////////////////////////////////////////////
int getLoopState () const {
return _loopState;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief set the current input loop state
////////////////////////////////////////////////////////////////////////////////
void setLoopState (int state) {
_loopState = state;
}
// -----------------------------------------------------------------------------
// --SECTION-- private variables
// -----------------------------------------------------------------------------
private:
////////////////////////////////////////////////////////////////////////////////
/// @brief current state of input loop (may be affected by out-of-band signals)
////////////////////////////////////////////////////////////////////////////////
std::atomic<int> _loopState;
////////////////////////////////////////////////////////////////////////////////
/// @brief last value entered by user.
////////////////////////////////////////////////////////////////////////////////
std::string _lastInput;
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not the input from the previous invocation was a CTRL-C
////////////////////////////////////////////////////////////////////////////////
bool _lastInputWasEmpty;
////////////////////////////////////////////////////////////////////////////////
/// @brief system-wide instance of the ReadlineShell
////////////////////////////////////////////////////////////////////////////////
static std::atomic<ReadlineShell*> _instance;
};
}
#endif
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------

View File

@ -33,8 +33,6 @@
#include "LinenoiseShell.h"
#elif defined TRI_HAVE_LINENOISE
#include "LinenoiseShell.h"
#elif defined TRI_HAVE_READLINE
#include "ReadlineShell.h"
#endif
#include "DummyShell.h"
@ -63,12 +61,9 @@ ShellImplementation* ShellImplFactory::buildShell (std::string const& history,
}
#ifdef _WIN32
// under Windows the readline is not compilable
return new LinenoiseShell(history, completer);
#elif defined TRI_HAVE_LINENOISE
return new LinenoiseShell(history, completer);
#elif defined TRI_HAVE_READLINE
return new ReadlineShell(history, completer);
#else
// last resort!
return new DummyShell(history, completer);
@ -85,12 +80,9 @@ bool ShellImplFactory::hasCtrlCHandler () {
}
#ifdef _WIN32
// under Windows the readline is not compilable
return false;
#elif defined TRI_HAVE_LINENOISE
return false;
#elif defined TRI_HAVE_READLINE
return true;
#else
return false;
#endif