diff --git a/.gitignore b/.gitignore index 8697fe7942..5470731d3e 100644 --- a/.gitignore +++ b/.gitignore @@ -71,3 +71,4 @@ UnitTests/Philadelphia/Runner.cpp UnitTests/test_suite .v8-build VC++ +UnitTests/RestDocuments/*.log diff --git a/Doxygen/Examples.AvocadoDB/rest_create-document-bad-json b/Doxygen/Examples.AvocadoDB/rest_create-document-bad-json new file mode 100644 index 0000000000..bbff044a5e --- /dev/null +++ b/Doxygen/Examples.AvocadoDB/rest_create-document-bad-json @@ -0,0 +1,12 @@ +> curl --data @- -X POST --dump - http://localhost:8529/document?collection=173347 +{ 1 : 2 } + +HTTP/1.1 400 Bad Request +content-type: application/json; charset=utf-8 + +{ + "errorMessage": "expecting attribute name", + "errorNum": 502, + "code": 400, + "error": true +} diff --git a/Doxygen/Examples.AvocadoDB/rest_read-document b/Doxygen/Examples.AvocadoDB/rest_read-document new file mode 100644 index 0000000000..df36f91046 --- /dev/null +++ b/Doxygen/Examples.AvocadoDB/rest_read-document @@ -0,0 +1,11 @@ +> curl -X GET --dump - http://localhost:8529/document/161039/11108289 + +HTTP/1.1 200 OK +content-type: application/json; charset=utf-8 +etag: "11108289" + +{ + "_rev": 11108289, + "_id": "161039/11108289", + "Hallo": "World" +} diff --git a/Doxygen/Examples.AvocadoDB/rest_read-document-if-none-match b/Doxygen/Examples.AvocadoDB/rest_read-document-if-none-match new file mode 100644 index 0000000000..c7ca1e8085 --- /dev/null +++ b/Doxygen/Examples.AvocadoDB/rest_read-document-if-none-match @@ -0,0 +1,5 @@ +> curl -X GET --dump - http://localhost:8529/document/161039/11173825 + +HTTP/1.1 304 Not Modified +content-type: text/plain;charset=utf-8 +etag: "11173825" diff --git a/Doxygen/Examples.AvocadoDB/rest_read-document-unknown-handle b/Doxygen/Examples.AvocadoDB/rest_read-document-unknown-handle new file mode 100644 index 0000000000..718347da05 --- /dev/null +++ b/Doxygen/Examples.AvocadoDB/rest_read-document-unknown-handle @@ -0,0 +1,11 @@ +> curl -X GET --dump - http://localhost:8529/document/161039/234567 + +HTTP/1.1 404 Not Found +content-type: application/json; charset=utf-8 + +{ + "errorMessage": "document /document/161039 not found", + "errorNum": 1200, + "code": 404, + "error": true +} diff --git a/Rest/HttpResponse.cpp b/Rest/HttpResponse.cpp index 12ec8bdcf0..89c8b86848 100644 --- a/Rest/HttpResponse.cpp +++ b/Rest/HttpResponse.cpp @@ -64,6 +64,7 @@ namespace triagens { case NOT_FOUND: return "404 Not Found"; case METHOD_NOT_ALLOWED: return "405 Method"; case CONFLICT: return "409 Conflict"; + case PRECONDITION_FAILED: return "412 Precondition Failed"; case UNPROCESSABLE_ENTITY: return "422 Unprocessable Entity"; case SERVER_ERROR: return "500 Internal Error"; @@ -101,6 +102,7 @@ namespace triagens { case 404: return NOT_FOUND; case 405: return METHOD_NOT_ALLOWED; case 409: return CONFLICT; + case 412: return PRECONDITION_FAILED; case 422: return UNPROCESSABLE_ENTITY; case 500: return SERVER_ERROR; diff --git a/Rest/HttpResponse.h b/Rest/HttpResponse.h index 55ba9af1ec..143b26e82e 100644 --- a/Rest/HttpResponse.h +++ b/Rest/HttpResponse.h @@ -115,6 +115,7 @@ namespace triagens { NOT_FOUND = 404, METHOD_NOT_ALLOWED = 405, CONFLICT = 409, + PRECONDITION_FAILED = 412, UNPROCESSABLE_ENTITY = 422, SERVER_ERROR = 500, diff --git a/RestHandler/RestDocumentHandler.cpp b/RestHandler/RestDocumentHandler.cpp index 35084a4ab7..75678f3ba4 100644 --- a/RestHandler/RestDocumentHandler.cpp +++ b/RestHandler/RestDocumentHandler.cpp @@ -194,7 +194,7 @@ HttpHandler::status_e RestDocumentHandler::execute () { /// /// @verbinclude rest_create-document /// -/// Create a document in collection where @LIT{waitForSync} is @LIT{false}. +/// Create a document in a collection where @LIT{waitForSync} is @LIT{false}. /// /// @verbinclude rest_create-document-accept /// @@ -208,15 +208,11 @@ HttpHandler::status_e RestDocumentHandler::execute () { /// /// Unknown collection identifier: /// -/// @verbinclude rest4 +/// @verbinclude rest_create-document-unknown-cid /// /// Illegal document: /// -/// @verbinclude rest5 -/// -/// Create a document given a collection name: -/// -/// @verbinclude rest6 +/// @verbinclude rest_create-document-bad-json //////////////////////////////////////////////////////////////////////////////// bool RestDocumentHandler::createDocument () { @@ -315,19 +311,19 @@ bool RestDocumentHandler::createDocument () { //////////////////////////////////////////////////////////////////////////////// bool RestDocumentHandler::readDocument () { -#ifdef FIXME switch (request->suffix().size()) { case 0: return readAllDocuments(); - case 1: + case 2: return readSingleDocument(true); default: - generateError(HttpResponse::BAD, "expecting URI /document/"); + generateError(HttpResponse::BAD, + TRI_REST_ERROR_SUPERFLUOUS_SUFFICES, + "expecting GET /document/"); return false; } -#endif } //////////////////////////////////////////////////////////////////////////////// @@ -345,41 +341,45 @@ bool RestDocumentHandler::readDocument () { /// If the @FA{document-handle} points to a non-existing document, then a /// @LIT{HTTP 404} is returned and the body contains an error document. /// +/// If the "If-None-Match" header is given, then it must contain exactly one +/// etag. The document is returned, if it has a different revision than the +/// given etag. Otherwise a @LIT{HTTP 304} is returned. +/// +/// If the "If-Match" header is given, then it must contain exactly one +/// etag. The document is returned, if it has the same revision ad the +/// given etag. Otherwise a @LIT{HTTP 412} is returned. +/// /// @EXAMPLES /// -/// Use a collection and document identfier: +/// Use a document handle: /// -/// @verbinclude rest1 +/// @verbinclude rest_read-document /// -/// Use a collection name and document reference: +/// Use a document handle and an etag: /// -/// @verbinclude rest18 +/// @verbinclude rest_read-document-if-none-match /// -/// Unknown document identifier: +/// Unknown document handle: /// -/// @verbinclude rest2 -/// -/// Unknown collection identifier: -/// -/// @verbinclude rest17 +/// @verbinclude rest_read-document-unknown-handle //////////////////////////////////////////////////////////////////////////////// bool RestDocumentHandler::readSingleDocument (bool generateBody) { -#ifdef FIXME vector const& suffix = request->suffix(); + /// check for an etag + string ifNoneMatch = request->header("if-none-match"); + TRI_voc_rid_t ifNoneRid = parseEtag(ifNoneMatch); + + string ifMatch = request->header("if-match"); + TRI_voc_rid_t ifRid = parseEtag(ifMatch); + // split the document reference - string cid; - string did; - - bool ok = splitDocumentReference(suffix[0], cid, did); - - if (! ok) { - return false; - } + string cid = suffix[0]; + string did = suffix[1]; // find and load collection given by name oder identifier - ok = findCollection(cid) && loadCollection(); + bool ok = findCollection(cid) && loadCollection(); if (! ok) { return false; @@ -391,6 +391,7 @@ bool RestDocumentHandler::readSingleDocument (bool generateBody) { _documentCollection->beginRead(_documentCollection); + // FIXME FIXME TRI_doc_mptr_t const* document = findDocument(did); _documentCollection->endRead(_documentCollection); @@ -404,8 +405,42 @@ bool RestDocumentHandler::readSingleDocument (bool generateBody) { return false; } - generateDocument(document, generateBody); -#endif + TRI_voc_rid_t rid = document->_rid; + + if (ifNoneRid == 0) { + if (ifRid == 0) { + generateDocument(document, generateBody); + } + else if (ifRid == rid) { + generateDocument(document, generateBody); + } + else { + generatePreconditionFailed(); + } + } + else if (ifNoneRid == rid) { + if (ifRid == 0) { + generateNotModified(StringUtils::itoa(rid)); + } + else if (ifRid == rid) { + generateNotModified(StringUtils::itoa(rid)); + } + else { + generatePreconditionFailed(); + } + } + else { + if (ifRid == 0) { + generateDocument(document, generateBody); + } + else if (ifRid == rid) { + generateDocument(document, generateBody); + } + else { + generatePreconditionFailed(); + } + } + return true; } diff --git a/RestHandler/RestVocbaseBaseHandler.cpp b/RestHandler/RestVocbaseBaseHandler.cpp index 5bba395107..578356c017 100644 --- a/RestHandler/RestVocbaseBaseHandler.cpp +++ b/RestHandler/RestVocbaseBaseHandler.cpp @@ -240,6 +240,24 @@ void RestVocbaseBaseHandler::generateNotImplemented (string const& path) { "'" + path + "' not implemented"); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief generates precondition failed +//////////////////////////////////////////////////////////////////////////////// + +void RestVocbaseBaseHandler::generatePreconditionFailed () { + response = new HttpResponse(HttpResponse::PRECONDITION_FAILED); +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief generates not modified +//////////////////////////////////////////////////////////////////////////////// + +void RestVocbaseBaseHandler::generateNotModified (string const& etag) { + response = new HttpResponse(HttpResponse::NOT_MODIFIED); + + response->setHeader("ETag", "\"" + etag + "\""); +} + //////////////////////////////////////////////////////////////////////////////// /// @brief generates next entry from a result set //////////////////////////////////////////////////////////////////////////////// @@ -301,26 +319,6 @@ void RestVocbaseBaseHandler::generateDocument (TRI_doc_mptr_t const* document, } } -//////////////////////////////////////////////////////////////////////////////// -/// @brief splits a document reference into to parts -//////////////////////////////////////////////////////////////////////////////// - -bool RestVocbaseBaseHandler::splitDocumentReference (string const& name, string& cid, string& did) { - vector doc = StringUtils::split(name, TRI_DOCUMENT_HANDLE_SEPARATOR_STR); - - if (doc.size() != 2) { - generateError(HttpResponse::BAD, - TRI_VOC_ERROR_DOCUMENT_HANDLE_BAD, - "missing or illegal document handle"); - return false; - } - - cid = doc[0]; - did = doc[1]; - - return true; -} - //////////////////////////////////////////////////////////////////////////////// /// @brief extracts the revision //////////////////////////////////////////////////////////////////////////////// @@ -539,6 +537,21 @@ TRI_doc_mptr_t const* RestVocbaseBaseHandler::findDocument (string const& doc) { return document; } +//////////////////////////////////////////////////////////////////////////////// +/// @brief converts an etag field +//////////////////////////////////////////////////////////////////////////////// + +TRI_voc_rid_t RestVocbaseBaseHandler::parseEtag (string const& etag) { + string trim = StringUtils::trim(etag); + size_t len = trim.size(); + + if (len < 2 || trim[0] != '"' || trim[len-1] != '"') { + return 0; + } + + return StringUtils::int64(trim.substr(1, len-2)); +} + //////////////////////////////////////////////////////////////////////////////// /// @} //////////////////////////////////////////////////////////////////////////////// diff --git a/RestHandler/RestVocbaseBaseHandler.h b/RestHandler/RestVocbaseBaseHandler.h index 26c3d75d65..d136e789c4 100644 --- a/RestHandler/RestVocbaseBaseHandler.h +++ b/RestHandler/RestVocbaseBaseHandler.h @@ -252,18 +252,24 @@ namespace triagens { void generateNotImplemented (string const& path); +//////////////////////////////////////////////////////////////////////////////// +/// @brief generates precondition failed +//////////////////////////////////////////////////////////////////////////////// + + void generatePreconditionFailed (); + +//////////////////////////////////////////////////////////////////////////////// +/// @brief generates not modified +//////////////////////////////////////////////////////////////////////////////// + + void generateNotModified (string const& etag); + //////////////////////////////////////////////////////////////////////////////// /// @brief generates first entry from a result set //////////////////////////////////////////////////////////////////////////////// void generateDocument (TRI_doc_mptr_t const*, bool generateBody); -//////////////////////////////////////////////////////////////////////////////// -/// @brief splits a document reference into to parts -//////////////////////////////////////////////////////////////////////////////// - - bool splitDocumentReference (string const& name, string& cid, string& did); - //////////////////////////////////////////////////////////////////////////////// /// @brief extracts the revision //////////////////////////////////////////////////////////////////////////////// @@ -300,6 +306,12 @@ namespace triagens { TRI_doc_mptr_t const* findDocument (string const& doc); +//////////////////////////////////////////////////////////////////////////////// +/// @brief converts an etag field +//////////////////////////////////////////////////////////////////////////////// + + TRI_voc_rid_t parseEtag (string const& etag); + //////////////////////////////////////////////////////////////////////////////// /// @} //////////////////////////////////////////////////////////////////////////////// diff --git a/UnitTests/RestDocuments/avocadodb.rb b/UnitTests/RestDocuments/avocadodb.rb index 237d413392..bd74aaef00 100644 --- a/UnitTests/RestDocuments/avocadodb.rb +++ b/UnitTests/RestDocuments/avocadodb.rb @@ -26,7 +26,11 @@ class AvocadoDB end def self.log (args) - logfile = File.new("output.log", "a") + if args.key?(:output) + logfile = File.new("#{args[:output]}.log", "a") + else + logfile = File.new("output.log", "a") + end method = args[:method] || :get url = args[:url] @@ -37,7 +41,8 @@ class AvocadoDB logfile.puts '-' * 80 if method == :get - logfile.puts "MISSING" + logfile.puts "> curl -X GET --dump - http://localhost:8529#{url}" + logfile.puts elsif method == :post if body == nil logfile.puts "> curl -X POST --dump - http://localhost:8529#{url}" diff --git a/UnitTests/RestDocuments/rest_document_spec.rb b/UnitTests/RestDocuments/rest_create-document_spec.rb similarity index 91% rename from UnitTests/RestDocuments/rest_document_spec.rb rename to UnitTests/RestDocuments/rest_create-document_spec.rb index 11378ff1b0..ef99460399 100644 --- a/UnitTests/RestDocuments/rest_document_spec.rb +++ b/UnitTests/RestDocuments/rest_create-document_spec.rb @@ -19,7 +19,7 @@ describe AvocadoDB do doc.parsed_response['code'].should eq(400) doc.headers['content-type'].should eq("application/json; charset=utf-8") - AvocadoDB.log(:method => :post, :url => cmd, :result => doc) + AvocadoDB.log(:method => :post, :url => cmd, :result => doc, :output => "rest_create-document-missing-cid") end it "returns an error if url contains a suffix" do @@ -32,7 +32,7 @@ describe AvocadoDB do doc.parsed_response['code'].should eq(400) doc.headers['content-type'].should eq("application/json; charset=utf-8") - AvocadoDB.log(:method => :post, :url => cmd, :result => doc) + AvocadoDB.log(:method => :post, :url => cmd, :result => doc, :output => "rest_create.document-superfluous-suffix") end it "returns an error if the collection identifier is unknown" do @@ -45,7 +45,7 @@ describe AvocadoDB do doc.parsed_response['code'].should eq(404) doc.headers['content-type'].should eq("application/json; charset=utf-8") - AvocadoDB.log(:method => :post, :url => cmd, :result => doc) + AvocadoDB.log(:method => :post, :url => cmd, :result => doc, :output => "rest_create-document-unknown-cid") end it "returns an error if the collection name is unknown" do @@ -58,7 +58,7 @@ describe AvocadoDB do doc.parsed_response['code'].should eq(404) doc.headers['content-type'].should eq("application/json; charset=utf-8") - AvocadoDB.log(:method => :post, :url => cmd, :result => doc) + AvocadoDB.log(:method => :post, :url => cmd, :result => doc, :output => "rest_create-document-unknown-name") end it "returns an error if the JSON body is corrupted" do @@ -77,7 +77,7 @@ describe AvocadoDB do doc.parsed_response['code'].should eq(400) doc.headers['content-type'].should eq("application/json; charset=utf-8") - AvocadoDB.log(:method => :post, :url => cmd, :body => body, :result => doc) + AvocadoDB.log(:method => :post, :url => cmd, :body => body, :result => doc, :output => "rest_create-document-bad-json") AvocadoDB.drop_collection("UnitTestsCollectionBasics") end end @@ -124,7 +124,7 @@ describe AvocadoDB do etag.should eq("\"#{rev}\"") location.should eq("/document/#{did}") - AvocadoDB.log(:method => :post, :url => cmd, :body => body, :result => doc) + AvocadoDB.log(:method => :post, :url => cmd, :body => body, :result => doc, :output => "rest_create-document") AvocadoDB.delete(location) end @@ -172,7 +172,7 @@ describe AvocadoDB do etag.should eq("\"#{rev}\"") location.should eq("/document/#{did}") - AvocadoDB.log(:method => :post, :url => cmd, :body => body, :result => doc) + AvocadoDB.log(:method => :post, :url => cmd, :body => body, :result => doc, :output => "rest_create-document-accept") AvocadoDB.delete(location) end @@ -220,7 +220,7 @@ describe AvocadoDB do etag.should eq("\"#{rev}\"") location.should eq("/document/#{did}") - AvocadoDB.log(:method => :post, :url => cmd, :body => body, :result => doc) + AvocadoDB.log(:method => :post, :url => cmd, :body => body, :result => doc, :output => "rest_create-document-new-named-collection") AvocadoDB.delete(location) end @@ -277,7 +277,7 @@ describe AvocadoDB do etag.should eq("\"#{rev}\"") location.should eq("/document/#{did}") - AvocadoDB.log(:method => :post, :url => cmd, :body => body, :result => doc) + AvocadoDB.log(:method => :post, :url => cmd, :body => body, :result => doc, :output => "rest_create-document-create-collection") AvocadoDB.delete(location) end diff --git a/UnitTests/RestDocuments/rest_read-document_spec.rb b/UnitTests/RestDocuments/rest_read-document_spec.rb new file mode 100644 index 0000000000..af3a9a84f3 --- /dev/null +++ b/UnitTests/RestDocuments/rest_read-document_spec.rb @@ -0,0 +1,201 @@ +require 'rspec' +require './avocadodb.rb' + +describe AvocadoDB do + context "reading a document in a collection" do + +################################################################################ +## error handling +################################################################################ + + context "error handling" do + before do + @cn = "UnitTestsCollectionBasics" + @cid = AvocadoDB.create_collection(@cn) + end + + after do + AvocadoDB.drop_collection(@cn) + end + + it "returns an error if document handle is corrupted" do + cmd = "/document/123456" + doc = AvocadoDB.get(cmd) + + doc.code.should eq(400) + doc.parsed_response['error'].should eq(true) + doc.parsed_response['errorNum'].should eq(503) + doc.parsed_response['code'].should eq(400) + doc.headers['content-type'].should eq("application/json; charset=utf-8") + + AvocadoDB.log(:method => :get, :url => cmd, :result => doc, :output => "rest_read-document-bad-handle") + end + + it "returns an error if collection identifier is unknown" do + cmd = "/document/123456/234567" + doc = AvocadoDB.get(cmd) + + doc.code.should eq(404) + doc.parsed_response['error'].should eq(true) + doc.parsed_response['errorNum'].should eq(1201) + doc.parsed_response['code'].should eq(404) + doc.headers['content-type'].should eq("application/json; charset=utf-8") + + AvocadoDB.log(:method => :get, :url => cmd, :result => doc, :output => "rest_read-document-unknown-cid") + end + + it "returns an error if document handle is unknown" do + cmd = "/document/#{@cid}/234567" + doc = AvocadoDB.get(cmd) + + doc.code.should eq(404) + doc.parsed_response['error'].should eq(true) + doc.parsed_response['errorNum'].should eq(1200) + doc.parsed_response['code'].should eq(404) + doc.headers['content-type'].should eq("application/json; charset=utf-8") + + AvocadoDB.log(:method => :get, :url => cmd, :result => doc, :output => "rest_read-document-unknown-handle") + end + end + +################################################################################ +## reading documents +################################################################################ + + context "reading documents" do + before do + @cn = "UnitTestsCollectionBasics" + @cid = AvocadoDB.create_collection(@cn) + end + + after do + AvocadoDB.drop_collection(@cn) + end + + it "create a document and read it" do + cmd = "/document?collection=#{@cid}" + body = "{ \"Hallo\" : \"World\" }" + doc = AvocadoDB.post(cmd, :body => body) + + doc.code.should eq(201) + + location = doc.headers['location'] + location.should be_kind_of(String) + + did = doc.parsed_response['_id'] + rev = doc.parsed_response['_rev'] + + # get document + cmd = "/document/#{did}" + doc = AvocadoDB.get(cmd) + + doc.code.should eq(200) + doc.headers['content-type'].should eq("application/json; charset=utf-8") + + did2 = doc.parsed_response['_id'] + did2.should be_kind_of(String) + did2.should eq(did) + + rev2 = doc.parsed_response['_rev'] + rev2.should be_kind_of(Integer) + rev2.should eq(rev) + + etag = doc.headers['etag'] + etag.should be_kind_of(String) + + etag.should eq("\"#{rev}\"") + + AvocadoDB.log(:method => :get, :url => cmd, :result => doc, :output => "rest_read-document") + + AvocadoDB.delete(location) + end + + it "create a document and read it, use if-none-match" do + cmd = "/document?collection=#{@cid}" + body = "{ \"Hallo\" : \"World\" }" + doc = AvocadoDB.post(cmd, :body => body) + + doc.code.should eq(201) + + location = doc.headers['location'] + location.should be_kind_of(String) + + did = doc.parsed_response['_id'] + rev = doc.parsed_response['_rev'] + + # get document, if-none-match with same rev + cmd = "/document/#{did}" + doc = AvocadoDB.get(cmd, :headers => { "if-none-match" => "\"#{rev}\"" }) + + doc.code.should eq(304) + + etag = doc.headers['etag'] + etag.should be_kind_of(String) + + etag.should eq("\"#{rev}\"") + + AvocadoDB.log(:method => :get, :url => cmd, :result => doc, :output => "rest_read-document-if-none-match") + + # get document, if-none-match with different rev + cmd = "/document/#{did}" + doc = AvocadoDB.get(cmd, :headers => { "if-none-match" => "\"#{rev-1}\"" }) + + doc.code.should eq(200) + doc.headers['content-type'].should eq("application/json; charset=utf-8") + + etag = doc.headers['etag'] + etag.should be_kind_of(String) + + etag.should eq("\"#{rev}\"") + + did2 = doc.parsed_response['_id'] + did2.should be_kind_of(String) + did2.should eq(did) + + rev2 = doc.parsed_response['_rev'] + rev2.should be_kind_of(Integer) + rev2.should eq(rev) + + etag = doc.headers['etag'] + etag.should be_kind_of(String) + + etag.should eq("\"#{rev}\"") + + AvocadoDB.log(:method => :get, :url => cmd, :result => doc, :output => "rest_read-document-if-none-match-other") + + # get document, if-match with same rev + cmd = "/document/#{did}" + doc = AvocadoDB.get(cmd, :headers => { "if-match" => "\"#{rev}\"" }) + + doc.code.should eq(200) + doc.headers['content-type'].should eq("application/json; charset=utf-8") + + did2 = doc.parsed_response['_id'] + did2.should be_kind_of(String) + did2.should eq(did) + + rev2 = doc.parsed_response['_rev'] + rev2.should be_kind_of(Integer) + rev2.should eq(rev) + + etag = doc.headers['etag'] + etag.should be_kind_of(String) + + etag.should eq("\"#{rev}\"") + + AvocadoDB.log(:method => :get, :url => cmd, :result => doc, :output => "rest_read-document-if-match") + + # get document, if-match with different rev + cmd = "/document/#{did}" + doc = AvocadoDB.get(cmd, :headers => { "if-match" => "\"#{rev-1}\"" }) + + doc.code.should eq(412) + + AvocadoDB.log(:method => :get, :url => cmd, :result => doc, :output => "rest_read-document-if-match-other") + + AvocadoDB.delete(location) + end + end + + end +end diff --git a/V8/v8-vocbase.cpp b/V8/v8-vocbase.cpp index 528710add9..a0b9abc728 100644 --- a/V8/v8-vocbase.cpp +++ b/V8/v8-vocbase.cpp @@ -1316,15 +1316,6 @@ static v8::Handle JS_WithinQuery (v8::Arguments const& argv) { return scope.Close(result); } -//////////////////////////////////////////////////////////////////////////////// -/// @} -//////////////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////////////// -/// @addtogroup VocBase -/// @{ -//////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// /// @brief get a (persistent) cursor by its id //////////////////////////////////////////////////////////////////////////////// @@ -1358,6 +1349,10 @@ static v8::Handle JS_Cursor (v8::Arguments const& argv) { return scope.Close(WrapQueryCursor(cursor)); } +//////////////////////////////////////////////////////////////////////////////// +/// @} +//////////////////////////////////////////////////////////////////////////////// + // ----------------------------------------------------------------------------- // --SECTION-- AVOCADO QUERY LANGUAGE // -----------------------------------------------------------------------------