1
0
Fork 0
This commit is contained in:
Frank Celler 2012-03-20 09:35:10 +01:00
parent 4a5506219b
commit 2bb58c386a
39 changed files with 1411 additions and 930 deletions

View File

@ -82,6 +82,7 @@ static void ResizeAssociativeArray (TRI_associative_array_t* array) {
array->_nrResizes++;
array->_table = TRI_Allocate(array->_nrAlloc * array->_elementSize);
// TODO: handle malloc failures
for (j = 0; j < array->_nrAlloc; j++) {
array->clearElement(array, array->_table + j * array->_elementSize);
@ -135,6 +136,7 @@ void TRI_InitAssociativeArray (TRI_associative_array_t* array,
array->_nrAlloc = 10;
array->_table = TRI_Allocate(array->_elementSize * array->_nrAlloc);
// TODO: handle malloc failures
p = array->_table;
e = p + array->_elementSize * array->_nrAlloc;
@ -528,6 +530,7 @@ static void ResizeAssociativePointer (TRI_associative_pointer_t* array) {
array->_nrResizes++;
array->_table = TRI_Allocate(array->_nrAlloc * sizeof(void*));
// TODO: handle malloc failures
for (j = 0; j < array->_nrAlloc; j++) {
array->_table[j] = NULL;
@ -575,6 +578,7 @@ void TRI_InitAssociativePointer (TRI_associative_pointer_t* array,
array->_nrAlloc = 10;
array->_table = TRI_Allocate(sizeof(void*) * array->_nrAlloc);
// TODO: handle malloc failures
p = array->_table;
e = p + array->_nrAlloc;
@ -924,6 +928,7 @@ static void ResizeAssociativeSynced (TRI_associative_synced_t* array) {
array->_nrResizes++;
array->_table = TRI_Allocate(array->_nrAlloc * sizeof(void*));
// TODO: handle malloc failures
for (j = 0; j < array->_nrAlloc; j++) {
array->_table[j] = NULL;
@ -971,6 +976,7 @@ void TRI_InitAssociativeSynced (TRI_associative_synced_t* array,
array->_nrAlloc = 10;
array->_table = TRI_Allocate(sizeof(void*) * array->_nrAlloc);
// TODO: handle malloc failures
p = array->_table;
e = p + array->_nrAlloc;

View File

@ -68,16 +68,15 @@ static void Reserve (TRI_string_buffer_t * self, size_t size) {
self->_len = (size_t)(1.2 * (self->_len + size));
self->_buffer = TRI_Reallocate(self->_buffer, self->_len + 1);
self->_current = self->_buffer + off;
memset(self->_current, 0, Remaining(self) + 1);
#if I_CARE_ABOUT_MALLOC_FAILURES
if (NULL == self->_buffer) {
abort();
}
#endif
self->_current = self->_buffer + off;
memset(self->_current, 0, Remaining(self) + 1);
}
}

View File

@ -907,16 +907,13 @@ void QLOptimizeFreeRangeVector (TRI_vector_pointer_t* vector) {
TRI_FreeString(range->_refValue._field);
}
if (range->_valueType == RANGE_TYPE_JSON) {
// minValue and maxValue point to the same string, just free it once!
TRI_FreeString(range->_minValue._stringValue);
}
if (range->_valueType == RANGE_TYPE_STRING) {
if (range->_valueType == RANGE_TYPE_JSON ||
range->_valueType == RANGE_TYPE_STRING) {
if (range->_minValue._stringValue) {
TRI_FreeString(range->_minValue._stringValue);
range->_minValue._stringValue = 0;
}
if (range->_maxValue._stringValue) {
TRI_FreeString(range->_maxValue._stringValue);
range->_maxValue._stringValue = 0;
@ -1436,13 +1433,20 @@ static QL_optimize_range_t* QLOptimizeCreateRange (TRI_query_node_t* memberNode,
}
else if (range->_valueType == RANGE_TYPE_STRING) {
range->_minValue._stringValue = TRI_DuplicateString(valueNode->_value._stringValue);
if (!range->_minValue._stringValue) {
TRI_Free(range);
return NULL;
}
range->_maxValue._stringValue = TRI_DuplicateString(valueNode->_value._stringValue);
if (!range->_maxValue._stringValue) {
TRI_Free(range);
return NULL;
}
}
else if (range->_valueType == RANGE_TYPE_JSON) {
documentJs = TRI_InitQueryJavascript();
if (!documentJs) {
TRI_DestroyStringBuffer(name);
TRI_Free(name);
TRI_Free(range);
return NULL;
}
@ -1450,9 +1454,16 @@ static QL_optimize_range_t* QLOptimizeCreateRange (TRI_query_node_t* memberNode,
range->_minValue._stringValue = TRI_DuplicateString(documentJs->_buffer->_buffer);
range->_maxValue._stringValue = TRI_DuplicateString(documentJs->_buffer->_buffer);
TRI_FreeQueryJavascript(documentJs);
if (!range->_minValue._stringValue) {
TRI_DestroyStringBuffer(name);
TRI_Free(name);
if (!range->_minValue._stringValue || !range->_maxValue._stringValue) {
if (range->_minValue._stringValue) {
TRI_FreeString(range->_minValue._stringValue);
}
if (range->_maxValue._stringValue) {
TRI_FreeString(range->_maxValue._stringValue);
}
TRI_Free(range);
return NULL;
}

View File

@ -16,10 +16,10 @@
#include <BasicsC/conversions.h>
#include <BasicsC/strings.h>
#include "VocBase/voc-errors.h"
#include "VocBase/query-node.h"
#include "VocBase/query-base.h"
#include "VocBase/query-parse.h"
#include "VocBase/query-error.h"
#define ABORT_IF_OOM(ptr) \
if (!ptr) { \

View File

@ -119,33 +119,39 @@ namespace triagens {
// -----------------------------------------------------------------------------
HttpResponse::HttpResponse ()
: code(NOT_IMPLEMENTED),
headerFields(5),
bodyValue(),
freeables() {
: _code(NOT_IMPLEMENTED),
_headers(5),
_body(),
_isHeadResponse(false),
_bodySize(0),
_freeables() {
}
HttpResponse::HttpResponse (string const& header)
: code(NOT_IMPLEMENTED),
headerFields(5),
bodyValue(),
freeables() {
: _code(NOT_IMPLEMENTED),
_headers(5),
_body(),
_isHeadResponse(false),
_bodySize(0),
_freeables() {
setHeaders(header, true);
}
HttpResponse::HttpResponse (HttpResponseCode code)
: code(code),
headerFields(5),
bodyValue(),
freeables() {
: _code(code),
_headers(5),
_body(),
_isHeadResponse(false),
_bodySize(0),
_freeables() {
char* headerBuffer = StringUtils::duplicate("server\ntriagens GmbH High-Performance HTTP Server\n"
"connection\nKeep-Alive\n"
"content-type\ntext/plain;charset=utf-8\n");
freeables.push_back(headerBuffer);
_freeables.push_back(headerBuffer);
bool key = true;
char* startKey = headerBuffer;
@ -161,7 +167,7 @@ namespace triagens {
key = false;
}
else {
headerFields.insert(startKey, startValue);
_headers.insert(startKey, startValue);
startKey = ptr + 1;
startValue = 0;
@ -174,7 +180,7 @@ namespace triagens {
HttpResponse::~HttpResponse () {
for (vector<char const*>::iterator i = freeables.begin(); i != freeables.end(); ++i) {
for (vector<char const*>::iterator i = _freeables.begin(); i != _freeables.end(); ++i) {
delete[] (*i);
}
}
@ -183,6 +189,10 @@ namespace triagens {
// HttpResponse methods
// -----------------------------------------------------------------------------
HttpResponse::HttpResponseCode HttpResponse::responseCode () {
return _code;
}
void HttpResponse::setContentType (string const& contentType) {
setHeader("content-type", contentType);
}
@ -190,20 +200,25 @@ namespace triagens {
size_t HttpResponse::contentLength () {
char const* const* i = headerFields.lookup("content-length");
if (i == 0) {
return 0;
if (_isHeadResponse) {
return _bodySize;
}
else {
char const* const* i = _headers.lookup("content-length");
return StringUtils::uint32(*i);
if (i == 0) {
return 0;
}
return StringUtils::uint32(*i);
}
}
string HttpResponse::header (string const& key) const {
string k = StringUtils::tolower(key);
char const* const* i = headerFields.lookup(k.c_str());
char const* const* i = _headers.lookup(k.c_str());
if (i == 0) {
return "";
@ -217,7 +232,7 @@ namespace triagens {
string HttpResponse::header (string const& key, bool& found) const {
string k = StringUtils::tolower(key);
char const* const* i = headerFields.lookup(k.c_str());
char const* const* i = _headers.lookup(k.c_str());
if (i == 0) {
found = false;
@ -237,7 +252,7 @@ namespace triagens {
map<string, string> result;
for (headerFields.range(begin, end); begin < end; ++begin) {
for (_headers.range(begin, end); begin < end; ++begin) {
char const* key = begin->_key;
if (key == 0) {
@ -256,7 +271,7 @@ namespace triagens {
string lk = StringUtils::tolower(key);
if (value.empty()) {
headerFields.erase(lk.c_str());
_headers.erase(lk.c_str());
}
else {
StringUtils::trimInPlace(lk);
@ -264,10 +279,10 @@ namespace triagens {
char const* k = StringUtils::duplicate(lk);
char const* v = StringUtils::duplicate(value);
headerFields.insert(k, lk.size(), v);
_headers.insert(k, lk.size(), v);
freeables.push_back(k);
freeables.push_back(v);
_freeables.push_back(k);
_freeables.push_back(v);
}
}
@ -279,7 +294,7 @@ namespace triagens {
char* headerBuffer = new char[headers.size() + 1];
memcpy(headerBuffer, headers.c_str(), headers.size() + 1);
freeables.push_back(headerBuffer);
_freeables.push_back(headerBuffer);
// check for '\n' (we check for '\r' later)
int lineNum = includeLine0 ? 0 : 1;
@ -322,14 +337,14 @@ namespace triagens {
if (start2 < end2) {
*end2 = '\0';
code = static_cast<HttpResponseCode>(::atoi(start2));
_code = static_cast<HttpResponseCode>(::atoi(start2));
}
else {
code = NOT_IMPLEMENTED;
_code = NOT_IMPLEMENTED;
}
}
else {
code = NOT_IMPLEMENTED;
_code = NOT_IMPLEMENTED;
}
}
@ -354,10 +369,10 @@ namespace triagens {
*end4 = '\0';
headerFields.insert(start, end3 - start, start2);
_headers.insert(start, end3 - start, start2);
}
else {
headerFields.insert(start, end3 - start, end3);
_headers.insert(start, end3 - start, end3);
}
}
}
@ -374,11 +389,19 @@ namespace triagens {
HttpResponse* HttpResponse::swap () {
HttpResponse* response = new HttpResponse(code);
HttpResponse* response = new HttpResponse(_code);
response->headerFields.swap(&headerFields);
response->bodyValue.swap(&bodyValue);
response->freeables.swap(freeables);
response->_headers.swap(&_headers);
response->_body.swap(&_body);
response->_freeables.swap(_freeables);
bool isHeadResponse = response->_isHeadResponse;
response->_isHeadResponse = _isHeadResponse;
_isHeadResponse = isHeadResponse;
size_t bodySize = response->_bodySize;
response->_bodySize = _bodySize;
_bodySize = bodySize;
return response;
}
@ -387,7 +410,7 @@ namespace triagens {
void HttpResponse::writeHeader (StringBuffer* output) {
output->appendText("HTTP/1.1 ");
output->appendText(responseString(code));
output->appendText(responseString(_code));
output->appendText("\r\n");
basics::Dictionary<char const*>::KeyValue const* begin;
@ -396,7 +419,7 @@ namespace triagens {
bool seenTransferEncoding = false;
string transferEncoding;
for (headerFields.range(begin, end); begin < end; ++begin) {
for (_headers.range(begin, end); begin < end; ++begin) {
char const* key = begin->_key;
if (key == 0) {
@ -433,7 +456,14 @@ namespace triagens {
}
output->appendText("content-length: ");
output->appendInteger(static_cast<uint32_t>(bodyValue.length()));
if (_isHeadResponse) {
output->appendInteger(_bodySize);
}
else {
output->appendInteger(_body.length());
}
output->appendText("\r\n");
}
@ -442,8 +472,27 @@ namespace triagens {
size_t HttpResponse::bodySize () {
if (_isHeadResponse) {
return _bodySize;
}
else {
return _body.length();
}
}
StringBuffer& HttpResponse::body () {
return bodyValue;
return _body;
}
void HttpResponse::headResponse (size_t size) {
_body.clear();
_isHeadResponse = true;
_bodySize = size;
}
}
}

View File

@ -180,9 +180,7 @@ namespace triagens {
/// @brief returns the response code
////////////////////////////////////////////////////////////////////////////////
HttpResponseCode responseCode () {
return code;
}
HttpResponseCode responseCode ();
////////////////////////////////////////////////////////////////////////////////
/// @brief returns the content length
@ -258,6 +256,12 @@ namespace triagens {
void writeHeader (basics::StringBuffer*);
////////////////////////////////////////////////////////////////////////////////
/// @brief returns the size of the body
////////////////////////////////////////////////////////////////////////////////
size_t bodySize ();
////////////////////////////////////////////////////////////////////////////////
/// @brief returns the body
///
@ -270,13 +274,25 @@ namespace triagens {
basics::StringBuffer& body ();
////////////////////////////////////////////////////////////////////////////////
/// @brief returns the body
///
/// In case of HEAD request, no body must be defined. However, the response
/// needs to know the size of body.
////////////////////////////////////////////////////////////////////////////////
void headResponse (size_t);
private:
HttpResponseCode code;
HttpResponseCode _code;
basics::Dictionary<char const*> headerFields;
basics::StringBuffer bodyValue;
basics::Dictionary<char const*> _headers;
basics::StringBuffer _body;
vector<char const*> freeables;
bool _isHeadResponse;
size_t _bodySize;
vector<char const*> _freeables;
};
}
}

View File

@ -180,10 +180,11 @@ HttpHandler::status_e RestDocumentHandler::execute () {
/// then a @LIT{HTTP 400} is returned and the body of the response contains
/// an error document.
///
/// @REST{POST /document?collection=@FA{collection-identifier}&createCollection=@FA{create}}
/// @REST{POST /document?collection=@FA{collection-name}&createCollection=@FA{create}}
///
/// Instead of a @FA{collection-identifier}, a collection name can be used. If
/// @FA{create} is true, then the collection is created if it does not exists.
/// Instead of a @FA{collection-identifier}, a @FA{collection-name} can be
/// used. If @FA{createCollection} is true, then the collection is created if it does not
/// exists.
///
/// @EXAMPLES
///
@ -368,11 +369,8 @@ bool RestDocumentHandler::readSingleDocument (bool generateBody) {
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);
TRI_voc_rid_t ifNoneRid = extractRevision("if-none-match");
TRI_voc_rid_t ifRid = extractRevision("if-match", "_rev");
// split the document reference
string cid = suffix[0];
@ -415,7 +413,7 @@ bool RestDocumentHandler::readSingleDocument (bool generateBody) {
generateDocument(document, generateBody);
}
else {
generatePreconditionFailed();
generatePreconditionFailed(_documentCollection->base._cid, document->_did, rid);
}
}
else if (ifNoneRid == rid) {
@ -426,7 +424,7 @@ bool RestDocumentHandler::readSingleDocument (bool generateBody) {
generateNotModified(StringUtils::itoa(rid));
}
else {
generatePreconditionFailed();
generatePreconditionFailed(_documentCollection->base._cid, document->_did, rid);
}
}
else {
@ -437,7 +435,7 @@ bool RestDocumentHandler::readSingleDocument (bool generateBody) {
generateDocument(document, generateBody);
}
else {
generatePreconditionFailed();
generatePreconditionFailed(_documentCollection->base._cid, document->_did, rid);
}
}
@ -460,8 +458,10 @@ bool RestDocumentHandler::readSingleDocument (bool generateBody) {
////////////////////////////////////////////////////////////////////////////////
bool RestDocumentHandler::readAllDocuments () {
#ifdef FIXME
vector<string> const& suffix = request->suffix();
// extract the cid
bool found;
string cid = request->value("collection", found);
// find and load collection given by name oder identifier
bool ok = findCollection(cid) && loadCollection();
@ -534,7 +534,6 @@ bool RestDocumentHandler::readAllDocuments () {
response->body().appendText(TRI_BeginStringBuffer(&buffer), TRI_LengthStringBuffer(&buffer));
TRI_AnnihilateStringBuffer(&buffer);
#endif
return true;
}
@ -554,16 +553,16 @@ bool RestDocumentHandler::readAllDocuments () {
////////////////////////////////////////////////////////////////////////////////
bool RestDocumentHandler::checkDocument () {
#ifdef FIXME
vector<string> const& suffix = request->suffix();
if (suffix.size() != 1) {
generateError(HttpResponse::BAD, "expecting URI /document/<document-handle>");
if (suffix.size() != 2) {
generateError(HttpResponse::BAD,
TRI_REST_ERROR_BAD_PARAMETER,
"expecting URI /document/<document-handle>");
return false;
}
return readSingleDocument(false);
#endif
}
////////////////////////////////////////////////////////////////////////////////
@ -629,19 +628,19 @@ bool RestDocumentHandler::checkDocument () {
////////////////////////////////////////////////////////////////////////////////
bool RestDocumentHandler::updateDocument () {
#ifdef FIXME
vector<string> const& suffix = request->suffix();
// split the document reference
string cid;
string did;
ok = splitDocumentReference(suffix[1], cid, did);
if (! ok) {
if (suffix.size() != 2) {
generateError(HttpResponse::BAD,
TRI_REST_ERROR_BAD_PARAMETER,
"expecting UPDATE /document/<document-handle>");
return false;
}
// split the document reference
string cid = suffix[0];
string didStr = suffix[1];
// find and load collection given by name oder identifier
bool ok = findCollection(cid) && loadCollection();
@ -660,7 +659,7 @@ bool RestDocumentHandler::updateDocument () {
TRI_voc_did_t did = StringUtils::uint64(didStr);
// extract the revision
TRI_voc_rid_t revision = extractRevision();
TRI_voc_rid_t revision = extractRevision("if-match", "_rev");
// extract or chose the update policy
TRI_doc_update_policy_e policy = extractUpdatePolicy();
@ -672,40 +671,39 @@ bool RestDocumentHandler::updateDocument () {
_documentCollection->beginWrite(_documentCollection);
// unlocking is performed in updateJson()
TRI_doc_mptr_t const* mptr = _documentCollection->updateJson(_documentCollection, json, did, revision, policy, true);
TRI_voc_rid_t rid = 0;
if (mptr != 0) {
rid = mptr->_rid;
}
TRI_doc_mptr_t const* mptr = _documentCollection->updateJson(_documentCollection, json, did, revision, &rid, policy, true);
// .............................................................................
// outside write transaction
// .............................................................................
if (mptr != 0) {
generateOk(_documentCollection->base._cid, did, rid);
generateUpdated(_documentCollection->base._cid, did, mptr->_rid);
return true;
}
else {
if (TRI_errno() == TRI_VOC_ERROR_READ_ONLY) {
generateError(HttpResponse::FORBIDDEN, "collection is read-only");
generateError(HttpResponse::FORBIDDEN,
TRI_VOC_ERROR_READ_ONLY,
"collection is read-only");
return false;
}
else if (TRI_errno() == TRI_VOC_ERROR_DOCUMENT_NOT_FOUND) {
generateDocumentNotFound(suffix[0], didStr);
generateDocumentNotFound(cid + TRI_DOCUMENT_HANDLE_SEPARATOR_STR + didStr);
return false;
}
else if (TRI_errno() == TRI_VOC_ERROR_CONFLICT) {
generateConflict(suffix[0], didStr);
generatePreconditionFailed(_documentCollection->base._cid, did, rid);
return false;
}
else {
generateError(HttpResponse::SERVER_ERROR, "cannot update, failed with " + string(TRI_last_error()));
generateError(HttpResponse::SERVER_ERROR,
TRI_ERROR_INTERNAL,
"cannot update, failed with " + string(TRI_last_error()));
return false;
}
}
#endif
}
////////////////////////////////////////////////////////////////////////////////
@ -713,9 +711,8 @@ bool RestDocumentHandler::updateDocument () {
///
/// @REST{DELETE /document/@FA{document-handle}}
///
/// Deletes the document identified by @FA{document-handle} from the collection
/// identified by @FA{collection-identifier}. If the document exists and could
/// be deleted, then a @LIT{HTTP 204} is returned.
/// Deletes the document identified by @FA{document-handle}. If the document
/// exists and could be deleted, then a @LIT{HTTP 204} is returned.
///
/// The body of the response contains a JSON object with the information about
/// the handle and the revision. The attribute @LIT{_id} contains the known
@ -727,7 +724,7 @@ bool RestDocumentHandler::updateDocument () {
///
/// If an etag is supplied in the "If-Match" field, then the AvocadoDB checks
/// that the revision of the document is equal to the tag. If there is a
/// mismatch, then a @LIT{HTTP 409} conflict is returned and no delete is
/// mismatch, then a @LIT{HTTP 412} conflict is returned and no delete is
/// performed.
///
/// @REST{DELETE /document/@FA{document-handle}?policy=@FA{policy}}
@ -737,9 +734,9 @@ bool RestDocumentHandler::updateDocument () {
///
/// @REST{DELETE /document/@FA{document-handle}?rev=@FA{etag}}
///
/// You can also supply the etag using the parameter @LIT{rev} instead of an "ETag"
/// header. You must never supply both the "ETag" header and the @LIT{rev}
/// parameter.
/// You can also supply the etag using the parameter @LIT{rev} instead of an
/// "If-Match" header. You must never supply both the "If-Match" header and the
/// @LIT{rev} parameter.
///
/// @EXAMPLES
///
@ -757,19 +754,21 @@ bool RestDocumentHandler::updateDocument () {
////////////////////////////////////////////////////////////////////////////////
bool RestDocumentHandler::deleteDocument () {
#ifdef FIXME
vector<string> const& suffix = request->suffix();
// split the document reference
string didStr;
ok = splitDocumentReference(suffix[1], didStr);
if (! ok) {
if (suffix.size() != 2) {
generateError(HttpResponse::BAD,
TRI_REST_ERROR_BAD_PARAMETER,
"expecting DELETE /document/<document-handle>");
return false;
}
// split the document reference
string cid = suffix[0];
string didStr = suffix[1];
// find and load collection given by name oder identifier
bool ok = findCollection(cid[0]) && loadCollection();
bool ok = findCollection(cid) && loadCollection();
if (! ok) {
return false;
@ -779,7 +778,7 @@ bool RestDocumentHandler::deleteDocument () {
TRI_voc_did_t did = StringUtils::uint64(didStr);
// extract the revision
TRI_voc_rid_t revision = extractRevision();
TRI_voc_rid_t revision = extractRevision("if-match", "_rev");
// extract or chose the update policy
TRI_doc_update_policy_e policy = extractUpdatePolicy();
@ -791,35 +790,39 @@ bool RestDocumentHandler::deleteDocument () {
_documentCollection->beginWrite(_documentCollection);
// unlocking is performed in destroy()
ok = _documentCollection->destroy(_documentCollection, did, revision, policy, true);
TRI_voc_rid_t rid = 0;
ok = _documentCollection->destroy(_documentCollection, did, revision, &rid, policy, true);
// .............................................................................
// outside write transaction
// .............................................................................
if (ok) {
generateOk();
generateDeleted(_documentCollection->base._cid, did, rid);
return true;
}
else {
if (TRI_errno() == TRI_VOC_ERROR_READ_ONLY) {
generateError(HttpResponse::FORBIDDEN, "collection is read-only");
generateError(HttpResponse::FORBIDDEN,
TRI_VOC_ERROR_READ_ONLY,
"collection is read-only");
return false;
}
else if (TRI_errno() == TRI_VOC_ERROR_DOCUMENT_NOT_FOUND) {
generateDocumentNotFound(suffix[0], didStr);
generateDocumentNotFound(cid + TRI_DOCUMENT_HANDLE_SEPARATOR_STR + didStr);
return false;
}
else if (TRI_errno() == TRI_VOC_ERROR_CONFLICT) {
generateConflict(suffix[0], didStr);
generatePreconditionFailed(_documentCollection->base._cid, did, rid);
return false;
}
else {
generateError(HttpResponse::SERVER_ERROR, "cannot delete, failed with " + string(TRI_last_error()));
generateError(HttpResponse::SERVER_ERROR,
TRI_ERROR_INTERNAL,
"cannot delete, failed with " + string(TRI_last_error()));
return false;
}
}
#endif
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -143,17 +143,7 @@ void RestVocbaseBaseHandler::generateOk () {
}
////////////////////////////////////////////////////////////////////////////////
/// @brief generates ok message without content
////////////////////////////////////////////////////////////////////////////////
void RestVocbaseBaseHandler::generateOk (TRI_voc_cid_t, TRI_voc_did_t, TRI_voc_rid_t rid) {
response = new HttpResponse(HttpResponse::NO_CONTENT);
response->setHeader("ETag", "\"" + StringUtils::itoa(rid) + "\"");
}
////////////////////////////////////////////////////////////////////////////////
/// @brief generates created message without content but a location header
/// @brief generates created message
////////////////////////////////////////////////////////////////////////////////
void RestVocbaseBaseHandler::generateCreated (TRI_voc_cid_t cid, TRI_voc_did_t did, TRI_voc_rid_t rid) {
@ -177,7 +167,7 @@ void RestVocbaseBaseHandler::generateCreated (TRI_voc_cid_t cid, TRI_voc_did_t d
}
////////////////////////////////////////////////////////////////////////////////
/// @brief generates accepted message without content but a location header
/// @brief generates accepted message
////////////////////////////////////////////////////////////////////////////////
void RestVocbaseBaseHandler::generateAccepted (TRI_voc_cid_t cid, TRI_voc_did_t did, TRI_voc_rid_t rid) {
@ -200,6 +190,50 @@ void RestVocbaseBaseHandler::generateAccepted (TRI_voc_cid_t cid, TRI_voc_did_t
.appendText("}");
}
////////////////////////////////////////////////////////////////////////////////
/// @brief generates deleted message
////////////////////////////////////////////////////////////////////////////////
void RestVocbaseBaseHandler::generateDeleted (TRI_voc_cid_t cid, TRI_voc_did_t did, TRI_voc_rid_t rid) {
string cidStr = StringUtils::itoa(cid);
string didStr = StringUtils::itoa(did);
string ridStr = StringUtils::itoa(rid);
string handle = cidStr + "/" + didStr;
response = new HttpResponse(HttpResponse::OK);
response->setContentType("application/json; charset=utf-8");
response->body()
.appendText("{\"error\":false,\"_id\":\"")
.appendText(handle.c_str())
.appendText("\",\"_rev\":")
.appendInteger(rid)
.appendText("}");
}
////////////////////////////////////////////////////////////////////////////////
/// @brief generates updated message
////////////////////////////////////////////////////////////////////////////////
void RestVocbaseBaseHandler::generateUpdated (TRI_voc_cid_t cid, TRI_voc_did_t did, TRI_voc_rid_t rid) {
string cidStr = StringUtils::itoa(cid);
string didStr = StringUtils::itoa(did);
string ridStr = StringUtils::itoa(rid);
string handle = cidStr + "/" + didStr;
response = new HttpResponse(HttpResponse::OK);
response->setContentType("application/json; charset=utf-8");
response->body()
.appendText("{\"error\":false,\"_id\":\"")
.appendText(handle.c_str())
.appendText("\",\"_rev\":")
.appendInteger(rid)
.appendText("}");
}
////////////////////////////////////////////////////////////////////////////////
/// @brief generates collection not found error message
////////////////////////////////////////////////////////////////////////////////
@ -244,8 +278,16 @@ void RestVocbaseBaseHandler::generateNotImplemented (string const& path) {
/// @brief generates precondition failed
////////////////////////////////////////////////////////////////////////////////
void RestVocbaseBaseHandler::generatePreconditionFailed () {
void RestVocbaseBaseHandler::generatePreconditionFailed (TRI_voc_cid_t cid, TRI_voc_did_t did, TRI_voc_rid_t rid) {
response = new HttpResponse(HttpResponse::PRECONDITION_FAILED);
response->setContentType("application/json; charset=utf-8");
response->body()
.appendText("{\"error\":true,\"_id\":\"")
.appendInteger(cid).appendChar(TRI_DOCUMENT_HANDLE_SEPARATOR_CHR).appendInteger(did)
.appendText("\",\"_rev\":")
.appendInteger(rid)
.appendText("}");
}
////////////////////////////////////////////////////////////////////////////////
@ -274,37 +316,36 @@ void RestVocbaseBaseHandler::generateDocument (TRI_doc_mptr_t const* document,
// add document identifier to buffer
TRI_string_buffer_t buffer;
if (generateDocument) {
string id = StringUtils::itoa(_documentCollection->base._cid) + TRI_DOCUMENT_HANDLE_SEPARATOR_STR + StringUtils::itoa(document->_did);
string id = StringUtils::itoa(_documentCollection->base._cid) + TRI_DOCUMENT_HANDLE_SEPARATOR_STR + StringUtils::itoa(document->_did);
TRI_json_t augmented;
TRI_json_t augmented;
TRI_InitArrayJson(&augmented);
TRI_InitArrayJson(&augmented);
TRI_json_t* _id = TRI_CreateStringCopyJson(id.c_str());
TRI_json_t* _id = TRI_CreateStringCopyJson(id.c_str());
if (_id) {
TRI_Insert2ArrayJson(&augmented, "_id", _id);
}
if (_id) {
TRI_Insert2ArrayJson(&augmented, "_id", _id);
}
TRI_json_t* _rev = TRI_CreateNumberJson(document->_rid);
TRI_json_t* _rev = TRI_CreateNumberJson(document->_rid);
if (_rev) {
TRI_Insert2ArrayJson(&augmented, "_rev", _rev);
}
if (_rev) {
TRI_Insert2ArrayJson(&augmented, "_rev", _rev);
}
// convert object to string
TRI_InitStringBuffer(&buffer);
// convert object to string
TRI_InitStringBuffer(&buffer);
TRI_StringifyAugmentedShapedJson(_documentCollection->_shaper, &buffer, &document->_document, &augmented);
TRI_StringifyAugmentedShapedJson(_documentCollection->_shaper, &buffer, &document->_document, &augmented);
TRI_DestroyJson(&augmented);
TRI_DestroyJson(&augmented);
if (_id) {
TRI_Free(_id);
}
if (_rev) {
TRI_Free(_rev);
}
if (_id) {
TRI_Free(_id);
}
if (_rev) {
TRI_Free(_rev);
}
// and generate a response
@ -314,18 +355,21 @@ void RestVocbaseBaseHandler::generateDocument (TRI_doc_mptr_t const* document,
if (generateDocument) {
response->body().appendText(TRI_BeginStringBuffer(&buffer), TRI_LengthStringBuffer(&buffer));
TRI_AnnihilateStringBuffer(&buffer);
}
else {
response->headResponse(TRI_LengthStringBuffer(&buffer));
}
TRI_AnnihilateStringBuffer(&buffer);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief extracts the revision
////////////////////////////////////////////////////////////////////////////////
TRI_voc_rid_t RestVocbaseBaseHandler::extractRevision () {
TRI_voc_rid_t RestVocbaseBaseHandler::extractRevision (string const& header, string const& parameter) {
bool found;
string etag = request->header("etag", found);
string etag = StringUtils::trim(request->header(header, found));
if (found && ! etag.empty() && etag[0] == '"' && etag[etag.length()-1] == '"') {
return StringUtils::uint64(etag.c_str() + 1, etag.length() - 2);
@ -334,13 +378,18 @@ TRI_voc_rid_t RestVocbaseBaseHandler::extractRevision () {
return 0;
}
etag = request->value("_rev", found);
if (found) {
return StringUtils::uint64(etag.c_str() + 1, etag.length() - 2);
if (parameter.empty()) {
return 0;
}
else {
return 0;
etag = request->value(parameter, found);
if (found) {
return StringUtils::uint64(etag.c_str() + 1, etag.length() - 2);
}
else {
return 0;
}
}
}
@ -537,21 +586,6 @@ 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));
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

View File

@ -146,23 +146,29 @@ namespace triagens {
void generateOk ();
////////////////////////////////////////////////////////////////////////////////
/// @brief generates ok message without content
////////////////////////////////////////////////////////////////////////////////
void generateOk (TRI_voc_cid_t, TRI_voc_did_t, TRI_voc_rid_t rid);
////////////////////////////////////////////////////////////////////////////////
/// @brief generates created message without content but a location header
/// @brief generates created message
////////////////////////////////////////////////////////////////////////////////
void generateCreated (TRI_voc_cid_t, TRI_voc_did_t, TRI_voc_rid_t);
////////////////////////////////////////////////////////////////////////////////
/// @brief generates accepted message without content but a location header
/// @brief generates accepted message
////////////////////////////////////////////////////////////////////////////////
void generateAccepted (TRI_voc_cid_t, TRI_voc_did_t, TRI_voc_rid_t);
////////////////////////////////////////////////////////////////////////////////
/// @brief generates deleted message
////////////////////////////////////////////////////////////////////////////////
void generateDeleted (TRI_voc_cid_t, TRI_voc_did_t, TRI_voc_rid_t);
////////////////////////////////////////////////////////////////////////////////
/// @brief generates updated message
////////////////////////////////////////////////////////////////////////////////
void generateUpdated (TRI_voc_cid_t, TRI_voc_did_t, TRI_voc_rid_t);
////////////////////////////////////////////////////////////////////////////////
/// @brief generates collection not found error message
////////////////////////////////////////////////////////////////////////////////
@ -191,7 +197,7 @@ namespace triagens {
/// @brief generates precondition failed
////////////////////////////////////////////////////////////////////////////////
void generatePreconditionFailed ();
void generatePreconditionFailed (TRI_voc_cid_t, TRI_voc_did_t, TRI_voc_rid_t);
////////////////////////////////////////////////////////////////////////////////
/// @brief generates not modified
@ -209,7 +215,7 @@ namespace triagens {
/// @brief extracts the revision
////////////////////////////////////////////////////////////////////////////////
TRI_voc_rid_t extractRevision ();
TRI_voc_rid_t extractRevision (string const& header, string const& parameter = "");
////////////////////////////////////////////////////////////////////////////////
/// @brief extracts the update policy
@ -241,12 +247,6 @@ namespace triagens {
TRI_doc_mptr_t const* findDocument (string const& doc);
////////////////////////////////////////////////////////////////////////////////
/// @brief converts an etag field
////////////////////////////////////////////////////////////////////////////////
TRI_voc_rid_t parseEtag (string const& etag);
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

View File

@ -229,6 +229,7 @@ void ActionDispatcherThread::initialise () {
bool ok;
char const* files[] = { "common/bootstrap/modules.js",
"common/bootstrap/print.js",
"common/bootstrap/errors.js",
"server/server.js"
};
size_t i;

View File

@ -67,6 +67,7 @@ using namespace triagens::avocado;
#include "js/common/bootstrap/js-modules.h"
#include "js/common/bootstrap/js-print.h"
#include "js/common/bootstrap/js-errors.h"
#include "js/server/js-server.h"
// -----------------------------------------------------------------------------
@ -397,6 +398,7 @@ void AvocadoServer::buildApplicationServer () {
LOGGER_INFO << "using built-in JavaScript startup files";
StartupLoader.defineScript("common/bootstrap/modules.js", JS_common_bootstrap_modules);
StartupLoader.defineScript("common/bootstrap/print.js", JS_common_bootstrap_print);
StartupLoader.defineScript("common/bootstrap/errors.js", JS_common_bootstrap_errors);
StartupLoader.defineScript("server/server.js", JS_server_server);
}
else {
@ -629,6 +631,7 @@ void AvocadoServer::executeShell () {
bool ok;
char const* files[] = { "common/bootstrap/modules.js",
"common/bootstrap/print.js",
"common/bootstrap/errors.js",
"server/server.js"
};
size_t i;

View File

@ -33,7 +33,7 @@
#include "Admin/ApplicationAdminServer.h"
#include "HttpServer/ApplicationHttpServer.h"
#include "VocBase/vocbase.h"
#include "VocBase/query-error.h"
#include "VocBase/voc-errors.h"
// -----------------------------------------------------------------------------
// --SECTION-- class AvocadoServer

View File

@ -51,7 +51,6 @@ using namespace triagens::avocado;
int main (int argc, char* argv[]) {
TRIAGENS_RESULT_GENERATOR_INITIALISE;
TRI_InitialiseVocBase();
TRI_InitialiseQueryErrors();
// create and start a AvocadoDB server
AvocadoServer server(argc, argv);

View File

@ -1094,7 +1094,7 @@ bool TRI_RemoveElementSkipList (TRI_skiplist_t* skiplist, void* element, void* o
// Use the callback to determine if the element is less or greater than
// the next node element.
// .......................................................................
compareResult = skiplist->compareElementElement(skiplist,element,&(nextNode->_element), 0);
compareResult = skiplist->compareElementElement(skiplist,element,&(nextNode->_element), -1);
// .......................................................................
// We have found the item!
@ -1354,6 +1354,7 @@ void TRI_InitSkipListMulti (TRI_skiplist_multi_t* skiplist,
size_t elementSize,
int (*compareElementElement) (TRI_skiplist_multi_t*, void*, void*, int),
int (*compareKeyElement) (TRI_skiplist_multi_t*, void*, void*, int),
bool (*equalElementElement) (TRI_skiplist_multi_t*, void*, void*),
TRI_skiplist_prob_e probability,
uint32_t maximumHeight) {
@ -1367,6 +1368,7 @@ void TRI_InitSkipListMulti (TRI_skiplist_multi_t* skiplist,
skiplist->compareElementElement = compareElementElement;
skiplist->compareKeyElement = compareKeyElement;
skiplist->equalElementElement = equalElementElement;
// ..........................................................................
// Assign the maximum height of the skip list. This maximum height must be
@ -1827,6 +1829,10 @@ bool TRI_InsertElementSkipListMulti(TRI_skiplist_multi_t* skiplist, void* elemen
// We do not allow non-unique elements.
// .......................................................................
if (compareResult == 0) {
/* start oreste: */
assert(false);
/* end oreste: */
if (overwrite) {
memcpy(&(nextNode->_element),element,skiplist->_base._elementSize);
TRI_FreeSkipListNode(&(skiplist->_base), newNode);
@ -1878,7 +1884,6 @@ bool TRI_InsertElementSkipListMulti(TRI_skiplist_multi_t* skiplist, void* elemen
// SKIPLIST_ABSOLUTE_MAX_HEIGHT number of elements.
// ..........................................................................
for (j = 0; j < newHeight; ++j) {
tempLeftNode = newNode->_column[j]._prev;
tempRightNode = tempLeftNode->_column[j]._next;
@ -1897,6 +1902,7 @@ bool TRI_InsertElementSkipListMulti(TRI_skiplist_multi_t* skiplist, void* elemen
*/
}
return true;
}
@ -2026,12 +2032,12 @@ bool TRI_RemoveElementSkipListMulti (TRI_skiplist_multi_t* skiplist, void* eleme
// Use the callback to determine if the element is less or greater than
// the next node element.
// .......................................................................
compareResult = skiplist->compareElementElement(skiplist,element,&(nextNode->_element), -1);
compareResult = skiplist->compareElementElement(skiplist,element,&(nextNode->_element), TRI_SKIPLIST_COMPARE_SLIGHTLY_LESS);
// .......................................................................
// We have found an item which matches the key
// .......................................................................
if (compareResult == 0) {
if (compareResult == TRI_SKIPLIST_COMPARE_STRICTLY_EQUAL) {
currentNode = nextNode;
goto END;
}
@ -2051,7 +2057,23 @@ bool TRI_RemoveElementSkipListMulti (TRI_skiplist_multi_t* skiplist, void* eleme
// We have reached the lowest level of the lists -- no such item.
// .......................................................................
if (currentLevel == 0) {
return false;
// .....................................................................
// The element could not be located
// .....................................................................
if (compareResult == TRI_SKIPLIST_COMPARE_STRICTLY_LESS) {
return false;
}
// .....................................................................
// The element could be located and we are at the lowest level
// .....................................................................
if (compareResult == TRI_SKIPLIST_COMPARE_SLIGHTLY_LESS) {
goto END;
}
// can not occur
assert(false);
}
// .......................................................................
@ -2066,16 +2088,41 @@ bool TRI_RemoveElementSkipListMulti (TRI_skiplist_multi_t* skiplist, void* eleme
END:
// ..........................................................................
// locate the correct elemet -- since we allow duplicates
// ..........................................................................
while (currentNode != NULL) {
if (skiplist->equalElementElement(skiplist, element, &(currentNode->_element))) {
break;
}
currentNode = TRI_NextNodeBaseSkipList(&(skiplist->_base), currentNode);
}
// ..........................................................................
// The actual element could not be located - an element with a matching key
// may exist, but the same data stored within the element could not be located
// ..........................................................................
if (currentNode == NULL) {
return false;
}
// ..........................................................................
// Perhaps the user wants a copy before we destory the data?
// ..........................................................................
if (old != NULL) {
memcpy(old, &(currentNode->_element), skiplist->_base._elementSize);
}
// ..........................................................................
// remove element
// remove element
// ..........................................................................
for (j = 0; j < currentNode->_colLength; ++j) {
tempLeftNode = currentNode->_column[j]._prev;
tempRightNode = currentNode->_column[j]._next;
@ -2185,16 +2232,14 @@ void* TRI_RightLookupByKeySkipListMulti(TRI_skiplist_multi_t* skiplist, void* ke
// Use the callback to determine if the element is less or greater than
// the next node element.
// .......................................................................
compareResult = skiplist->compareKeyElement(skiplist,key,&(prevNode->_element), 0);
compareResult = skiplist->compareKeyElement(skiplist,key,&(prevNode->_element), 1);
// .......................................................................
// We have found the item!
// We have found the item! Not possible since we are searching by key!
// .......................................................................
if (compareResult == 0) {
//return &(nextNode->_element);
//return currentNode;
return prevNode->_column[0]._next;
assert(false);
}
// .......................................................................

View File

@ -60,6 +60,14 @@ typedef enum {
TRI_skiplist_prob_e;
typedef enum {
TRI_SKIPLIST_COMPARE_STRICTLY_LESS = -1,
TRI_SKIPLIST_COMPARE_STRICTLY_GREATER = 1,
TRI_SKIPLIST_COMPARE_STRICTLY_EQUAL = 0,
TRI_SKIPLIST_COMPARE_SLIGHTLY_LESS = -2,
TRI_SKIPLIST_COMPARE_SLIGHTLY_GREATER = 2
}
TRI_skiplist_compare_e;
////////////////////////////////////////////////////////////////////////////////
/// @brief storage structure for a node's nearest neighbours
@ -340,6 +348,12 @@ typedef struct TRI_skiplist_multi_s {
// ...........................................................................
int (*compareElementElement) (struct TRI_skiplist_multi_s*, void*, void*, int);
int (*compareKeyElement) (struct TRI_skiplist_multi_s*, void*, void*, int);
// ...........................................................................
// Returns true if the element is an exact copy, or if the data which the
// element points to is an exact copy
// ...........................................................................
bool (*equalElementElement) (struct TRI_skiplist_multi_s*, void*, void*);
} TRI_skiplist_multi_t;
@ -381,6 +395,7 @@ void TRI_InitSkipListMulti (TRI_skiplist_multi_t*,
size_t elementSize,
int (*compareElementElement) (TRI_skiplist_multi_t*, void*, void*, int),
int (*compareKeyElement) (TRI_skiplist_multi_t*, void*, void*, int),
bool (*equalElementElement) (TRI_skiplist_multi_t*, void*, void*),
TRI_skiplist_prob_e, uint32_t);

View File

@ -878,8 +878,8 @@ static int CompareElementElement (struct TRI_skiplist_s* skiplist, void* leftEle
// This is where the difference between CompareKeyElement (below) and
// CompareElementElement comes into play. Here if the 'keys' are the same,
// but the doc ptr is different (which it is since we are here), then
// we return 1 to indicate that the leftElement is bigger than the rightElement
// this has the effect of moving to the next node in the skiplist.
// we return what was requested to be returned: 0,-1 or 1. What is returned
// depends on the purpose of calling this callback.
// ............................................................................
return defaultEqual;
@ -1287,19 +1287,19 @@ static int MultiCompareElementElement (TRI_skiplist_multi_t* multiSkiplist, void
if (leftElement == NULL && rightElement == NULL) {
return 0;
return TRI_SKIPLIST_COMPARE_STRICTLY_EQUAL;
}
if (leftElement != NULL && rightElement == NULL) {
return 1;
return TRI_SKIPLIST_COMPARE_STRICTLY_GREATER;
}
if (leftElement == NULL && rightElement != NULL) {
return -1;
return TRI_SKIPLIST_COMPARE_STRICTLY_LESS;
}
if (leftElement == rightElement) {
return 0;
return TRI_SKIPLIST_COMPARE_STRICTLY_EQUAL;
}
if (hLeftElement->numFields != hRightElement->numFields) {
@ -1307,7 +1307,7 @@ static int MultiCompareElementElement (TRI_skiplist_multi_t* multiSkiplist, void
}
if (hLeftElement->data == hRightElement->data) {
return 0;
return TRI_SKIPLIST_COMPARE_STRICTLY_EQUAL;
}
@ -1389,6 +1389,30 @@ static int MultiCompareKeyElement (TRI_skiplist_multi_t* multiSkiplist, void* l
}
////////////////////////////////////////////////////////////////////////////////
/// @brief used to determine the order of two keys
////////////////////////////////////////////////////////////////////////////////
static bool MultiEqualElementElement (TRI_skiplist_multi_t* multiSkiplist, void* leftElement, void* rightElement) {
SkiplistIndexElement* hLeftElement = (SkiplistIndexElement*)(leftElement);
SkiplistIndexElement* hRightElement = (SkiplistIndexElement*)(rightElement);
if (leftElement == rightElement) {
return true;
}
/*
printf("%s:%u:%f:%f,%u:%u\n",__FILE__,__LINE__,
*((double*)((hLeftElement->fields)->_data.data)),
*((double*)((hRightElement->fields)->_data.data)),
(uint64_t)(hLeftElement->data),
(uint64_t)(hRightElement->data)
);
*/
return (hLeftElement->data == hRightElement->data);
}
@ -1424,6 +1448,7 @@ SkiplistIndex* MultiSkiplistIndex_new() {
sizeof(SkiplistIndexElement),
MultiCompareElementElement,
MultiCompareKeyElement,
MultiEqualElementElement,
TRI_SKIPLIST_PROB_HALF, 40);
return skiplistIndex;
@ -1435,6 +1460,7 @@ SkiplistIndex* MultiSkiplistIndex_new() {
/// @brief adds (inserts) a data element into a multi skiplist
////////////////////////////////////////////////////////////////////////////////
int MultiSkiplistIndex_add(SkiplistIndex* skiplistIndex, SkiplistIndexElement* element) {
bool result;
result = TRI_InsertElementSkipListMulti(skiplistIndex->skiplist.nonUniqueSkiplist, element, false);

View File

@ -0,0 +1,28 @@
require 'rspec'
require './avocadodb.rb'
describe AvocadoDB do
context "delete a document in a collection" do
################################################################################
## error handling
################################################################################
context "error handling" do
it "returns an error if document handle is missing" do
cmd = "/document"
doc = AvocadoDB.delete(cmd)
doc.code.should eq(400)
doc.parsed_response['error'].should eq(true)
doc.parsed_response['errorNum'].should eq(1202)
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, :output => "rest_delete-document-missing-handle")
end
end
end
end

View File

@ -125,7 +125,8 @@ describe AvocadoDB do
# get document, if-none-match with same rev
cmd = "/document/#{did}"
doc = AvocadoDB.get(cmd, :headers => { "if-none-match" => "\"#{rev}\"" })
hdr = { "if-none-match" => "\"#{rev}\"" }
doc = AvocadoDB.get(cmd, :headers => hdr)
doc.code.should eq(304)
@ -134,11 +135,12 @@ describe AvocadoDB do
etag.should eq("\"#{rev}\"")
AvocadoDB.log(:method => :get, :url => cmd, :result => doc, :output => "rest_read-document-if-none-match")
AvocadoDB.log(:method => :get, :url => cmd, :headers => hdr, :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}\"" })
hdr = { "if-none-match" => "\"#{rev-1}\"" }
doc = AvocadoDB.get(cmd, :headers => hdr)
doc.code.should eq(200)
doc.headers['content-type'].should eq("application/json; charset=utf-8")
@ -161,11 +163,12 @@ describe AvocadoDB do
etag.should eq("\"#{rev}\"")
AvocadoDB.log(:method => :get, :url => cmd, :result => doc, :output => "rest_read-document-if-none-match-other")
AvocadoDB.log(:method => :get, :url => cmd, :headers => hdr, :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}\"" })
hdr = { "if-match" => "\"#{rev}\"" }
doc = AvocadoDB.get(cmd, :headers => hdr)
doc.code.should eq(200)
doc.headers['content-type'].should eq("application/json; charset=utf-8")
@ -183,15 +186,17 @@ describe AvocadoDB do
etag.should eq("\"#{rev}\"")
AvocadoDB.log(:method => :get, :url => cmd, :result => doc, :output => "rest_read-document-if-match")
AvocadoDB.log(:method => :get, :url => cmd, :headers => hdr, :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}\"" })
hdr = { "if-match" => "\"#{rev-1}\"" }
doc = AvocadoDB.get(cmd, :headers => hdr)
doc.code.should eq(412)
doc.headers['content-length'].should eq(0)
AvocadoDB.log(:method => :get, :url => cmd, :result => doc, :output => "rest_read-document-if-match-other")
AvocadoDB.log(:method => :get, :url => cmd, :headers => hdr, :result => doc, :output => "rest_read-document-if-match-other")
AvocadoDB.delete(location)
end

View File

@ -1400,6 +1400,7 @@ static TRI_json_t* ConvertHelper(v8::Handle<v8::Value> parameter) {
TRI_json_t* result = ConvertHelper(item);
if (result) {
TRI_PushBack2ListJson(listJson, result);
TRI_Free(result);
}
}
}
@ -1416,6 +1417,7 @@ static TRI_json_t* ConvertHelper(v8::Handle<v8::Value> parameter) {
TRI_json_t* result = ConvertHelper(item);
if (result) {
TRI_Insert2ArrayJson(arrayJson, TRI_ObjectToString(key).c_str(), result);
TRI_Free(result);
}
}
}
@ -1544,7 +1546,6 @@ static v8::Handle<v8::Value> JS_StatementAql (v8::Arguments const& argv) {
parameters = ConvertHelper(argv[1]);
}
// TODO: properly free parameters
instance = TRI_CreateQueryInstance(template_, parameters);
if (!instance) {
if (parameters) {
@ -3078,7 +3079,7 @@ static v8::Handle<v8::Value> JS_DeleteVocbaseCol (v8::Arguments const& argv) {
// inside a write transaction
// .............................................................................
bool ok = collection->destroyLock(collection, did, 0, TRI_DOC_UPDATE_LAST_WRITE);
bool ok = collection->destroyLock(collection, did, 0, 0, TRI_DOC_UPDATE_LAST_WRITE);
// .............................................................................
// outside a write transaction
@ -4164,7 +4165,7 @@ static v8::Handle<v8::Value> JS_ReplaceVocbaseCol (v8::Arguments const& argv) {
// inside a write transaction
// .............................................................................
bool ok = collection->updateLock(collection, shaped, did, 0, TRI_DOC_UPDATE_LAST_WRITE);
bool ok = collection->updateLock(collection, shaped, did, 0, 0, TRI_DOC_UPDATE_LAST_WRITE);
// .............................................................................
// outside a write transaction
@ -4348,7 +4349,7 @@ static v8::Handle<v8::Value> JS_ReplaceEdgesCol (v8::Arguments const& argv) {
// inside a write transaction
// .............................................................................
bool ok = collection->updateLock(collection, shaped, did, 0, TRI_DOC_UPDATE_LAST_WRITE);
bool ok = collection->updateLock(collection, shaped, did, 0, 0, TRI_DOC_UPDATE_LAST_WRITE);
// .............................................................................
// outside a write transaction

View File

@ -56,6 +56,7 @@ using namespace triagens::avocado;
#include "js/common/bootstrap/js-print.h"
#include "js/common/bootstrap/js-modules.h"
#include "js/common/bootstrap/js-errors.h"
#include "js/client/js-client.h"
// -----------------------------------------------------------------------------
@ -1055,6 +1056,7 @@ int main (int argc, char* argv[]) {
if (StartupPath.empty()) {
StartupLoader.defineScript("common/bootstrap/modules.js", JS_common_bootstrap_modules);
StartupLoader.defineScript("common/bootstrap/print.js", JS_common_bootstrap_print);
StartupLoader.defineScript("common/bootstrap/errors.js", JS_common_bootstrap_errors);
StartupLoader.defineScript("client/client.js", JS_client_client);
}
else {
@ -1066,6 +1068,7 @@ int main (int argc, char* argv[]) {
char const* files[] = {
"common/bootstrap/modules.js",
"common/bootstrap/print.js",
"common/bootstrap/errors.js",
"client/client.js"
};

View File

@ -93,11 +93,12 @@ static bool UpdateLock (TRI_doc_collection_t* document,
TRI_shaped_json_t const* json,
TRI_voc_did_t did,
TRI_voc_rid_t rid,
TRI_voc_rid_t* oldRid,
TRI_doc_update_policy_e policy) {
TRI_doc_mptr_t const* result;
document->beginWrite(document);
result = document->update(document, json, did, rid, policy, true);
result = document->update(document, json, did, rid, oldRid, policy, true);
return result != NULL;
}
@ -110,6 +111,7 @@ static TRI_doc_mptr_t const* UpdateJson (TRI_doc_collection_t* collection,
TRI_json_t const* json,
TRI_voc_did_t did,
TRI_voc_rid_t rid,
TRI_voc_rid_t* oldRid,
TRI_doc_update_policy_e policy,
bool release) {
TRI_shaped_json_t* shaped;
@ -122,7 +124,7 @@ static TRI_doc_mptr_t const* UpdateJson (TRI_doc_collection_t* collection,
return false;
}
result = collection->update(collection, shaped, did, rid, policy, release);
result = collection->update(collection, shaped, did, rid, oldRid, policy, release);
TRI_FreeShapedJson(shaped);
@ -136,11 +138,12 @@ static TRI_doc_mptr_t const* UpdateJson (TRI_doc_collection_t* collection,
static bool DestroyLock (TRI_doc_collection_t* document,
TRI_voc_did_t did,
TRI_voc_rid_t rid,
TRI_voc_rid_t* oldRid,
TRI_doc_update_policy_e policy) {
bool ok;
document->beginWrite(document);
ok = document->destroy(document, did, rid, policy, true);
ok = document->destroy(document, did, rid, oldRid, policy, true);
return ok;
}

View File

@ -218,7 +218,7 @@ TRI_doc_collection_info_t;
/// of success. Otherwise, @c false is returned and the "TRI_errno()" is
/// accordingly. The function will acquire and release a write lock.
///
/// <b><tt>bool destroy (TRI_doc_collection_t*, TRI_voc_did_t, TRI_voc_rid_t, TRI_doc_update_policy_e, bool release)</tt></b>
/// <b><tt>bool destroy (TRI_doc_collection_t*, TRI_voc_did_t, TRI_voc_rid_t, TRI_voc_rid_t*, TRI_doc_update_policy_e, bool release)</tt></b>
///
/// Deletes an existing document of the collection and returns @c true in case
/// of success. Otherwise, @c false is returned and the "TRI_errno()" is
@ -263,12 +263,12 @@ typedef struct TRI_doc_collection_s {
TRI_doc_mptr_t const* (*read) (struct TRI_doc_collection_s*, TRI_voc_did_t);
TRI_doc_mptr_t const* (*update) (struct TRI_doc_collection_s*, TRI_shaped_json_t const*, TRI_voc_did_t, TRI_voc_rid_t, TRI_doc_update_policy_e, bool release);
TRI_doc_mptr_t const* (*updateJson) (struct TRI_doc_collection_s*, TRI_json_t const*, TRI_voc_did_t, TRI_voc_rid_t, TRI_doc_update_policy_e, bool release);
bool (*updateLock) (struct TRI_doc_collection_s*, TRI_shaped_json_t const*, TRI_voc_did_t, TRI_voc_rid_t, TRI_doc_update_policy_e);
TRI_doc_mptr_t const* (*update) (struct TRI_doc_collection_s*, TRI_shaped_json_t const*, TRI_voc_did_t, TRI_voc_rid_t, TRI_voc_rid_t*, TRI_doc_update_policy_e, bool release);
TRI_doc_mptr_t const* (*updateJson) (struct TRI_doc_collection_s*, TRI_json_t const*, TRI_voc_did_t, TRI_voc_rid_t, TRI_voc_rid_t*, TRI_doc_update_policy_e, bool release);
bool (*updateLock) (struct TRI_doc_collection_s*, TRI_shaped_json_t const*, TRI_voc_did_t, TRI_voc_rid_t, TRI_voc_rid_t*, TRI_doc_update_policy_e);
bool (*destroy) (struct TRI_doc_collection_s* collection, TRI_voc_did_t, TRI_voc_rid_t, TRI_doc_update_policy_e, bool release);
bool (*destroyLock) (struct TRI_doc_collection_s* collection, TRI_voc_did_t, TRI_voc_rid_t, TRI_doc_update_policy_e);
bool (*destroy) (struct TRI_doc_collection_s* collection, TRI_voc_did_t, TRI_voc_rid_t, TRI_voc_rid_t*, TRI_doc_update_policy_e, bool release);
bool (*destroyLock) (struct TRI_doc_collection_s* collection, TRI_voc_did_t, TRI_voc_rid_t, TRI_voc_rid_t*, TRI_doc_update_policy_e);
TRI_doc_collection_info_t* (*figures) (struct TRI_doc_collection_s* collection);
TRI_voc_size_t (*size) (struct TRI_doc_collection_s* collection);

View File

@ -36,8 +36,8 @@
#include <BasicsC/json.h>
#include "VocBase/vocbase.h"
#include "VocBase/voc-errors.h"
#include "VocBase/query-node.h"
#include "VocBase/query-error.h"
#include "QL/parser.h"
#include "QL/ast-query.h"

View File

@ -28,6 +28,10 @@
#include "VocBase/query-cursor.h"
#include "VocBase/query-context.h"
// -----------------------------------------------------------------------------
// --SECTION-- private functions
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup VocBase
/// @{
@ -49,6 +53,32 @@ static void RemoveCollectionsQueryCursor (TRI_query_cursor_t* cursor) {
cursor->_containers._length = 0;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief frees the data of a cursor
///
/// This will release any locks on the underlying collection data and might be
/// called before the actual cursor is disposed.
////////////////////////////////////////////////////////////////////////////////
static void FreeData (TRI_query_cursor_t* const cursor) {
if (cursor->_deleted) {
return;
}
cursor->_deleted = true;
assert(cursor->_functionCode);
TRI_Free(cursor->_functionCode);
// free result set
if (cursor->_result._selectResult) {
cursor->_result._selectResult->free(cursor->_result._selectResult);
}
// free select
RemoveCollectionsQueryCursor(cursor);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief returns the next element
////////////////////////////////////////////////////////////////////////////////
@ -61,6 +91,8 @@ static TRI_rc_result_t* NextQueryCursor (TRI_query_cursor_t* const cursor) {
return &cursor->_result;
}
FreeData(cursor);
return NULL;
}
@ -88,27 +120,33 @@ static uint32_t GetBatchSizeQueryCursor (const TRI_query_cursor_t* const cursor)
return cursor->_batchSize;
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- public functions
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup VocBase
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief frees a cursor
////////////////////////////////////////////////////////////////////////////////
void TRI_FreeQueryCursor (TRI_query_cursor_t* cursor) {
assert(cursor->_functionCode);
TRI_Free(cursor->_functionCode);
// free result set
if (cursor->_result._selectResult) {
cursor->_result._selectResult->free(cursor->_result._selectResult);
}
FreeData(cursor);
// free select
RemoveCollectionsQueryCursor(cursor);
TRI_DestroyMutex(&cursor->_lock);
TRI_DestroyVectorPointer(&cursor->_containers);
TRI_Free(cursor);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief create a cursor
////////////////////////////////////////////////////////////////////////////////

View File

@ -37,6 +37,10 @@
extern "C" {
#endif
// -----------------------------------------------------------------------------
// --SECTION-- public types
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup VocBase
/// @{
@ -67,6 +71,18 @@ typedef struct TRI_query_cursor_s {
}
TRI_query_cursor_t;
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- public functions
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup VocBase
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief frees a cursor

View File

@ -1,79 +0,0 @@
////////////////////////////////////////////////////////////////////////////////
/// @brief query errors
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2010-2012 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 triAGENS GmbH, Cologne, Germany
///
/// @author Jan Steemann
/// @author Copyright 2012, triagens GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#include "VocBase/query-error.h"
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup AvocadoErrors
/// @{
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- public functions
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief initialize query error definitions
////////////////////////////////////////////////////////////////////////////////
void TRI_InitialiseQueryErrors (void) {
REG_ERROR(OOM, "out of memory");
REG_ERROR(KILLED, "query killed");
REG_ERROR(PARSE, "parse error: %s");
REG_ERROR(EMPTY, "query is empty");
REG_ERROR(NUMBER_OUT_OF_RANGE, "number '%s' is out of range");
REG_ERROR(LIMIT_VALUE_OUT_OF_RANGE, "limit value '%s' is out of range");
REG_ERROR(TOO_MANY_JOINS, "too many joins");
REG_ERROR(COLLECTION_NAME_INVALID, "collection name '%s' is invalid");
REG_ERROR(COLLECTION_ALIAS_INVALID, "collection alias '%s' is invalid");
REG_ERROR(COLLECTION_ALIAS_REDECLARED, "collection alias '%s' is declared multiple times in the same query");
REG_ERROR(COLLECTION_ALIAS_UNDECLARED, "collection alias '%s' is used but was not declared in the from clause");
REG_ERROR(COLLECTION_NOT_FOUND, "unable to open collection '%s'");
REG_ERROR(GEO_RESTRICTION_INVALID, "geo restriction for alias '%s' is invalid");
REG_ERROR(GEO_INDEX_MISSING, "no suitable geo index found for geo restriction on '%s'");
REG_ERROR(BIND_PARAMETER_MISSING, "no value specified for bind parameter '%s'");
REG_ERROR(BIND_PARAMETER_REDECLARED, "value for bind parameter '%s' is declared multiple times");
REG_ERROR(BIND_PARAMETER_UNDECLARED, "bind parameter '%s' was not declared in the query");
REG_ERROR(BIND_PARAMETER_VALUE_INVALID, "invalid value for bind parameter '%s'");
REG_ERROR(BIND_PARAMETER_NUMBER_OUT_OF_RANGE, "bind parameter number '%s' out of range");
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// Local Variables:
// mode: outline-minor
// outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|// --SECTION--\\|/// @\\}\\)"
// End:

View File

@ -1,249 +0,0 @@
////////////////////////////////////////////////////////////////////////////////
/// @brief query errors
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2010-2012 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 triAGENS GmbH, Cologne, Germany
///
/// @author Jan Steemann
/// @author Copyright 2012, triagens GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#ifndef DURHAM_STORAGE_VOCBASE_QUERY_ERROR_H
#define DURHAM_STORAGE_VOCBASE_QUERY_ERROR_H 1
#include <BasicsC/common.h>
#ifdef __cplusplus
extern "C" {
#endif
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup AvocadoErrors
/// @{
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- definitions
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief error numbers for specific errors during query parsing and execution
///
/// Note that the error numbers defined here must not conflict with error
/// numbers defined for other parts of the program (e.g. in VocBase/vocbase.h)
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_QUERY_BASE (1500)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1500: Out of memory.
///
/// Will be raised during query execution when a memory allocation request can
/// not be satisfied.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_QUERY_OOM (1500)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1501: Query was killed by administrator.
///
/// Will be raised when a running query is killed by an explicit admin command.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_QUERY_KILLED (1501)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1510: Parse error.
///
/// Will be raised when query is parsed and is found to be syntactially invalid.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_QUERY_PARSE (1510)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1511: Query is emtpy / no command specified.
///
/// Will be raised when an empty query is specified.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_QUERY_EMPTY (1511)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1520: Specified numeric value is out of range.
///
/// Will be raised when a numeric value inside a query is out of the allowed
/// value range.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_QUERY_NUMBER_OUT_OF_RANGE (1520)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1521: Specified limit value is out of range.
///
/// Will be raised when a limit value in the query is outside the allowed range
/// (e. g. when passing a negative skip value)
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_QUERY_LIMIT_VALUE_OUT_OF_RANGE (1521)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1540: Too many joins.
///
/// Will be raised when the number of joins in a query is beyond the allowed
/// value.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_QUERY_TOO_MANY_JOINS (1540)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1550: Invalid name for collection.
///
/// Will be raised when an invalid collection name is used in the from clause
/// of a query.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_QUERY_COLLECTION_NAME_INVALID (1550)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1551: Invalid alias for collection.
///
/// Will be raised when an invalid alias name is used for a collection.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_QUERY_COLLECTION_ALIAS_INVALID (1551)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1552: Redeclaration of alias within query.
///
/// Will be raised when the same alias name is declared multiple times in the
/// same query's from clause.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_QUERY_COLLECTION_ALIAS_REDECLARED (1552)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1553: Usage of undeclared alias in query.
///
/// Will be raised when an alias not declared in the from clause is used in the
/// query.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_QUERY_COLLECTION_ALIAS_UNDECLARED (1553)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1560: Collection not found.
///
/// Will be raised when one of the collections referenced in the query was not
/// found.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_QUERY_COLLECTION_NOT_FOUND (1560)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1570: Invalid geo restriction specification.
///
/// Will be raised when a specified geo restriction is invalid.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_QUERY_GEO_RESTRICTION_INVALID (1570)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1571: No suitable geo index found to resolve query.
///
/// Will be raised when a geo restriction was specified but no suitable geo
/// index is found to resolve it.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_QUERY_GEO_INDEX_MISSING (1571)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1590: No value specified for declared bind parameter.
///
/// Will be raised when a bind parameter was declared in the query but the
/// query is being executed with no value for that parameter.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_QUERY_BIND_PARAMETER_MISSING (1590)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1591: Redeclaration of same bind parameter value.
///
/// Will be raised when a value gets specified multiple times for the same bind
/// parameter.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_QUERY_BIND_PARAMETER_REDECLARED (1591)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1592: Value specified for undeclared bind parameter.
///
/// Will be raised when a value gets specified for an undeclared bind parameter.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_QUERY_BIND_PARAMETER_UNDECLARED (1592)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1593: Invalid value for bind parameter.
///
/// Will be raised when an invalid value is specified for one of the bind
/// parameters.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_QUERY_BIND_PARAMETER_VALUE_INVALID (1593)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1594: Bind parameter number is out of range.
///
/// Will be specified when the numeric index for a bind parameter of type
/// @LIT{\@n} is out of the allowed range.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_QUERY_BIND_PARAMETER_NUMBER_OUT_OF_RANGE (1594)
////////////////////////////////////////////////////////////////////////////////
/// @brief helper macro to define an error string
////////////////////////////////////////////////////////////////////////////////
#define REG_ERROR(id, label) TRI_set_errno_string(TRI_ERROR_QUERY_ ## id, label);
// -----------------------------------------------------------------------------
// --SECTION-- public functions
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief initialize query error definitions
////////////////////////////////////////////////////////////////////////////////
void TRI_InitialiseQueryErrors (void);
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
#ifdef __cplusplus
}
#endif
#endif
// Local Variables:
// mode: outline-minor
// outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|// --SECTION--\\|/// @\\}\\)"
// End:

View File

@ -28,8 +28,8 @@
#ifndef TRIAGENS_DURHAM_VOC_BASE_QUERY_PARSE_H
#define TRIAGENS_DURHAM_VOC_BASE_QUERY_PARSE_H 1
#include "VocBase/voc-errors.h"
#include "VocBase/query-base.h"
#include "VocBase/query-error.h"
#include "VocBase/query-memory.h"
#include "QL/optimize.h"

View File

@ -360,6 +360,7 @@ static TRI_doc_mptr_t const* UpdateDocument (TRI_sim_collection_t* collection,
void const* body,
TRI_voc_size_t bodySize,
TRI_voc_rid_t rid,
TRI_voc_rid_t* oldRid,
TRI_doc_update_policy_e policy,
TRI_df_marker_t** result,
bool release) {
@ -368,6 +369,10 @@ static TRI_doc_mptr_t const* UpdateDocument (TRI_sim_collection_t* collection,
bool ok;
// check the revision
if (oldRid != NULL) {
*oldRid = header->_rid;
}
switch (policy) {
case TRI_DOC_UPDATE_ERROR:
if (rid != 0) {
@ -482,6 +487,7 @@ static TRI_doc_mptr_t const* UpdateDocument (TRI_sim_collection_t* collection,
static bool DeleteDocument (TRI_sim_collection_t* collection,
TRI_doc_deletion_marker_t* marker,
TRI_voc_rid_t rid,
TRI_voc_rid_t* oldRid,
TRI_doc_update_policy_e policy,
bool release) {
TRI_datafile_t* journal;
@ -504,6 +510,10 @@ static bool DeleteDocument (TRI_sim_collection_t* collection,
}
// check the revision
if (oldRid != NULL) {
*oldRid = header->_rid;
}
switch (policy) {
case TRI_DOC_UPDATE_ERROR:
if (rid != 0) {
@ -800,6 +810,7 @@ static TRI_doc_mptr_t const* UpdateShapedJson (TRI_doc_collection_t* document,
TRI_shaped_json_t const* json,
TRI_voc_did_t did,
TRI_voc_rid_t rid,
TRI_voc_rid_t* oldRid,
TRI_doc_update_policy_e policy,
bool release) {
TRI_df_marker_t const* original;
@ -838,6 +849,7 @@ static TRI_doc_mptr_t const* UpdateShapedJson (TRI_doc_collection_t* document,
&marker, sizeof(marker),
json->_data.data, json->_data.length,
rid,
oldRid,
policy,
&result,
release);
@ -870,6 +882,7 @@ static TRI_doc_mptr_t const* UpdateShapedJson (TRI_doc_collection_t* document,
&marker.base, sizeof(marker),
json->_data.data, json->_data.length,
rid,
oldRid,
policy,
&result,
release);
@ -889,6 +902,7 @@ static TRI_doc_mptr_t const* UpdateShapedJson (TRI_doc_collection_t* document,
static bool DeleteShapedJson (TRI_doc_collection_t* document,
TRI_voc_did_t did,
TRI_voc_rid_t rid,
TRI_voc_rid_t* oldRid,
TRI_doc_update_policy_e policy,
bool release) {
TRI_sim_collection_t* collection;
@ -904,7 +918,7 @@ static bool DeleteShapedJson (TRI_doc_collection_t* document,
marker._did = did;
marker._sid = 0;
return DeleteDocument(collection, &marker, rid, policy, release);
return DeleteDocument(collection, &marker, rid, oldRid, policy, release);
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -1,289 +0,0 @@
////////////////////////////////////////////////////////////////////////////////
/// @brief vocbase error codes
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2010-2012 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 triAGENS GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
/// @author Jan Steemann
/// @author Copyright 2012, triagens GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#ifndef TRIAGENS_DURHAM_VOC_VOCBASE_VOC_ERROR_H
#define TRIAGENS_DURHAM_VOC_VOCBASE_VOC_ERROR_H 1
#ifdef __cplusplus
extern "C" {
#endif
// -----------------------------------------------------------------------------
// --SECTION-- public constants
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup AvocadoErrors
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief error codes
///
/// If you add a new error code, you must also add the description in @ref
/// TRI_InitialiseVocBase.
///
/// Please note that the error numbers defined here must not conflict with error
/// numbers defined for other parts of the program (e.g. in
/// VocBase/query-error.h)
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_BEGIN (1000)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1000: Illegal state.
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_ILLEGAL_STATE (1000)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1001: Shaper failed.
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_SHAPER_FAILED (1001)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1002: Corrupted datafile.
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_CORRUPTED_DATAFILE (1002)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1003: mmap failed.
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_MMAP_FAILED (1003)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1004: msync failed.
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_MSYNC_FAILED (1004)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1005: No journal.
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_NO_JOURNAL (1005)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1006: Datafile sealed.
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_DATAFILE_SEALED (1006)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1007: Corrupted collection.
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_CORRUPTED_COLLECTION (1007)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1008: Unknown type.
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_UNKNOWN_TYPE (1008)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1009: Illegal parameter.
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_ILLEGAL_PARAMETER (1009)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1010: Index exists.
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_INDEX_EXISTS (1010)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1011: Conflict.
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_CONFLICT (1011)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1100: Wrong path.
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_WRONG_PATH (1100)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1101: Cannot rename.
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_CANNOT_RENAME (1101)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1102: Write failed.
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_WRITE_FAILED (1102)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1103: Read only.
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_READ_ONLY (1103)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1104: Datafile full.
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_DATAFILE_FULL (1104)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1105: Filesystem full.
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_FILESYSTEM_FULL (1105)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1106: Read failed.
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_READ_FAILED (1106)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1107: File not found.
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_FILE_NOT_FOUND (1107)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1108: File not accessible.
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_FILE_NOT_ACCESSIBLE (1108)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1200: Document not found.
///
/// Will be raised when a document with a given identifier or handle is unknown.
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_DOCUMENT_NOT_FOUND (1200)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1201: Collection not found.
///
/// Will be raised when a collection with a given identifier or name is unknown.
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_COLLECTION_NOT_FOUND (1201)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1202: Parameter collection not found.
///
/// Will be raised when the collection parameter is missing.
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_COLLECTION_PARAMETER_MISSING (1202)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1203: Document altered.
///
/// Will be raised when a document has been altered and a change would
/// result in a conflict.
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_DOCUMENT_ALTERED (1203)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1203: Illegal document handle.
///
/// Will be raised when a document handle is corrupt.
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_DOCUMENT_HANDLE_BAD (1204)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1205: Collection already exists.
///
/// Will be raised when a collection with a given identifier or name already
/// exists.
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_COLLECTION_EXISTS (1205)
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
#ifdef __cplusplus
}
#endif
#endif
// Local Variables:
// mode: outline-minor
// outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|// --SECTION--\\|/// @\\}\\)"
// End:

62
VocBase/voc-errors.c Normal file
View File

@ -0,0 +1,62 @@
////////////////////////////////////////////////////////////////////////////////
/// @brief auto-generated file generated from errors.dat
////////////////////////////////////////////////////////////////////////////////
#include <BasicsC/common.h>
#include "VocBase/voc-errors.h"
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup VocError
/// @{
////////////////////////////////////////////////////////////////////////////////
void TRI_InitialiseAvocadoErrors (void) {
REG_ERROR(VOC_ERROR_ILLEGAL_STATE, "illegal state");
REG_ERROR(VOC_ERROR_SHAPER_FAILED, "illegal shaper");
REG_ERROR(VOC_ERROR_CORRUPTED_DATAFILE, "corrupted datafile");
REG_ERROR(VOC_ERROR_MMAP_FAILED, "mmap failed");
REG_ERROR(VOC_ERROR_MSYNC_FAILED, "msync failed");
REG_ERROR(VOC_ERROR_NO_JOURNAL, "no journal");
REG_ERROR(VOC_ERROR_DATAFILE_SEALED, "datafile sealed");
REG_ERROR(VOC_ERROR_CORRUPTED_COLLECTION, "corrupted collection");
REG_ERROR(VOC_ERROR_UNKNOWN_TYPE, "unknown type");
REG_ERROR(VOC_ERROR_ILLEGAL_PARAMETER, "illegal parameter");
REG_ERROR(VOC_ERROR_INDEX_EXISTS, "index exists");
REG_ERROR(VOC_ERROR_CONFLICT, "conflict");
REG_ERROR(VOC_ERROR_WRONG_PATH, "wrong path");
REG_ERROR(VOC_ERROR_CANNOT_RENAME, "cannot rename");
REG_ERROR(VOC_ERROR_WRITE_FAILED, "write failed");
REG_ERROR(VOC_ERROR_READ_ONLY, "ready only");
REG_ERROR(VOC_ERROR_DATAFILE_FULL, "datafile full");
REG_ERROR(VOC_ERROR_FILESYSTEM_FULL, "filesystem full");
REG_ERROR(VOC_ERROR_READ_FAILED, "read failed");
REG_ERROR(VOC_ERROR_FILE_NOT_FOUND, "file not found");
REG_ERROR(VOC_ERROR_FILE_NOT_ACCESSIBLE, "file not accessible");
REG_ERROR(VOC_ERROR_DOCUMENT_NOT_FOUND, "document not found");
REG_ERROR(ERROR_QUERY_OOM, "out of memory");
REG_ERROR(ERROR_QUERY_KILLED, "query killed");
REG_ERROR(ERROR_QUERY_PARSE, "parse error: %s");
REG_ERROR(ERROR_QUERY_EMPTY, "query is empty");
REG_ERROR(ERROR_QUERY_SPECIFICATION_INVALID, "query specification invalid");
REG_ERROR(ERROR_QUERY_NUMBER_OUT_OF_RANGE, "number '%s' is out of range");
REG_ERROR(ERROR_QUERY_LIMIT_VALUE_OUT_OF_RANGE, "limit value '%s' is out of range");
REG_ERROR(ERROR_QUERY_TOO_MANY_JOINS, "too many joins.");
REG_ERROR(ERROR_QUERY_COLLECTION_NAME_INVALID, "collection name '%s' is invalid");
REG_ERROR(ERROR_QUERY_COLLECTION_ALIAS_INVALID, "collection alias '%s' is invalid");
REG_ERROR(ERROR_QUERY_COLLECTION_ALIAS_REDECLARED, "collection alias '%s' is declared multiple times in the same query");
REG_ERROR(ERROR_QUERY_COLLECTION_ALIAS_UNDECLARED, "collection alias '%s' is used but was not declared in the from clause");
REG_ERROR(ERROR_QUERY_COLLECTION_NOT_FOUND, "unable to open collection '%s'");
REG_ERROR(ERROR_QUERY_GEO_RESTRICTION_INVALID, "geo restriction for alias '%s' is invalid");
REG_ERROR(ERROR_QUERY_GEO_INDEX_MISSING, "no suitable geo index found for geo restriction on '%s'");
REG_ERROR(ERROR_QUERY_BIND_PARAMETER_MISSING, "no value specified for declared bind parameter '%s'");
REG_ERROR(ERROR_QUERY_BIND_PARAMETER_REDECLARED, "value for bind parameter '%s' is declared multiple times");
REG_ERROR(ERROR_QUERY_BIND_PARAMETER_UNDECLARED, "bind parameter '%s' was not declared in the query");
REG_ERROR(ERROR_QUERY_BIND_PARAMETER_VALUE_INVALID, "invalid value for bind parameter '%s'");
REG_ERROR(ERROR_QUERY_BIND_PARAMETER_NUMBER_OUT_OF_RANGE, "bind parameter number '%s' out of range");
REG_ERROR(ERROR_CURSOR_NOT_FOUND, "cursor not found");
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

592
VocBase/voc-errors.h Normal file
View File

@ -0,0 +1,592 @@
#ifndef TRIAGENS_DURHAM_VOC_BASE_ERRORS_H
#define TRIAGENS_DURHAM_VOC_BASE_ERRORS_H 1
#ifdef __cplusplus
extern "C" {
#endif
////////////////////////////////////////////////////////////////////////////////
/// @page AvocadoErrors Error codes and meanings
///
/// The following errors might be raised when running AvocadoDB:
///
/// - 1000: @CODE{illegal state}
/// TODO
/// - 1001: @CODE{illegal shaper}
/// TODO
/// - 1002: @CODE{corrupted datafile}
/// TODO
/// - 1003: @CODE{mmap failed}
/// TODO
/// - 1004: @CODE{msync failed}
/// TODO
/// - 1005: @CODE{no journal}
/// TODO
/// - 1006: @CODE{datafile sealed}
/// TODO
/// - 1007: @CODE{corrupted collection}
/// TODO
/// - 1008: @CODE{unknown type}
/// TODO
/// - 1009: @CODE{illegal parameter}
/// TODO
/// - 1010: @CODE{index exists}
/// TODO
/// - 1011: @CODE{conflict}
/// TODO
/// - 1100: @CODE{wrong path}
/// TODO
/// - 1101: @CODE{cannot rename}
/// TODO
/// - 1102: @CODE{write failed}
/// TODO
/// - 1103: @CODE{ready only}
/// TODO
/// - 1104: @CODE{datafile full}
/// TODO
/// - 1105: @CODE{filesystem full}
/// TODO
/// - 1106: @CODE{read failed}
/// TODO
/// - 1107: @CODE{file not found}
/// TODO
/// - 1108: @CODE{file not accessible}
/// TODO
/// - 1200: @CODE{document not found}
/// TODO
/// - 1500: @CODE{out of memory}
/// Will be raised during query execution when a memory allocation request
/// can not be satisfied.
/// - 1501: @CODE{query killed}
/// Will be raised when a running query is killed by an explicit admin
/// command.
/// - 1510: @CODE{parse error: \%s}
/// Will be raised when query is parsed and is found to be syntactially
/// invalid.
/// - 1511: @CODE{query is empty}
/// Will be raised when an empty query is specified.
/// - 1512: @CODE{query specification invalid}
/// Will be raised when a query is sent to the server with an incomplete or
/// invalid query specification structure.
/// - 1520: @CODE{number '\%s' is out of range}
/// Will be raised when a numeric value inside a query is out of the allowed
/// value range.
/// - 1521: @CODE{limit value '\%s' is out of range}
/// Will be raised when a limit value in the query is outside the allowed
/// range (e. g. when passing a negative skip value).
/// - 1540: @CODE{too many joins.}
/// Will be raised when the number of joins in a query is beyond the allowed
/// value.
/// - 1550: @CODE{collection name '\%s' is invalid}
/// Will be raised when an invalid collection name is used in the from clause
/// of a query.
/// - 1551: @CODE{collection alias '\%s' is invalid}
/// Will be raised when an invalid alias name is used for a collection.
/// - 1552: @CODE{collection alias '\%s' is declared multiple times in the same query}
/// Will be raised when the same alias name is declared multiple times in the
/// same query's from clause.
/// - 1553: @CODE{collection alias '\%s' is used but was not declared in the from clause}
/// Will be raised when an alias not declared in the from clause is used in
/// the query.
/// - 1560: @CODE{unable to open collection '\%s'}
/// Will be raised when one of the collections referenced in the query was
/// not found.
/// - 1570: @CODE{geo restriction for alias '\%s' is invalid}
/// Will be raised when a specified geo restriction is invalid.
/// - 1571: @CODE{no suitable geo index found for geo restriction on '\%s'}
/// Will be raised when a geo restriction was specified but no suitable geo
/// index is found to resolve it.
/// - 1590: @CODE{no value specified for declared bind parameter '\%s'}
/// Will be raised when a bind parameter was declared in the query but the
/// query is being executed with no value for that parameter.
/// - 1591: @CODE{value for bind parameter '\%s' is declared multiple times}
/// Will be raised when a value gets specified multiple times for the same
/// bind parameter.
/// - 1592: @CODE{bind parameter '\%s' was not declared in the query}
/// Will be raised when a value gets specified for an undeclared bind
/// parameter.
/// - 1593: @CODE{invalid value for bind parameter '\%s'}
/// Will be raised when an invalid value is specified for one of the bind
/// parameters.
/// - 1594: @CODE{bind parameter number '\%s' out of range}
/// Will be specified when the numeric index for a bind parameter of type @n
/// is out of the allowed range.
/// - 1600: @CODE{cursor not found}
/// Will be raised when a cursor is requested via its id but a cursor with
/// that id cannot be found.
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup VocError
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief helper macro to define an error string
////////////////////////////////////////////////////////////////////////////////
#define REG_ERROR(id, label) TRI_set_errno_string(TRI_ ## id, label);
////////////////////////////////////////////////////////////////////////////////
/// @brief register all errors for AvocadoDB
////////////////////////////////////////////////////////////////////////////////
void TRI_InitialiseAvocadoErrors (void);
////////////////////////////////////////////////////////////////////////////////
/// @brief 1000: VOC_ERROR_ILLEGAL_STATE
///
/// illegal state
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_ILLEGAL_STATE (1000)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1001: VOC_ERROR_SHAPER_FAILED
///
/// illegal shaper
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_SHAPER_FAILED (1001)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1002: VOC_ERROR_CORRUPTED_DATAFILE
///
/// corrupted datafile
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_CORRUPTED_DATAFILE (1002)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1003: VOC_ERROR_MMAP_FAILED
///
/// mmap failed
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_MMAP_FAILED (1003)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1004: VOC_ERROR_MSYNC_FAILED
///
/// msync failed
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_MSYNC_FAILED (1004)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1005: VOC_ERROR_NO_JOURNAL
///
/// no journal
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_NO_JOURNAL (1005)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1006: VOC_ERROR_DATAFILE_SEALED
///
/// datafile sealed
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_DATAFILE_SEALED (1006)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1007: VOC_ERROR_CORRUPTED_COLLECTION
///
/// corrupted collection
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_CORRUPTED_COLLECTION (1007)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1008: VOC_ERROR_UNKNOWN_TYPE
///
/// unknown type
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_UNKNOWN_TYPE (1008)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1009: VOC_ERROR_ILLEGAL_PARAMETER
///
/// illegal parameter
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_ILLEGAL_PARAMETER (1009)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1010: VOC_ERROR_INDEX_EXISTS
///
/// index exists
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_INDEX_EXISTS (1010)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1011: VOC_ERROR_CONFLICT
///
/// conflict
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_CONFLICT (1011)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1100: VOC_ERROR_WRONG_PATH
///
/// wrong path
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_WRONG_PATH (1100)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1101: VOC_ERROR_CANNOT_RENAME
///
/// cannot rename
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_CANNOT_RENAME (1101)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1102: VOC_ERROR_WRITE_FAILED
///
/// write failed
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_WRITE_FAILED (1102)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1103: VOC_ERROR_READ_ONLY
///
/// ready only
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_READ_ONLY (1103)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1104: VOC_ERROR_DATAFILE_FULL
///
/// datafile full
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_DATAFILE_FULL (1104)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1105: VOC_ERROR_FILESYSTEM_FULL
///
/// filesystem full
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_FILESYSTEM_FULL (1105)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1106: VOC_ERROR_READ_FAILED
///
/// read failed
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_READ_FAILED (1106)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1107: VOC_ERROR_FILE_NOT_FOUND
///
/// file not found
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_FILE_NOT_FOUND (1107)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1108: VOC_ERROR_FILE_NOT_ACCESSIBLE
///
/// file not accessible
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_FILE_NOT_ACCESSIBLE (1108)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1200: VOC_ERROR_DOCUMENT_NOT_FOUND
///
/// document not found
///
/// TODO
////////////////////////////////////////////////////////////////////////////////
#define TRI_VOC_ERROR_DOCUMENT_NOT_FOUND (1200)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1500: ERROR_QUERY_OOM
///
/// out of memory
///
/// Will be raised during query execution when a memory allocation request can
/// not be satisfied.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_QUERY_OOM (1500)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1501: ERROR_QUERY_KILLED
///
/// query killed
///
/// Will be raised when a running query is killed by an explicit admin command.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_QUERY_KILLED (1501)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1510: ERROR_QUERY_PARSE
///
/// parse error: %s
///
/// Will be raised when query is parsed and is found to be syntactially invalid.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_QUERY_PARSE (1510)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1511: ERROR_QUERY_EMPTY
///
/// query is empty
///
/// Will be raised when an empty query is specified.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_QUERY_EMPTY (1511)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1512: ERROR_QUERY_SPECIFICATION_INVALID
///
/// query specification invalid
///
/// Will be raised when a query is sent to the server with an incomplete or
/// invalid query specification structure.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_QUERY_SPECIFICATION_INVALID (1512)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1520: ERROR_QUERY_NUMBER_OUT_OF_RANGE
///
/// number '%s' is out of range
///
/// Will be raised when a numeric value inside a query is out of the allowed
/// value range.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_QUERY_NUMBER_OUT_OF_RANGE (1520)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1521: ERROR_QUERY_LIMIT_VALUE_OUT_OF_RANGE
///
/// limit value '%s' is out of range
///
/// Will be raised when a limit value in the query is outside the allowed range
/// (e. g. when passing a negative skip value).
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_QUERY_LIMIT_VALUE_OUT_OF_RANGE (1521)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1540: ERROR_QUERY_TOO_MANY_JOINS
///
/// too many joins.
///
/// Will be raised when the number of joins in a query is beyond the allowed
/// value.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_QUERY_TOO_MANY_JOINS (1540)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1550: ERROR_QUERY_COLLECTION_NAME_INVALID
///
/// collection name '%s' is invalid
///
/// Will be raised when an invalid collection name is used in the from clause
/// of a query.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_QUERY_COLLECTION_NAME_INVALID (1550)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1551: ERROR_QUERY_COLLECTION_ALIAS_INVALID
///
/// collection alias '%s' is invalid
///
/// Will be raised when an invalid alias name is used for a collection.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_QUERY_COLLECTION_ALIAS_INVALID (1551)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1552: ERROR_QUERY_COLLECTION_ALIAS_REDECLARED
///
/// collection alias '%s' is declared multiple times in the same query
///
/// Will be raised when the same alias name is declared multiple times in the
/// same query's from clause.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_QUERY_COLLECTION_ALIAS_REDECLARED (1552)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1553: ERROR_QUERY_COLLECTION_ALIAS_UNDECLARED
///
/// collection alias '%s' is used but was not declared in the from clause
///
/// Will be raised when an alias not declared in the from clause is used in the
/// query.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_QUERY_COLLECTION_ALIAS_UNDECLARED (1553)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1560: ERROR_QUERY_COLLECTION_NOT_FOUND
///
/// unable to open collection '%s'
///
/// Will be raised when one of the collections referenced in the query was not
/// found.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_QUERY_COLLECTION_NOT_FOUND (1560)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1570: ERROR_QUERY_GEO_RESTRICTION_INVALID
///
/// geo restriction for alias '%s' is invalid
///
/// Will be raised when a specified geo restriction is invalid.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_QUERY_GEO_RESTRICTION_INVALID (1570)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1571: ERROR_QUERY_GEO_INDEX_MISSING
///
/// no suitable geo index found for geo restriction on '%s'
///
/// Will be raised when a geo restriction was specified but no suitable geo
/// index is found to resolve it.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_QUERY_GEO_INDEX_MISSING (1571)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1590: ERROR_QUERY_BIND_PARAMETER_MISSING
///
/// no value specified for declared bind parameter '%s'
///
/// Will be raised when a bind parameter was declared in the query but the
/// query is being executed with no value for that parameter.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_QUERY_BIND_PARAMETER_MISSING (1590)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1591: ERROR_QUERY_BIND_PARAMETER_REDECLARED
///
/// value for bind parameter '%s' is declared multiple times
///
/// Will be raised when a value gets specified multiple times for the same bind
/// parameter.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_QUERY_BIND_PARAMETER_REDECLARED (1591)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1592: ERROR_QUERY_BIND_PARAMETER_UNDECLARED
///
/// bind parameter '%s' was not declared in the query
///
/// Will be raised when a value gets specified for an undeclared bind parameter.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_QUERY_BIND_PARAMETER_UNDECLARED (1592)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1593: ERROR_QUERY_BIND_PARAMETER_VALUE_INVALID
///
/// invalid value for bind parameter '%s'
///
/// Will be raised when an invalid value is specified for one of the bind
/// parameters.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_QUERY_BIND_PARAMETER_VALUE_INVALID (1593)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1594: ERROR_QUERY_BIND_PARAMETER_NUMBER_OUT_OF_RANGE
///
/// bind parameter number '%s' out of range
///
/// Will be specified when the numeric index for a bind parameter of type @n is
/// out of the allowed range.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_QUERY_BIND_PARAMETER_NUMBER_OUT_OF_RANGE (1594)
////////////////////////////////////////////////////////////////////////////////
/// @brief 1600: ERROR_CURSOR_NOT_FOUND
///
/// cursor not found
///
/// Will be raised when a cursor is requested via its id but a cursor with that
/// id cannot be found.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_CURSOR_NOT_FOUND (1600)
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
#ifdef __cplusplus
}
#endif
#endif

View File

@ -890,44 +890,7 @@ void TRI_InitialiseVocBase () {
TRI_InitSpin(&TickLock);
// general errors
TRI_set_errno_string(TRI_VOC_ERROR_ILLEGAL_STATE, "illegal state");
TRI_set_errno_string(TRI_VOC_ERROR_SHAPER_FAILED, "illegal shaper");
TRI_set_errno_string(TRI_VOC_ERROR_CORRUPTED_DATAFILE, "corrupted datafile");
TRI_set_errno_string(TRI_VOC_ERROR_MMAP_FAILED, "mmap failed");
TRI_set_errno_string(TRI_VOC_ERROR_MSYNC_FAILED, "msync failed");
TRI_set_errno_string(TRI_VOC_ERROR_NO_JOURNAL, "no journal");
TRI_set_errno_string(TRI_VOC_ERROR_DATAFILE_SEALED, "datafile sealed");
TRI_set_errno_string(TRI_VOC_ERROR_CORRUPTED_COLLECTION, "corrupted collection");
TRI_set_errno_string(TRI_VOC_ERROR_UNKNOWN_TYPE, "unknown type");
TRI_set_errno_string(TRI_VOC_ERROR_ILLEGAL_PARAMETER, "illegal paramater");
TRI_set_errno_string(TRI_VOC_ERROR_INDEX_EXISTS, "index exists");
TRI_set_errno_string(TRI_VOC_ERROR_CONFLICT, "conflict");
// open errors
TRI_set_errno_string(TRI_VOC_ERROR_WRONG_PATH, "wrong path");
// close errors
TRI_set_errno_string(TRI_VOC_ERROR_CANNOT_RENAME, "cannot rename");
// write errors
TRI_set_errno_string(TRI_VOC_ERROR_WRITE_FAILED, "write failed");
TRI_set_errno_string(TRI_VOC_ERROR_READ_ONLY, "read only");
TRI_set_errno_string(TRI_VOC_ERROR_DATAFILE_FULL, "datafile full");
TRI_set_errno_string(TRI_VOC_ERROR_FILESYSTEM_FULL, "filesystem full");
// read errors
TRI_set_errno_string(TRI_VOC_ERROR_READ_FAILED, "read failed");
TRI_set_errno_string(TRI_VOC_ERROR_FILE_NOT_FOUND, "file not found");
TRI_set_errno_string(TRI_VOC_ERROR_FILE_NOT_ACCESSIBLE, "file not accessible");
// api errors
TRI_set_errno_string(TRI_VOC_ERROR_COLLECTION_EXISTS, "collection already exists");
TRI_set_errno_string(TRI_VOC_ERROR_COLLECTION_NOT_FOUND, "collection not found");
TRI_set_errno_string(TRI_VOC_ERROR_COLLECTION_PARAMETER_MISSING, "parameter <collection> is missing");
TRI_set_errno_string(TRI_VOC_ERROR_DOCUMENT_ALTERED, "document has been altered");
TRI_set_errno_string(TRI_VOC_ERROR_DOCUMENT_HANDLE_BAD, "illegal or corrupted document handle");
TRI_set_errno_string(TRI_VOC_ERROR_DOCUMENT_NOT_FOUND, "document not found");
TRI_InitialiseAvocadoErrors();
#ifdef TRI_READLINE_VERSION
LOG_TRACE("%s", "$Revision: READLINE " TRI_READLINE_VERSION " $");

View File

@ -35,7 +35,7 @@
#include <BasicsC/threads.h>
#include <BasicsC/vector.h>
#include "VocBase/voc-error.h"
#include "VocBase/voc-errors.h"
#ifdef __cplusplus
extern "C" {

View File

@ -84,7 +84,7 @@ function getCursorResult(cursor) {
function postCursor(req, res) {
if (req.suffix.length != 0) {
actions.actionResultError (req, res, 400, actions.cursorNotModified, "Invalid query data");
actions.actionResultError (req, res, 404, actions.errorInvalidRequest, "Invalid request");
return;
}
@ -92,7 +92,7 @@ function postCursor(req, res) {
var json = JSON.parse(req.requestBody);
if (!json || !(json instanceof Object)) {
actions.actionResultError (req, res, 400, actions.cursorNotModified, "Invalid query data");
actions.actionResultError (req, res, 400, actions.errorQuerySpecificationInvalid, "Query specification invalid");
return;
}
@ -104,11 +104,12 @@ function postCursor(req, res) {
(json.batchSize != undefined ? json.batchSize : 1000));
}
else {
actions.actionResultError (req, res, 400, actions.cursorNotModified, "Invalid query data");
actions.actionResultError (req, res, 400, actions.errorQuerySpecificationInvalid, "Query specification invalid");
return;
}
if (cursor instanceof AvocadoQueryError) {
// error occurred
actions.actionResultError (req, res, 404, cursor.code, cursor.message);
return;
}
@ -119,7 +120,7 @@ function postCursor(req, res) {
actions.actionResultOK(req, res, 201, result);
}
catch (e) {
actions.actionResultError (req, res, 404, actions.cursorNotModified, "Cursor not created");
actions.actionResultError (req, res, 404, actions.errorJavascriptException, "Javascript exception");
}
}
@ -129,7 +130,7 @@ function postCursor(req, res) {
function putCursor(req, res) {
if (req.suffix.length != 1) {
actions.actionResultError (req, res, 404, actions.cursorNotFound, "Cursor not found");
actions.actionResultError (req, res, 404, actions.errorInvalidRequest, "Invalid request");
return;
}
@ -144,7 +145,7 @@ function putCursor(req, res) {
actions.actionResultOK(req, res, 200, getCursorResult(cursor));
}
catch (e) {
actions.actionResultError (req, res, 404, actions.cursorNotFound, "Cursor not found");
actions.actionResultError (req, res, 404, actions.errorCursorNotFound, "Cursor not found");
}
}
@ -154,7 +155,7 @@ function putCursor(req, res) {
function deleteCursor(req, res) {
if (req.suffix.length != 1) {
actions.actionResultError (req, res, 404, actions.cursorNotFound, "Cursor not found");
actions.actionResultError (req, res, 404, actions.errorInvalidRequest, "Invalid request");
return;
}
@ -169,7 +170,7 @@ function deleteCursor(req, res) {
actions.actionResultOK(req, res, 202, { "_id" : cursorId });
}
catch (e) {
actions.actionResultError (req, res, 404, actions.cursorNotFound, "Cursor not found");
actions.actionResultError (req, res, 404, actions.errorCursorNotFound, "Cursor not found");
}
}

View File

@ -42,7 +42,7 @@ var actions = require("actions");
function postQuery(req, res) {
if (req.suffix.length != 0) {
actions.actionResultError (req, res, 400, actions.queryNotModified, "Invalid query data");
actions.actionResultError (req, res, 404, actions.errorInvalidRequest, "Invalid request");
return;
}
@ -50,7 +50,7 @@ function postQuery(req, res) {
var json = JSON.parse(req.requestBody);
if (!json || !(json instanceof Object) || json.query == undefined) {
actions.actionResultError (req, res, 400, actions.queryNotModified, "Invalid query data");
actions.actionResultError (req, res, 400, actions.errorQuerySpecificationInvalid, "Query specification invalid");
return;
}
@ -65,7 +65,7 @@ function postQuery(req, res) {
actions.actionResultOK(req, res, 200, result);
}
catch (e) {
actions.actionResultError (req, res, 500, actions.queryNotModified, "Internal server error");
actions.actionResultError (req, res, 404, actions.errorJavascriptException, "Javascript exception");
}
}

View File

@ -0,0 +1,52 @@
////////////////////////////////////////////////////////////////////////////////
/// @brief auto-generated file generated from errors.dat
////////////////////////////////////////////////////////////////////////////////
var internal = require("internal");
ModuleCache["/internal"].exports.errors = {
"VOC_ERROR_ILLEGAL_STATE" : { "code" : 1000, "message" : "illegal state" },
"VOC_ERROR_SHAPER_FAILED" : { "code" : 1001, "message" : "illegal shaper" },
"VOC_ERROR_CORRUPTED_DATAFILE" : { "code" : 1002, "message" : "corrupted datafile" },
"VOC_ERROR_MMAP_FAILED" : { "code" : 1003, "message" : "mmap failed" },
"VOC_ERROR_MSYNC_FAILED" : { "code" : 1004, "message" : "msync failed" },
"VOC_ERROR_NO_JOURNAL" : { "code" : 1005, "message" : "no journal" },
"VOC_ERROR_DATAFILE_SEALED" : { "code" : 1006, "message" : "datafile sealed" },
"VOC_ERROR_CORRUPTED_COLLECTION" : { "code" : 1007, "message" : "corrupted collection" },
"VOC_ERROR_UNKNOWN_TYPE" : { "code" : 1008, "message" : "unknown type" },
"VOC_ERROR_ILLEGAL_PARAMETER" : { "code" : 1009, "message" : "illegal parameter" },
"VOC_ERROR_INDEX_EXISTS" : { "code" : 1010, "message" : "index exists" },
"VOC_ERROR_CONFLICT" : { "code" : 1011, "message" : "conflict" },
"VOC_ERROR_WRONG_PATH" : { "code" : 1100, "message" : "wrong path" },
"VOC_ERROR_CANNOT_RENAME" : { "code" : 1101, "message" : "cannot rename" },
"VOC_ERROR_WRITE_FAILED" : { "code" : 1102, "message" : "write failed" },
"VOC_ERROR_READ_ONLY" : { "code" : 1103, "message" : "ready only" },
"VOC_ERROR_DATAFILE_FULL" : { "code" : 1104, "message" : "datafile full" },
"VOC_ERROR_FILESYSTEM_FULL" : { "code" : 1105, "message" : "filesystem full" },
"VOC_ERROR_READ_FAILED" : { "code" : 1106, "message" : "read failed" },
"VOC_ERROR_FILE_NOT_FOUND" : { "code" : 1107, "message" : "file not found" },
"VOC_ERROR_FILE_NOT_ACCESSIBLE" : { "code" : 1108, "message" : "file not accessible" },
"VOC_ERROR_DOCUMENT_NOT_FOUND" : { "code" : 1200, "message" : "document not found" },
"ERROR_QUERY_OOM" : { "code" : 1500, "message" : "out of memory" },
"ERROR_QUERY_KILLED" : { "code" : 1501, "message" : "query killed" },
"ERROR_QUERY_PARSE" : { "code" : 1510, "message" : "parse error: %s" },
"ERROR_QUERY_EMPTY" : { "code" : 1511, "message" : "query is empty" },
"ERROR_QUERY_SPECIFICATION_INVALID" : { "code" : 1512, "message" : "query specification invalid" },
"ERROR_QUERY_NUMBER_OUT_OF_RANGE" : { "code" : 1520, "message" : "number '%s' is out of range" },
"ERROR_QUERY_LIMIT_VALUE_OUT_OF_RANGE" : { "code" : 1521, "message" : "limit value '%s' is out of range" },
"ERROR_QUERY_TOO_MANY_JOINS" : { "code" : 1540, "message" : "too many joins." },
"ERROR_QUERY_COLLECTION_NAME_INVALID" : { "code" : 1550, "message" : "collection name '%s' is invalid" },
"ERROR_QUERY_COLLECTION_ALIAS_INVALID" : { "code" : 1551, "message" : "collection alias '%s' is invalid" },
"ERROR_QUERY_COLLECTION_ALIAS_REDECLARED" : { "code" : 1552, "message" : "collection alias '%s' is declared multiple times in the same query" },
"ERROR_QUERY_COLLECTION_ALIAS_UNDECLARED" : { "code" : 1553, "message" : "collection alias '%s' is used but was not declared in the from clause" },
"ERROR_QUERY_COLLECTION_NOT_FOUND" : { "code" : 1560, "message" : "unable to open collection '%s'" },
"ERROR_QUERY_GEO_RESTRICTION_INVALID" : { "code" : 1570, "message" : "geo restriction for alias '%s' is invalid" },
"ERROR_QUERY_GEO_INDEX_MISSING" : { "code" : 1571, "message" : "no suitable geo index found for geo restriction on '%s'" },
"ERROR_QUERY_BIND_PARAMETER_MISSING" : { "code" : 1590, "message" : "no value specified for declared bind parameter '%s'" },
"ERROR_QUERY_BIND_PARAMETER_REDECLARED" : { "code" : 1591, "message" : "value for bind parameter '%s' is declared multiple times" },
"ERROR_QUERY_BIND_PARAMETER_UNDECLARED" : { "code" : 1592, "message" : "bind parameter '%s' was not declared in the query" },
"ERROR_QUERY_BIND_PARAMETER_VALUE_INVALID" : { "code" : 1593, "message" : "invalid value for bind parameter '%s'" },
"ERROR_QUERY_BIND_PARAMETER_NUMBER_OUT_OF_RANGE" : { "code" : 1594, "message" : "bind parameter number '%s' out of range" },
"ERROR_CURSOR_NOT_FOUND" : { "code" : 1600, "message" : "cursor not found" },
};

View File

@ -41,16 +41,16 @@ var console = require("console");
/// @brief error codes
////////////////////////////////////////////////////////////////////////////////
exports.queryNotFound = 10404;
exports.queryNotModified = 10304;
exports.errorQuerySpecificationInvalid = 1512;
exports.errorCursorNotFound = 1600;
exports.errorInvalidRequest = 1700;
exports.errorJavascriptException = 1701;
exports.collectionNotFound = 20404;
exports.documentNotFound = 30404;
exports.documentNotModified = 30304;
exports.cursorNotFound = 40404;
exports.cursorNotModified = 40304;
exports.keyValueNotFound = 41404;
exports.keyValueNotModified = 41304;

View File

@ -82,14 +82,127 @@ function aqlBindParametersTestSuite () {
}
////////////////////////////////////////////////////////////////////////////////
/// @brief check keyword names in select
/// @brief check length of result set for null bind parameter
////////////////////////////////////////////////////////////////////////////////
function testKeywordNamesWhereValid () {
//this.collection.save({ "value1" : i, "value2" : j, "value3" : "test", "value4" : null, "value5" : -13.5});
var result = this.getQueryResults("SELECT { value: @value1@ } FROM " + this.collection._name + " c WHERE c.value1 == @value1@", { "value1" : 0 });
function executeRsLengthCheckNull (expectedLength, value) {
var params = { "7" : value };
var result = this.getQueryResults("SELECT { value: @7 } FROM " + this.collection._name + " c " +
"WHERE c.value4 == @7", params);
assertEqual(11, result.length);
assertEqual(expectedLength, result.length);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief check length of result set for string bind parameter
////////////////////////////////////////////////////////////////////////////////
function executeRsLengthCheckString (expectedLength, value) {
var params = { "0" : value };
var result = this.getQueryResults("SELECT { value: @0 } FROM " + this.collection._name + " c " +
"WHERE c.value3 == @0", params);
assertEqual(expectedLength, result.length);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief check length of result set for 1 bind parameter
////////////////////////////////////////////////////////////////////////////////
function executeRsLengthCheck (expectedLength, value) {
var params = { "value1" : value };
var result = this.getQueryResults("SELECT { value: @value1@ } FROM " + this.collection._name + " c " +
"WHERE c.value1 == @value1@", params);
assertEqual(expectedLength, result.length);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief check length of result set for 2 bind parameters
////////////////////////////////////////////////////////////////////////////////
function executeRsLengthCheck2 (expectedLength, value1, value2) {
var params = { "value1" : value1, "value2" : value2 };
var result = this.getQueryResults("SELECT { value: @value1@ } FROM " + this.collection._name + " c " +
"WHERE c.value1 == @value1@ && c.value2 == @value2@", params);
assertEqual(expectedLength, result.length);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief check result sets
////////////////////////////////////////////////////////////////////////////////
function testRsLengths1 () {
this.executeRsLengthCheck(11, 0);
this.executeRsLengthCheck(11, 1);
this.executeRsLengthCheck(11, 2);
this.executeRsLengthCheck(11, 9);
this.executeRsLengthCheck(11, 10);
this.executeRsLengthCheck(0, -1);
this.executeRsLengthCheck(0, -5);
this.executeRsLengthCheck(0, -10);
this.executeRsLengthCheck(0, -11);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief check result sets
////////////////////////////////////////////////////////////////////////////////
function testRsLengths2 () {
this.executeRsLengthCheck2(1, 0, 0);
this.executeRsLengthCheck2(1, 0, 1);
this.executeRsLengthCheck2(1, 1, 0);
this.executeRsLengthCheck2(1, 2, 0);
this.executeRsLengthCheck2(1, 2, 1);
this.executeRsLengthCheck2(1, 0, 2);
this.executeRsLengthCheck2(1, 1, 2);
this.executeRsLengthCheck2(1, 10, 0);
this.executeRsLengthCheck2(1, 10, 1);
this.executeRsLengthCheck2(1, 0, 10);
this.executeRsLengthCheck2(1, 1, 10);
this.executeRsLengthCheck2(1, 10, 10);
this.executeRsLengthCheck2(0, 11, 0);
this.executeRsLengthCheck2(0, 11, 1);
this.executeRsLengthCheck2(0, 0, 11);
this.executeRsLengthCheck2(0, 1, 11);
this.executeRsLengthCheck2(0, -1, 0);
this.executeRsLengthCheck2(0, 1, -1);
this.executeRsLengthCheck2(0, 10, -1);
this.executeRsLengthCheck2(0, 11, -1);
this.executeRsLengthCheck2(0, -10, 1);
this.executeRsLengthCheck2(0, -10, 10);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief check result sets
////////////////////////////////////////////////////////////////////////////////
function testRsLengthsString () {
this.executeRsLengthCheckString(121, "test");
this.executeRsLengthCheckString(0, " test");
this.executeRsLengthCheckString(0, " test ");
this.executeRsLengthCheckString(0, "test ");
this.executeRsLengthCheckString(0, "test ");
this.executeRsLengthCheckString(0, "rest");
this.executeRsLengthCheckString(0, 15);
this.executeRsLengthCheckString(0, 1);
this.executeRsLengthCheckString(0, -15);
this.executeRsLengthCheckString(0, null);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief check result sets
////////////////////////////////////////////////////////////////////////////////
function testRsLengthsNull () {
this.executeRsLengthCheckNull(0, "test");
this.executeRsLengthCheckNull(0, "1");
this.executeRsLengthCheckNull(0, 1);
this.executeRsLengthCheckNull(0, 2);
}
}