mirror of https://gitee.com/bigwinds/arangodb
fixed read
This commit is contained in:
parent
d4303479a8
commit
d13c6813d0
|
@ -71,3 +71,4 @@ UnitTests/Philadelphia/Runner.cpp
|
||||||
UnitTests/test_suite
|
UnitTests/test_suite
|
||||||
.v8-build
|
.v8-build
|
||||||
VC++
|
VC++
|
||||||
|
UnitTests/RestDocuments/*.log
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -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"
|
||||||
|
}
|
|
@ -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"
|
|
@ -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
|
||||||
|
}
|
|
@ -64,6 +64,7 @@ namespace triagens {
|
||||||
case NOT_FOUND: return "404 Not Found";
|
case NOT_FOUND: return "404 Not Found";
|
||||||
case METHOD_NOT_ALLOWED: return "405 Method";
|
case METHOD_NOT_ALLOWED: return "405 Method";
|
||||||
case CONFLICT: return "409 Conflict";
|
case CONFLICT: return "409 Conflict";
|
||||||
|
case PRECONDITION_FAILED: return "412 Precondition Failed";
|
||||||
case UNPROCESSABLE_ENTITY: return "422 Unprocessable Entity";
|
case UNPROCESSABLE_ENTITY: return "422 Unprocessable Entity";
|
||||||
|
|
||||||
case SERVER_ERROR: return "500 Internal Error";
|
case SERVER_ERROR: return "500 Internal Error";
|
||||||
|
@ -101,6 +102,7 @@ namespace triagens {
|
||||||
case 404: return NOT_FOUND;
|
case 404: return NOT_FOUND;
|
||||||
case 405: return METHOD_NOT_ALLOWED;
|
case 405: return METHOD_NOT_ALLOWED;
|
||||||
case 409: return CONFLICT;
|
case 409: return CONFLICT;
|
||||||
|
case 412: return PRECONDITION_FAILED;
|
||||||
case 422: return UNPROCESSABLE_ENTITY;
|
case 422: return UNPROCESSABLE_ENTITY;
|
||||||
|
|
||||||
case 500: return SERVER_ERROR;
|
case 500: return SERVER_ERROR;
|
||||||
|
|
|
@ -115,6 +115,7 @@ namespace triagens {
|
||||||
NOT_FOUND = 404,
|
NOT_FOUND = 404,
|
||||||
METHOD_NOT_ALLOWED = 405,
|
METHOD_NOT_ALLOWED = 405,
|
||||||
CONFLICT = 409,
|
CONFLICT = 409,
|
||||||
|
PRECONDITION_FAILED = 412,
|
||||||
UNPROCESSABLE_ENTITY = 422,
|
UNPROCESSABLE_ENTITY = 422,
|
||||||
|
|
||||||
SERVER_ERROR = 500,
|
SERVER_ERROR = 500,
|
||||||
|
|
|
@ -194,7 +194,7 @@ HttpHandler::status_e RestDocumentHandler::execute () {
|
||||||
///
|
///
|
||||||
/// @verbinclude rest_create-document
|
/// @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
|
/// @verbinclude rest_create-document-accept
|
||||||
///
|
///
|
||||||
|
@ -208,15 +208,11 @@ HttpHandler::status_e RestDocumentHandler::execute () {
|
||||||
///
|
///
|
||||||
/// Unknown collection identifier:
|
/// Unknown collection identifier:
|
||||||
///
|
///
|
||||||
/// @verbinclude rest4
|
/// @verbinclude rest_create-document-unknown-cid
|
||||||
///
|
///
|
||||||
/// Illegal document:
|
/// Illegal document:
|
||||||
///
|
///
|
||||||
/// @verbinclude rest5
|
/// @verbinclude rest_create-document-bad-json
|
||||||
///
|
|
||||||
/// Create a document given a collection name:
|
|
||||||
///
|
|
||||||
/// @verbinclude rest6
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool RestDocumentHandler::createDocument () {
|
bool RestDocumentHandler::createDocument () {
|
||||||
|
@ -315,19 +311,19 @@ bool RestDocumentHandler::createDocument () {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool RestDocumentHandler::readDocument () {
|
bool RestDocumentHandler::readDocument () {
|
||||||
#ifdef FIXME
|
|
||||||
switch (request->suffix().size()) {
|
switch (request->suffix().size()) {
|
||||||
case 0:
|
case 0:
|
||||||
return readAllDocuments();
|
return readAllDocuments();
|
||||||
|
|
||||||
case 1:
|
case 2:
|
||||||
return readSingleDocument(true);
|
return readSingleDocument(true);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
generateError(HttpResponse::BAD, "expecting URI /document/<document-handle>");
|
generateError(HttpResponse::BAD,
|
||||||
|
TRI_REST_ERROR_SUPERFLUOUS_SUFFICES,
|
||||||
|
"expecting GET /document/<document-handle>");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -345,41 +341,45 @@ bool RestDocumentHandler::readDocument () {
|
||||||
/// If the @FA{document-handle} points to a non-existing document, then a
|
/// 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.
|
/// @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
|
/// @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
|
/// @verbinclude rest_read-document-unknown-handle
|
||||||
///
|
|
||||||
/// Unknown collection identifier:
|
|
||||||
///
|
|
||||||
/// @verbinclude rest17
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool RestDocumentHandler::readSingleDocument (bool generateBody) {
|
bool RestDocumentHandler::readSingleDocument (bool generateBody) {
|
||||||
#ifdef FIXME
|
|
||||||
vector<string> const& suffix = request->suffix();
|
vector<string> 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
|
// split the document reference
|
||||||
string cid;
|
string cid = suffix[0];
|
||||||
string did;
|
string did = suffix[1];
|
||||||
|
|
||||||
bool ok = splitDocumentReference(suffix[0], cid, did);
|
|
||||||
|
|
||||||
if (! ok) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// find and load collection given by name oder identifier
|
// find and load collection given by name oder identifier
|
||||||
ok = findCollection(cid) && loadCollection();
|
bool ok = findCollection(cid) && loadCollection();
|
||||||
|
|
||||||
if (! ok) {
|
if (! ok) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -391,6 +391,7 @@ bool RestDocumentHandler::readSingleDocument (bool generateBody) {
|
||||||
|
|
||||||
_documentCollection->beginRead(_documentCollection);
|
_documentCollection->beginRead(_documentCollection);
|
||||||
|
|
||||||
|
// FIXME FIXME
|
||||||
TRI_doc_mptr_t const* document = findDocument(did);
|
TRI_doc_mptr_t const* document = findDocument(did);
|
||||||
|
|
||||||
_documentCollection->endRead(_documentCollection);
|
_documentCollection->endRead(_documentCollection);
|
||||||
|
@ -404,8 +405,42 @@ bool RestDocumentHandler::readSingleDocument (bool generateBody) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
generateDocument(document, generateBody);
|
TRI_voc_rid_t rid = document->_rid;
|
||||||
#endif
|
|
||||||
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -240,6 +240,24 @@ void RestVocbaseBaseHandler::generateNotImplemented (string const& path) {
|
||||||
"'" + path + "' not implemented");
|
"'" + 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
|
/// @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<string> 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
|
/// @brief extracts the revision
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -539,6 +537,21 @@ TRI_doc_mptr_t const* RestVocbaseBaseHandler::findDocument (string const& doc) {
|
||||||
return document;
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @}
|
/// @}
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -252,18 +252,24 @@ namespace triagens {
|
||||||
|
|
||||||
void generateNotImplemented (string const& path);
|
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
|
/// @brief generates first entry from a result set
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void generateDocument (TRI_doc_mptr_t const*, bool generateBody);
|
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
|
/// @brief extracts the revision
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -300,6 +306,12 @@ namespace triagens {
|
||||||
|
|
||||||
TRI_doc_mptr_t const* findDocument (string const& doc);
|
TRI_doc_mptr_t const* findDocument (string const& doc);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief converts an etag field
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
TRI_voc_rid_t parseEtag (string const& etag);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @}
|
/// @}
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -26,7 +26,11 @@ class AvocadoDB
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.log (args)
|
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
|
method = args[:method] || :get
|
||||||
url = args[:url]
|
url = args[:url]
|
||||||
|
@ -37,7 +41,8 @@ class AvocadoDB
|
||||||
logfile.puts '-' * 80
|
logfile.puts '-' * 80
|
||||||
|
|
||||||
if method == :get
|
if method == :get
|
||||||
logfile.puts "MISSING"
|
logfile.puts "> curl -X GET --dump - http://localhost:8529#{url}"
|
||||||
|
logfile.puts
|
||||||
elsif method == :post
|
elsif method == :post
|
||||||
if body == nil
|
if body == nil
|
||||||
logfile.puts "> curl -X POST --dump - http://localhost:8529#{url}"
|
logfile.puts "> curl -X POST --dump - http://localhost:8529#{url}"
|
||||||
|
|
|
@ -19,7 +19,7 @@ describe AvocadoDB do
|
||||||
doc.parsed_response['code'].should eq(400)
|
doc.parsed_response['code'].should eq(400)
|
||||||
doc.headers['content-type'].should eq("application/json; charset=utf-8")
|
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
|
end
|
||||||
|
|
||||||
it "returns an error if url contains a suffix" do
|
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.parsed_response['code'].should eq(400)
|
||||||
doc.headers['content-type'].should eq("application/json; charset=utf-8")
|
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
|
end
|
||||||
|
|
||||||
it "returns an error if the collection identifier is unknown" do
|
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.parsed_response['code'].should eq(404)
|
||||||
doc.headers['content-type'].should eq("application/json; charset=utf-8")
|
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
|
end
|
||||||
|
|
||||||
it "returns an error if the collection name is unknown" do
|
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.parsed_response['code'].should eq(404)
|
||||||
doc.headers['content-type'].should eq("application/json; charset=utf-8")
|
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
|
end
|
||||||
|
|
||||||
it "returns an error if the JSON body is corrupted" do
|
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.parsed_response['code'].should eq(400)
|
||||||
doc.headers['content-type'].should eq("application/json; charset=utf-8")
|
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")
|
AvocadoDB.drop_collection("UnitTestsCollectionBasics")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -124,7 +124,7 @@ describe AvocadoDB do
|
||||||
etag.should eq("\"#{rev}\"")
|
etag.should eq("\"#{rev}\"")
|
||||||
location.should eq("/document/#{did}")
|
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)
|
AvocadoDB.delete(location)
|
||||||
end
|
end
|
||||||
|
@ -172,7 +172,7 @@ describe AvocadoDB do
|
||||||
etag.should eq("\"#{rev}\"")
|
etag.should eq("\"#{rev}\"")
|
||||||
location.should eq("/document/#{did}")
|
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)
|
AvocadoDB.delete(location)
|
||||||
end
|
end
|
||||||
|
@ -220,7 +220,7 @@ describe AvocadoDB do
|
||||||
etag.should eq("\"#{rev}\"")
|
etag.should eq("\"#{rev}\"")
|
||||||
location.should eq("/document/#{did}")
|
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)
|
AvocadoDB.delete(location)
|
||||||
end
|
end
|
||||||
|
@ -277,7 +277,7 @@ describe AvocadoDB do
|
||||||
etag.should eq("\"#{rev}\"")
|
etag.should eq("\"#{rev}\"")
|
||||||
location.should eq("/document/#{did}")
|
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)
|
AvocadoDB.delete(location)
|
||||||
end
|
end
|
|
@ -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
|
|
@ -1316,15 +1316,6 @@ static v8::Handle<v8::Value> JS_WithinQuery (v8::Arguments const& argv) {
|
||||||
return scope.Close(result);
|
return scope.Close(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @}
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @addtogroup VocBase
|
|
||||||
/// @{
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief get a (persistent) cursor by its id
|
/// @brief get a (persistent) cursor by its id
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -1358,6 +1349,10 @@ static v8::Handle<v8::Value> JS_Cursor (v8::Arguments const& argv) {
|
||||||
return scope.Close(WrapQueryCursor(cursor));
|
return scope.Close(WrapQueryCursor(cursor));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- AVOCADO QUERY LANGUAGE
|
// --SECTION-- AVOCADO QUERY LANGUAGE
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
Loading…
Reference in New Issue