1
0
Fork 0
This commit is contained in:
Jan Steemann 2016-12-07 12:18:18 +01:00
parent 3b4266962a
commit b8c72dece8
9 changed files with 96 additions and 11 deletions

View File

@ -26,6 +26,15 @@ edge attribute `label`.
* process.stdout.isTTY now returns `true` in arangosh and when running arangod with the `--console` flag * process.stdout.isTTY now returns `true` in arangosh and when running arangod with the `--console` flag
v3.1.4 (XXXX-XX-XX)
-------------------
* fixed issue #2211
* fixed issue #2204
v3.1.3 (xxxx-xx-xx) v3.1.3 (xxxx-xx-xx)
------------------- -------------------

View File

@ -598,6 +598,34 @@ describe ArangoDB do
doc.parsed_response['cached'].should eq(false) doc.parsed_response['cached'].should eq(false)
end end
it "calls wrong export API" do
cmd = api
body = "{ \"query\" : \"FOR u IN #{@cn} LIMIT 5 RETURN u.n\", \"count\" : true, \"batchSize\" : 2 }"
doc = ArangoDB.log_post("#{prefix}-create-wrong-api", cmd, :body => body)
doc.code.should eq(201)
doc.headers['content-type'].should eq("application/json; charset=utf-8")
doc.parsed_response['error'].should eq(false)
doc.parsed_response['code'].should eq(201)
doc.parsed_response['id'].should be_kind_of(String)
doc.parsed_response['id'].should match(@reId)
doc.parsed_response['hasMore'].should eq(true)
doc.parsed_response['count'].should eq(5)
doc.parsed_response['result'].length.should eq(2)
doc.parsed_response['cached'].should eq(false)
id = doc.parsed_response['id']
cmd = "/_api/export/#{id}"
doc = ArangoDB.log_put("#{prefix}-create-wrong-api", cmd)
doc.code.should eq(404)
doc.headers['content-type'].should eq("application/json; charset=utf-8")
doc.parsed_response['error'].should eq(true)
doc.parsed_response['code'].should eq(404)
doc.parsed_response['errorNum'].should eq(1600)
end
it "creates a query that survives memory limit constraints" do it "creates a query that survives memory limit constraints" do
cmd = api cmd = api
body = "{ \"query\" : \"FOR i IN 1..10000 SORT i RETURN i\", \"memoryLimit\" : 10000000, \"batchSize\": 10 }" body = "{ \"query\" : \"FOR i IN 1..10000 SORT i RETURN i\", \"memoryLimit\" : 10000000, \"batchSize\": 10 }"

View File

@ -679,6 +679,33 @@ describe ArangoDB do
doc.parsed_response['result'].length.should eq(2000) doc.parsed_response['result'].length.should eq(2000)
end end
it "calls wrong cursor API" do
cmd = api + "?collection=#{@cn}"
body = "{ \"count\" : true, \"batchSize\" : 100, \"flush\" : true }"
doc = ArangoDB.log_post("#{prefix}-limit-return", cmd, :body => body)
doc.code.should eq(201)
doc.headers['content-type'].should eq("application/json; charset=utf-8")
doc.parsed_response['error'].should eq(false)
doc.parsed_response['code'].should eq(201)
doc.parsed_response['id'].should be_kind_of(String)
doc.parsed_response['id'].should match(@reId)
doc.parsed_response['hasMore'].should eq(true)
doc.parsed_response['count'].should eq(2000)
doc.parsed_response['result'].length.should eq(100)
id = doc.parsed_response['id']
# intentionally wrong
cmd = "/_api/cursor/#{id}"
doc = ArangoDB.log_put("#{prefix}-return-cont", cmd)
doc.code.should eq(404)
doc.headers['content-type'].should eq("application/json; charset=utf-8")
doc.parsed_response['error'].should eq(true)
doc.parsed_response['code'].should eq(404)
doc.parsed_response['errorNum'].should eq(1600)
end
end end
################################################################################ ################################################################################

View File

@ -447,7 +447,7 @@ void RestCursorHandler::modifyCursor() {
auto cursorId = static_cast<arangodb::CursorId>( auto cursorId = static_cast<arangodb::CursorId>(
arangodb::basics::StringUtils::uint64(id)); arangodb::basics::StringUtils::uint64(id));
bool busy; bool busy;
auto cursor = cursors->find(cursorId, busy); auto cursor = cursors->find(cursorId, Cursor::CURSOR_VPACK, busy);
if (cursor == nullptr) { if (cursor == nullptr) {
if (busy) { if (busy) {
@ -499,7 +499,7 @@ void RestCursorHandler::deleteCursor() {
auto cursorId = static_cast<arangodb::CursorId>( auto cursorId = static_cast<arangodb::CursorId>(
arangodb::basics::StringUtils::uint64(id)); arangodb::basics::StringUtils::uint64(id));
bool found = cursors->remove(cursorId); bool found = cursors->remove(cursorId, Cursor::CURSOR_VPACK);
if (!found) { if (!found) {
generateError(rest::ResponseCode::NOT_FOUND, TRI_ERROR_CURSOR_NOT_FOUND); generateError(rest::ResponseCode::NOT_FOUND, TRI_ERROR_CURSOR_NOT_FOUND);

View File

@ -306,7 +306,7 @@ void RestExportHandler::modifyCursor() {
auto cursorId = static_cast<arangodb::CursorId>( auto cursorId = static_cast<arangodb::CursorId>(
arangodb::basics::StringUtils::uint64(id)); arangodb::basics::StringUtils::uint64(id));
bool busy; bool busy;
auto cursor = cursors->find(cursorId, busy); auto cursor = cursors->find(cursorId, Cursor::CURSOR_EXPORT, busy);
if (cursor == nullptr) { if (cursor == nullptr) {
if (busy) { if (busy) {
@ -356,7 +356,7 @@ void RestExportHandler::deleteCursor() {
auto cursorId = static_cast<arangodb::CursorId>( auto cursorId = static_cast<arangodb::CursorId>(
arangodb::basics::StringUtils::uint64(id)); arangodb::basics::StringUtils::uint64(id));
bool found = cursors->remove(cursorId); bool found = cursors->remove(cursorId, Cursor::CURSOR_EXPORT);
if (!found) { if (!found) {
generateError(rest::ResponseCode::NOT_FOUND, TRI_ERROR_CURSOR_NOT_FOUND); generateError(rest::ResponseCode::NOT_FOUND, TRI_ERROR_CURSOR_NOT_FOUND);

View File

@ -44,6 +44,11 @@ typedef TRI_voc_tick_t CursorId;
class Cursor { class Cursor {
public: public:
enum CursorType {
CURSOR_VPACK,
CURSOR_EXPORT
};
Cursor(Cursor const&) = delete; Cursor(Cursor const&) = delete;
Cursor& operator=(Cursor const&) = delete; Cursor& operator=(Cursor const&) = delete;
@ -90,6 +95,8 @@ class Cursor {
_isUsed = false; _isUsed = false;
} }
virtual CursorType type() const = 0;
virtual bool hasNext() = 0; virtual bool hasNext() = 0;
virtual arangodb::velocypack::Slice next() = 0; virtual arangodb::velocypack::Slice next() = 0;
@ -110,7 +117,7 @@ class Cursor {
bool _isUsed; bool _isUsed;
}; };
class VelocyPackCursor : public Cursor { class VelocyPackCursor final : public Cursor {
public: public:
VelocyPackCursor(TRI_vocbase_t*, CursorId, aql::QueryResult&&, size_t, VelocyPackCursor(TRI_vocbase_t*, CursorId, aql::QueryResult&&, size_t,
std::shared_ptr<arangodb::velocypack::Builder>, double, std::shared_ptr<arangodb::velocypack::Builder>, double,
@ -121,6 +128,8 @@ class VelocyPackCursor : public Cursor {
public: public:
aql::QueryResult const* result() const { return &_result; } aql::QueryResult const* result() const { return &_result; }
CursorType type() const override final { return CURSOR_VPACK; }
bool hasNext() override final; bool hasNext() override final;
arangodb::velocypack::Slice next() override final; arangodb::velocypack::Slice next() override final;
@ -136,7 +145,7 @@ class VelocyPackCursor : public Cursor {
bool _cached; bool _cached;
}; };
class ExportCursor : public Cursor { class ExportCursor final : public Cursor {
public: public:
ExportCursor(TRI_vocbase_t*, CursorId, arangodb::CollectionExport*, size_t, ExportCursor(TRI_vocbase_t*, CursorId, arangodb::CollectionExport*, size_t,
double, bool); double, bool);
@ -144,6 +153,8 @@ class ExportCursor : public Cursor {
~ExportCursor(); ~ExportCursor();
public: public:
CursorType type() const override final { return CURSOR_EXPORT; }
bool hasNext() override final; bool hasNext() override final;
arangodb::velocypack::Slice next() override final; arangodb::velocypack::Slice next() override final;

View File

@ -140,7 +140,7 @@ ExportCursor* CursorRepository::createFromExport(arangodb::CollectionExport* ex,
/// @brief remove a cursor by id /// @brief remove a cursor by id
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool CursorRepository::remove(CursorId id) { bool CursorRepository::remove(CursorId id, Cursor::CursorType type) {
arangodb::Cursor* cursor = nullptr; arangodb::Cursor* cursor = nullptr;
{ {
@ -159,6 +159,11 @@ bool CursorRepository::remove(CursorId id) {
return false; return false;
} }
if (cursor->type() != type) {
// wrong type
return false;
}
if (cursor->isUsed()) { if (cursor->isUsed()) {
// cursor is in use by someone else. now mark as deleted // cursor is in use by someone else. now mark as deleted
cursor->deleted(); cursor->deleted();
@ -181,7 +186,7 @@ bool CursorRepository::remove(CursorId id) {
/// it must be returned later using release() /// it must be returned later using release()
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
Cursor* CursorRepository::find(CursorId id, bool& busy) { Cursor* CursorRepository::find(CursorId id, Cursor::CursorType type, bool& busy) {
arangodb::Cursor* cursor = nullptr; arangodb::Cursor* cursor = nullptr;
busy = false; busy = false;
@ -201,6 +206,11 @@ Cursor* CursorRepository::find(CursorId id, bool& busy) {
return nullptr; return nullptr;
} }
if (cursor->type() != type) {
// wrong cursor type
return nullptr;
}
if (cursor->isUsed()) { if (cursor->isUsed()) {
busy = true; busy = true;
return nullptr; return nullptr;

View File

@ -79,7 +79,7 @@ class CursorRepository {
/// @brief remove a cursor by id /// @brief remove a cursor by id
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
bool remove(CursorId); bool remove(CursorId, Cursor::CursorType);
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
/// @brief find an existing cursor by id /// @brief find an existing cursor by id
@ -87,7 +87,7 @@ class CursorRepository {
/// it must be returned later using release() /// it must be returned later using release()
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
Cursor* find(CursorId, bool&); Cursor* find(CursorId, Cursor::CursorType, bool&);
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
/// @brief return a cursor /// @brief return a cursor

View File

@ -137,7 +137,7 @@ static void JS_JsonCursor(v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_ASSERT(cursors != nullptr); TRI_ASSERT(cursors != nullptr);
bool busy; bool busy;
auto cursor = cursors->find(cursorId, busy); auto cursor = cursors->find(cursorId, Cursor::CURSOR_VPACK, busy);
if (cursor == nullptr) { if (cursor == nullptr) {
if (busy) { if (busy) {