1
0
Fork 0

constraint still not working, added test

This commit is contained in:
Frank Celler 2012-04-01 11:56:42 +02:00
parent 6ace3d598b
commit c238ea96e3
8 changed files with 196 additions and 155 deletions

View File

@ -288,10 +288,13 @@ bool RestDocumentHandler::createDocument () {
return true; return true;
} }
else { else {
if (TRI_errno() == TRI_ERROR_AVOCADO_READ_ONLY) { int res = TRI_errno();
generateError(HttpResponse::FORBIDDEN,
TRI_ERROR_AVOCADO_READ_ONLY, if (res == TRI_ERROR_AVOCADO_READ_ONLY) {
"collection is read-only"); generateError(HttpResponse::FORBIDDEN, res, "collection is read-only");
}
else if (res == TRI_ERROR_AVOCADO_UNIQUE_CONSTRAINT_VIOLATED) {
generateError(HttpResponse::CONFLICT, res, "cannot create document, unique constraint violated");
} }
else { else {
generateError(HttpResponse::SERVER_ERROR, generateError(HttpResponse::SERVER_ERROR,

View File

@ -32,21 +32,27 @@
/// <li>@ref HttpCollectionIntro</li> /// <li>@ref HttpCollectionIntro</li>
/// <li>@ref HttpCollectionResource</li> /// <li>@ref HttpCollectionResource</li>
/// <li>@ref HttpCollectionHttp /// <li>@ref HttpCollectionHttp
/// <ol> /// @copydetails HttpCollectionCallsTOC
/// <li>@ref HttpCollectionRead "GET /_api/collection/@FA{collection-identifier}"</li>
/// <li>@ref HttpCollectionCreate "POST /_api/collection"</li>
/// <li>@ref HttpCollectionLoad "PUT /_api/collection/@FA{collection-identifier}/load"</li>
/// <li>@ref HttpCollectionUnload "PUT /_api/collection/@FA{collection-identifier}/unload"</li>
/// <li>@ref HttpCollectionTruncate "PUT /_api/collection/@FA{collection-identifier}/truncate"</li>
/// <li>@ref HttpCollectionParameter "PUT /_api/collection/@FA{collection-identifier}/parameter"</li>
/// <li>@ref HttpCollectionRename "PUT /_api/collection/@FA{collection-identifier}/rename"</li>
/// <li>@ref HttpCollectionDelete "DELETE /_api/collection/@FA{collection-identifier}"</li>
/// <li>@ref HttpCollectionReadAll "GET /_api/collection/"</li>
/// </ol>
/// </li> /// </li>
/// </ol> /// </ol>
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @page HttpCollectionCallsTOC
///
/// <ol>
/// <li>@ref HttpCollectionRead "GET /_api/collection/@FA{collection-identifier}"</li>
/// <li>@ref HttpCollectionCreate "POST /_api/collection"</li>
/// <li>@ref HttpCollectionLoad "PUT /_api/collection/@FA{collection-identifier}/load"</li>
/// <li>@ref HttpCollectionUnload "PUT /_api/collection/@FA{collection-identifier}/unload"</li>
/// <li>@ref HttpCollectionTruncate "PUT /_api/collection/@FA{collection-identifier}/truncate"</li>
/// <li>@ref HttpCollectionParameter "PUT /_api/collection/@FA{collection-identifier}/parameter"</li>
/// <li>@ref HttpCollectionRename "PUT /_api/collection/@FA{collection-identifier}/rename"</li>
/// <li>@ref HttpCollectionDelete "DELETE /_api/collection/@FA{collection-identifier}"</li>
/// <li>@ref HttpCollectionReadAll "GET /_api/collection/"</li>
/// </ol>
////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @page HttpCollection HTTP Interface for Collections /// @page HttpCollection HTTP Interface for Collections
/// ///

View File

@ -32,16 +32,22 @@
/// <li>@ref HttpIndexIntro</li> /// <li>@ref HttpIndexIntro</li>
/// <li>@ref HttpIndexResource</li> /// <li>@ref HttpIndexResource</li>
/// <li>@ref HttpIndexHttp /// <li>@ref HttpIndexHttp
/// <ol> /// @copydetails HttpIndexCallsTOC
/// <li>@ref HttpIndexRead "GET /_api/index/@FA{collection-identifier}/@FA{index-identifier}"</li>
/// <li>@ref HttpIndexCreate "POST /_api/index/@FA{collection-identifier}"</li>
/// <li>@ref HttpIndexDelete "DELETE /_api/index/@FA{collection-identifier}/@FA{index-identifier}"</li>
/// <li>@ref HttpIndexReadAll "GET /_api/index/@FA{collection-identifier}"</li>
/// </ol>
/// </li> /// </li>
/// </ol> /// </ol>
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @page HttpIndexCallsTOC
///
/// <ol>
/// <li>@ref HttpIndexRead "GET /_api/index/@FA{collection-identifier}/@FA{index-identifier}"</li>
/// <li>@ref HttpIndexCreate "POST /_api/index/@FA{collection-identifier}"</li>
/// <li>@ref HttpIndexDelete "DELETE /_api/index/@FA{collection-identifier}/@FA{index-identifier}"</li>
/// <li>@ref HttpIndexReadAll "GET /_api/index/@FA{collection-identifier}"</li>
/// </ol>
////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @page HttpIndex HTTP Interface for Indexes /// @page HttpIndex HTTP Interface for Indexes
/// ///

View File

@ -32,14 +32,7 @@
/// <li>Querying and Managing Documents /// <li>Querying and Managing Documents
/// <ol> /// <ol>
/// <li>@ref RestDocument /// <li>@ref RestDocument
/// <ol> /// @copydetails RestDocumentCallsTOC
/// <li>@ref RestDocumentRead "GET /document/@FA{document-handle}"</li>
/// <li>@ref RestDocumentCreate "POST /document/collection=@FA{collection-identifier}"</li>
/// <li>@ref RestDocumentUpdate "PUT /document/@FA{document-handle}"</li>
/// <li>@ref RestDocumentDelete "DELETE /document/@FA{document-handle}"</li>
/// <li>@ref RestDocumentHead "HEAD /document/@FA{document-handle}"</li>
/// <li>@ref RestDocumentReadAll "GET /document?collection=@FA{collection-identifier}"</li>
/// </ol>
/// </li> /// </li>
/// <li>@ref OTWPSimpleQueries /// <li>@ref OTWPSimpleQueries
/// <ol> /// <ol>
@ -68,21 +61,11 @@
/// </li> /// </li>
/// </ol> /// </ol>
/// </li> /// </li>
/// <li>@ref OTWPDatabase /// <li>@ref HttpCollection
/// <ol> /// @copydetails HttpCollectionCallsTOC
/// <li>@ref OTWPDatabaseCollections "GET /_api/database/collections"</li>
/// <li>@ref OTWPDatabaseCollection "GET /_api/datebase/collection/@FA{collection-identifier}"</li>
/// <li>@ref OTWPDatabaseCollectionCreate "POST /_api/datebase/collection"</li>
/// </ol>
/// </li> /// </li>
/// <li>Administration /// <li>@ref HttpIndex
/// <ol> /// @copydetails HttpIndexCallsTOC
/// <li>GET /_admin/database/collection/@FA{collection-identifier}</li>
/// <li>POST /_admin/database/collection/@FA{collection-identifier}/index</li>
/// <li>GET /_admin/database/collection/@FA{collection-identifier}/indexes</li>
/// <li>GET /_admin/vocbase/collection/@FA{collection-identifier}/index/@FA{index-identifier}</li>
/// <li>DELETE /_admin/vocbase/collection/@FA{collection-identifier}/index/@FA{index-identifier}</li>
/// </ol>
/// </li> /// </li>
/// </ol> /// </ol>
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -113,21 +96,6 @@
/// @copydetails JSA_PUT_api_simple_within /// @copydetails JSA_PUT_api_simple_within
/// <hr> /// <hr>
/// ///
/// @section OTWPDatabase Querying and Managing Collections
///////////////////////////////////////////////////////////
///
/// @anchor OTWPDatabaseCollections
/// @copydetails JSA_GET_api_datebase_collections
/// <hr>
///
/// @anchor OTWPDatabaseCollection
/// @copydetails JSF_GET_api_database_collection
/// <hr>
///
/// @anchor OTWPDatabaseCollectionCreate
/// @copydetails JSF_POST_api_database_collection
/// <hr>
///
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Local Variables: // Local Variables:

View File

@ -58,6 +58,7 @@
/// <ol> /// <ol>
/// <li>@ref RestDocument</li> /// <li>@ref RestDocument</li>
/// <li>@ref HttpCollection</li> /// <li>@ref HttpCollection</li>
/// <li>@ref HttpIndex</li>
/// </ol> /// </ol>
/// </li> /// </li>
/// </ol> /// </ol>

View File

@ -32,18 +32,24 @@
/// <li>@ref RestDocumentIntro</li> /// <li>@ref RestDocumentIntro</li>
/// <li>@ref RestDocumentResource</li> /// <li>@ref RestDocumentResource</li>
/// <li>@ref RestDocumentHttp /// <li>@ref RestDocumentHttp
/// <ol> /// @copydetails RestDocumentCallsTOC
/// <li>@ref RestDocumentRead "GET /document/@FA{document-handle}"</li>
/// <li>@ref RestDocumentCreate "POST /document?collection=@FA{collection-identifier}"</li>
/// <li>@ref RestDocumentUpdate "PUT /document/@FA{document-handle}"</li>
/// <li>@ref RestDocumentDelete "DELETE /document/@FA{document-handle}"</li>
/// <li>@ref RestDocumentHead "HEAD /document/@FA{document-handle}"</li>
/// <li>@ref RestDocumentReadAll "GET /document?collection=@FA{collection-identifier}"</li>
/// </ol>
/// </li> /// </li>
/// </ol> /// </ol>
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @page RestDocumentCallsTOC
///
/// <ol>
/// <li>@ref RestDocumentRead "GET /document/@FA{document-handle}"</li>
/// <li>@ref RestDocumentCreate "POST /document?collection=@FA{collection-identifier}"</li>
/// <li>@ref RestDocumentUpdate "PUT /document/@FA{document-handle}"</li>
/// <li>@ref RestDocumentDelete "DELETE /document/@FA{document-handle}"</li>
/// <li>@ref RestDocumentHead "HEAD /document/@FA{document-handle}"</li>
/// <li>@ref RestDocumentReadAll "GET /document?collection=@FA{collection-identifier}"</li>
/// </ol>
////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @page RestDocument REST Interface for Documents /// @page RestDocument REST Interface for Documents
/// ///

View File

@ -0,0 +1,88 @@
require 'rspec'
require './avocadodb.rb'
describe AvocadoDB do
api = "/_api/index"
prefix = "api-index-unique-constraint"
context "one attribute:" do
context "dealing with unique constraints:" do
before do
@cn = "UnitTestsCollectionIndexes"
AvocadoDB.drop_collection(@cn)
@cid = AvocadoDB.create_collection(@cn)
end
after do
AvocadoDB.drop_collection(@cn)
end
it "rolls back in case of violation" do
cmd = "/_api/index/#{@cid}"
body = "{ \"type\" : \"hash\", \"unique\" : true, \"fields\" : [ \"a\" ] }"
doc = AvocadoDB.log_post("#{prefix}", cmd, :body => body)
doc.code.should eq(201)
doc.parsed_response['type'].should eq("hash")
doc.parsed_response['unique'].should eq(true)
cmd1 = "/document?collection=#{@cid}"
# create a document
body = "{ \"a\" : 1, \"b\" : 1 }"
doc = AvocadoDB.log_post("#{prefix}", cmd1, :body => body)
doc.code.should eq(201)
id1 = doc.parsed_response['_id']
id1.should be_kind_of(String)
rev1 = doc.parsed_response['_rev']
rev1.should be_kind_of(Integer)
cmd2 = "/document/#{id1}"
# check it
doc = AvocadoDB.log_get("#{prefix}", cmd2)
doc.code.should eq(200)
doc.parsed_response['a'].should eq(1)
doc.parsed_response['b'].should eq(1)
# create a unique constraint violation
body = "{ \"a\" : 1, \"b\" : 2 }"
doc = AvocadoDB.log_post("#{prefix}", cmd1, :body => body)
doc.code.should eq(409)
# id2 = doc.parsed_response['_id']
# id2.should be_kind_of(String)
# rev2 = doc.parsed_response['_rev']
# rev2.should be_kind_of(Integer)
# check the old document again
doc = AvocadoDB.log_get("#{prefix}", cmd2)
doc.code.should eq(200)
doc.parsed_response['a'].should eq(1)
doc.parsed_response['b'].should eq(1)
#
body = "{ \"a\" : 1, \"b\" : 3 }"
doc = AvocadoDB.log_post("#{prefix}", cmd1, :body => body)
doc.code.should eq(409)
# id3 = doc.parsed_response['_id']
# id3.should be_kind_of(String)
# rev3 = doc.parsed_response['_rev']
# rev3.should be_kind_of(Integer)
body = "{ \"a\" : 1 }"
doc = AvocadoDB.log_post("#{prefix}", cmd1, :body => body)
end
end
end
end

View File

@ -58,6 +58,13 @@ static int DeleteDocument (TRI_sim_collection_t* collection,
TRI_doc_update_policy_e policy, TRI_doc_update_policy_e policy,
bool release); bool release);
static int DeleteShapedJson (TRI_doc_collection_t* doc,
TRI_voc_did_t did,
TRI_voc_rid_t rid,
TRI_voc_rid_t* oldRid,
TRI_doc_update_policy_e policy,
bool release);
static TRI_index_t* CreateGeoIndexSimCollection (TRI_sim_collection_t* collection, static TRI_index_t* CreateGeoIndexSimCollection (TRI_sim_collection_t* collection,
char const* location, char const* location,
char const* latitude, char const* latitude,
@ -275,7 +282,7 @@ static void CreateHeader (TRI_doc_collection_t* c,
/// @brief creates a new document splitted into marker and body to file /// @brief creates a new document splitted into marker and body to file
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
static TRI_doc_mptr_t CreateDocument (TRI_sim_collection_t* collection, static TRI_doc_mptr_t CreateDocument (TRI_sim_collection_t* sim,
TRI_doc_document_marker_t* marker, TRI_doc_document_marker_t* marker,
size_t markerSize, size_t markerSize,
void const* body, void const* body,
@ -290,27 +297,26 @@ static TRI_doc_mptr_t CreateDocument (TRI_sim_collection_t* collection,
TRI_voc_size_t total; TRI_voc_size_t total;
TRI_doc_datafile_info_t* dfi; TRI_doc_datafile_info_t* dfi;
int res; int res;
int originalRes;
// ............................................................................. // .............................................................................
// create header // create header
// ............................................................................. // .............................................................................
// get a new header pointer // get a new header pointer
header = collection->_headers->request(collection->_headers); header = sim->_headers->request(sim->_headers);
// generate a new tick // generate a new tick
marker->_rid = marker->_did = marker->base._tick = TRI_NewTickVocBase(); marker->_rid = marker->_did = marker->base._tick = TRI_NewTickVocBase();
// find and select a journal // find and select a journal
total = markerSize + bodySize; total = markerSize + bodySize;
journal = SelectJournal(collection, total, result); journal = SelectJournal(sim, total, result);
if (journal == NULL) { if (journal == NULL) {
collection->base.base._lastError = TRI_set_errno(TRI_ERROR_AVOCADO_NO_JOURNAL); sim->base.base._lastError = TRI_set_errno(TRI_ERROR_AVOCADO_NO_JOURNAL);
if (release) { if (release) {
collection->base.endWrite(&collection->base); sim->base.endWrite(&sim->base);
} }
mptr._did = 0; mptr._did = 0;
@ -322,13 +328,13 @@ static TRI_doc_mptr_t CreateDocument (TRI_sim_collection_t* collection,
// ............................................................................. // .............................................................................
// verify the header pointer // verify the header pointer
header = collection->_headers->verify(collection->_headers, header); header = sim->_headers->verify(sim->_headers, header);
// generate crc // generate crc
TRI_FillCrcMarkerDatafile(&marker->base, markerSize, body, bodySize); TRI_FillCrcMarkerDatafile(&marker->base, markerSize, body, bodySize);
// and write marker and blob // and write marker and blob
res = WriteElement(collection, journal, &marker->base, markerSize, body, bodySize, *result); res = WriteElement(sim, journal, &marker->base, markerSize, body, bodySize, *result);
// ............................................................................. // .............................................................................
// update indexes // update indexes
@ -338,41 +344,30 @@ static TRI_doc_mptr_t CreateDocument (TRI_sim_collection_t* collection,
if (res == TRI_ERROR_NO_ERROR) { if (res == TRI_ERROR_NO_ERROR) {
// fill the header // fill the header
collection->base.createHeader(&collection->base, journal, *result, markerSize, header, 0); sim->base.createHeader(&sim->base, journal, *result, markerSize, header, 0);
// update the datafile info // update the datafile info
dfi = TRI_FindDatafileInfoDocCollection(&collection->base, journal->_fid); dfi = TRI_FindDatafileInfoDocCollection(&sim->base, journal->_fid);
dfi->_numberAlive += 1; dfi->_numberAlive += 1;
dfi->_sizeAlive += header->_document._data.length; dfi->_sizeAlive += header->_document._data.length;
// update immediate indexes // update immediate indexes
res = CreateImmediateIndexes(collection, header); res = CreateImmediateIndexes(sim, header);
originalRes = res;
// check for constraint error // check for constraint error, rollback if necessary
if (res != TRI_ERROR_NO_ERROR) { if (res != TRI_ERROR_NO_ERROR) {
TRI_doc_deletion_marker_t markerDel; TRI_doc_deletion_marker_t markerDel;
int resRollback;
LOG_WARNING("encountered index violating during create, deleting newly created document"); LOG_DEBUG("encountered index violating during create, deleting newly created document");
// ............................................................................. // rollback, ignore any additional errors
// rollback resRollback = DeleteShapedJson(&sim->base, header->_did, header->_rid, 0, TRI_DOC_UPDATE_LAST_WRITE, false);
// .............................................................................
memset(&markerDel, 0, sizeof(markerDel)); if (resRollback != TRI_ERROR_NO_ERROR) {
markerDel.base._size = sizeof(markerDel);
markerDel.base._type = TRI_DOC_MARKER_DELETION;
markerDel._did = header->_did;
markerDel._sid = 0;
// ignore any additional errors
res = DeleteDocument(collection, &markerDel, header->_rid, NULL, TRI_DOC_UPDATE_LAST_WRITE, false);
if (res != TRI_ERROR_NO_ERROR) {
LOG_ERROR("encountered error '%s' during rollback of create", TRI_last_error()); LOG_ERROR("encountered error '%s' during rollback of create", TRI_last_error());
TRI_set_errno(res);
} }
} }
@ -385,22 +380,20 @@ static TRI_doc_mptr_t CreateDocument (TRI_sim_collection_t* collection,
// release lock, header might be invalid after this // release lock, header might be invalid after this
if (release) { if (release) {
collection->base.endWrite(&collection->base); sim->base.endWrite(&sim->base);
} }
// wait for sync // wait for sync
WaitSync(collection, journal, ((char const*) *result) + markerSize + bodySize); WaitSync(sim, journal, ((char const*) *result) + markerSize + bodySize);
// and return // and return
return mptr; return mptr;
} }
else { else {
if (release) { if (release) {
collection->base.endWrite(&collection->base); sim->base.endWrite(&sim->base);
} }
TRI_set_errno(originalRes);
mptr._did = 0; mptr._did = 0;
return mptr; return mptr;
} }
@ -408,10 +401,11 @@ static TRI_doc_mptr_t CreateDocument (TRI_sim_collection_t* collection,
} }
else { else {
if (release) { if (release) {
collection->base.endWrite(&collection->base); sim->base.endWrite(&sim->base);
} }
LOG_ERROR("cannot write element: %s", TRI_last_error()); LOG_ERROR("cannot write element: %s", TRI_last_error());
mptr._did = 0; mptr._did = 0;
return mptr; return mptr;
} }
@ -480,12 +474,11 @@ static TRI_doc_mptr_t const UpdateDocument (TRI_sim_collection_t* collection,
case TRI_DOC_UPDATE_ERROR: case TRI_DOC_UPDATE_ERROR:
if (rid != 0) { if (rid != 0) {
if (rid != header->_rid) { if (rid != header->_rid) {
TRI_set_errno(TRI_ERROR_AVOCADO_CONFLICT);
if (release) { if (release) {
collection->base.endWrite(&collection->base); collection->base.endWrite(&collection->base);
} }
TRI_set_errno(TRI_ERROR_AVOCADO_CONFLICT);
mptr._did = 0; mptr._did = 0;
return mptr; return mptr;
} }
@ -497,22 +490,20 @@ static TRI_doc_mptr_t const UpdateDocument (TRI_sim_collection_t* collection,
break; break;
case TRI_DOC_UPDATE_CONFLICT: case TRI_DOC_UPDATE_CONFLICT:
TRI_set_errno(TRI_ERROR_NOT_IMPLEMENTED);
if (release) { if (release) {
collection->base.endWrite(&collection->base); collection->base.endWrite(&collection->base);
} }
TRI_set_errno(TRI_ERROR_NOT_IMPLEMENTED);
mptr._did = 0; mptr._did = 0;
return mptr; return mptr;
case TRI_DOC_UPDATE_ILLEGAL: case TRI_DOC_UPDATE_ILLEGAL:
TRI_set_errno(TRI_ERROR_INTERNAL);
if (release) { if (release) {
collection->base.endWrite(&collection->base); collection->base.endWrite(&collection->base);
} }
TRI_set_errno(TRI_ERROR_INTERNAL);
mptr._did = 0; mptr._did = 0;
return mptr; return mptr;
} }
@ -684,7 +675,6 @@ static TRI_doc_mptr_t const UpdateDocument (TRI_sim_collection_t* collection,
} }
TRI_set_errno(originalRes); TRI_set_errno(originalRes);
mptr._did = 0; mptr._did = 0;
return mptr; return mptr;
} }
@ -741,7 +731,7 @@ static int DeleteDocument (TRI_sim_collection_t* collection,
collection->base.endWrite(&collection->base); collection->base.endWrite(&collection->base);
} }
return TRI_ERROR_AVOCADO_CONFLICT; return TRI_set_errno(TRI_ERROR_AVOCADO_CONFLICT);
} }
} }
@ -755,14 +745,14 @@ static int DeleteDocument (TRI_sim_collection_t* collection,
collection->base.endWrite(&collection->base); collection->base.endWrite(&collection->base);
} }
return TRI_ERROR_NOT_IMPLEMENTED; return TRI_set_errno(TRI_ERROR_NOT_IMPLEMENTED);
case TRI_DOC_UPDATE_ILLEGAL: case TRI_DOC_UPDATE_ILLEGAL:
if (release) { if (release) {
collection->base.endWrite(&collection->base); collection->base.endWrite(&collection->base);
} }
return TRI_ERROR_INTERNAL; return TRI_set_errno(TRI_ERROR_INTERNAL);
} }
// generate a new tick // generate a new tick
@ -1126,16 +1116,16 @@ static TRI_doc_mptr_t const UpdateShapedJson (TRI_doc_collection_t* document,
/// @brief deletes a json document given the identifier /// @brief deletes a json document given the identifier
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
static int DeleteShapedJson (TRI_doc_collection_t* document, static int DeleteShapedJson (TRI_doc_collection_t* doc,
TRI_voc_did_t did, TRI_voc_did_t did,
TRI_voc_rid_t rid, TRI_voc_rid_t rid,
TRI_voc_rid_t* oldRid, TRI_voc_rid_t* oldRid,
TRI_doc_update_policy_e policy, TRI_doc_update_policy_e policy,
bool release) { bool release) {
TRI_sim_collection_t* collection; TRI_sim_collection_t* sim;
TRI_doc_deletion_marker_t marker; TRI_doc_deletion_marker_t marker;
collection = (TRI_sim_collection_t*) document; sim = (TRI_sim_collection_t*) doc;
memset(&marker, 0, sizeof(marker)); memset(&marker, 0, sizeof(marker));
@ -1145,7 +1135,7 @@ static int DeleteShapedJson (TRI_doc_collection_t* document,
marker._did = did; marker._did = did;
marker._sid = 0; marker._sid = 0;
return DeleteDocument(collection, &marker, rid, oldRid, policy, release); return DeleteDocument(sim, &marker, rid, oldRid, policy, release);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -1692,19 +1682,8 @@ static bool InitSimCollection (TRI_sim_collection_t* collection,
// create primary index // create primary index
primary = TRI_Allocate(sizeof(TRI_index_t)); primary = TRI_Allocate(sizeof(TRI_index_t));
if (primary == NULL) {
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
return false;
}
id = TRI_DuplicateString("_id"); id = TRI_DuplicateString("_id");
if (id == NULL) {
TRI_Free(primary);
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
return false;
}
TRI_InitDocCollection(&collection->base, shaper); TRI_InitDocCollection(&collection->base, shaper);
@ -2019,7 +1998,7 @@ int TRI_CloseSimCollection (TRI_sim_collection_t* collection) {
/// @brief creates a new entry in the immediate indexes /// @brief creates a new entry in the immediate indexes
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
static int CreateImmediateIndexes (TRI_sim_collection_t* collection, static int CreateImmediateIndexes (TRI_sim_collection_t* sim,
TRI_doc_mptr_t* header) { TRI_doc_mptr_t* header) {
TRI_df_marker_t const* marker; TRI_df_marker_t const* marker;
TRI_doc_mptr_t* found; TRI_doc_mptr_t* found;
@ -2033,7 +2012,7 @@ static int CreateImmediateIndexes (TRI_sim_collection_t* collection,
// ............................................................................. // .............................................................................
// add a new header // add a new header
found = TRI_InsertKeyAssociativePointer(&collection->_primaryIndex, &header->_did, header, false); found = TRI_InsertKeyAssociativePointer(&sim->_primaryIndex, &header->_did, header, false);
if (found != NULL) { if (found != NULL) {
LOG_ERROR("document %lu already existed with revision %lu while creating revision %lu", LOG_ERROR("document %lu already existed with revision %lu while creating revision %lu",
@ -2041,11 +2020,11 @@ static int CreateImmediateIndexes (TRI_sim_collection_t* collection,
(unsigned long) found->_rid, (unsigned long) found->_rid,
(unsigned long) header->_rid); (unsigned long) header->_rid);
collection->_headers->release(collection->_headers, header); sim->_headers->release(sim->_headers, header);
return TRI_ERROR_AVOCADO_UNIQUE_CONSTRAINT_VIOLATED; return TRI_set_errno(TRI_ERROR_AVOCADO_UNIQUE_CONSTRAINT_VIOLATED);
} }
// return in case of a delete // return in case of a deleted document
if (header->_deletion != 0) { if (header->_deletion != 0) {
return TRI_ERROR_NO_ERROR; return TRI_ERROR_NO_ERROR;
} }
@ -2067,58 +2046,42 @@ static int CreateImmediateIndexes (TRI_sim_collection_t* collection,
// IN // IN
entry = TRI_Allocate(sizeof(TRI_edge_header_t)); entry = TRI_Allocate(sizeof(TRI_edge_header_t));
if (!entry) {
return TRI_ERROR_OUT_OF_MEMORY;
}
entry->_mptr = header; entry->_mptr = header;
entry->_direction = TRI_EDGE_IN; entry->_direction = TRI_EDGE_IN;
entry->_cid = edge->_toCid; entry->_cid = edge->_toCid;
entry->_did = edge->_toDid; entry->_did = edge->_toDid;
TRI_InsertElementMultiPointer(&collection->_edgesIndex, entry, true); TRI_InsertElementMultiPointer(&sim->_edgesIndex, entry, true);
// OUT // OUT
entry = TRI_Allocate(sizeof(TRI_edge_header_t)); entry = TRI_Allocate(sizeof(TRI_edge_header_t));
if (!entry) {
return TRI_ERROR_OUT_OF_MEMORY;
}
entry->_mptr = header; entry->_mptr = header;
entry->_direction = TRI_EDGE_OUT; entry->_direction = TRI_EDGE_OUT;
entry->_cid = edge->_fromCid; entry->_cid = edge->_fromCid;
entry->_did = edge->_fromDid; entry->_did = edge->_fromDid;
TRI_InsertElementMultiPointer(&collection->_edgesIndex, entry, true); TRI_InsertElementMultiPointer(&sim->_edgesIndex, entry, true);
// ANY // ANY
entry = TRI_Allocate(sizeof(TRI_edge_header_t)); entry = TRI_Allocate(sizeof(TRI_edge_header_t));
if (!entry) {
return TRI_ERROR_OUT_OF_MEMORY;
}
entry->_mptr = header; entry->_mptr = header;
entry->_direction = TRI_EDGE_ANY; entry->_direction = TRI_EDGE_ANY;
entry->_cid = edge->_toCid; entry->_cid = edge->_toCid;
entry->_did = edge->_toDid; entry->_did = edge->_toDid;
TRI_InsertElementMultiPointer(&collection->_edgesIndex, entry, true); TRI_InsertElementMultiPointer(&sim->_edgesIndex, entry, true);
if (edge->_toCid != edge->_fromCid || edge->_toDid != edge->_fromDid) { if (edge->_toCid != edge->_fromCid || edge->_toDid != edge->_fromDid) {
entry = TRI_Allocate(sizeof(TRI_edge_header_t)); entry = TRI_Allocate(sizeof(TRI_edge_header_t));
if (!entry) {
return TRI_ERROR_OUT_OF_MEMORY;
}
entry->_mptr = header; entry->_mptr = header;
entry->_direction = TRI_EDGE_ANY; entry->_direction = TRI_EDGE_ANY;
entry->_cid = edge->_fromCid; entry->_cid = edge->_fromCid;
entry->_did = edge->_fromDid; entry->_did = edge->_fromDid;
TRI_InsertElementMultiPointer(&collection->_edgesIndex, entry, true); TRI_InsertElementMultiPointer(&sim->_edgesIndex, entry, true);
} }
} }
@ -2126,7 +2089,7 @@ static int CreateImmediateIndexes (TRI_sim_collection_t* collection,
// update all the other indices // update all the other indices
// ............................................................................. // .............................................................................
n = collection->_indexes._length; n = sim->_indexes._length;
result = TRI_ERROR_NO_ERROR; result = TRI_ERROR_NO_ERROR;
constraint = false; constraint = false;
@ -2134,7 +2097,7 @@ static int CreateImmediateIndexes (TRI_sim_collection_t* collection,
TRI_index_t* idx; TRI_index_t* idx;
int res; int res;
idx = collection->_indexes._buffer[i]; idx = sim->_indexes._buffer[i];
res = idx->insert(idx, header); res = idx->insert(idx, header);
// in case of no-memory, return immediately // in case of no-memory, return immediately
@ -2152,7 +2115,7 @@ static int CreateImmediateIndexes (TRI_sim_collection_t* collection,
} }
if (constraint) { if (constraint) {
return TRI_ERROR_AVOCADO_UNIQUE_CONSTRAINT_VIOLATED; return TRI_set_errno(TRI_ERROR_AVOCADO_UNIQUE_CONSTRAINT_VIOLATED);
} }
return result; return result;
@ -2221,7 +2184,7 @@ static int UpdateImmediateIndexes (TRI_sim_collection_t* collection,
} }
if (constraint) { if (constraint) {
return TRI_ERROR_AVOCADO_UNIQUE_CONSTRAINT_VIOLATED; return TRI_set_errno(TRI_ERROR_AVOCADO_UNIQUE_CONSTRAINT_VIOLATED);
} }
return result; return result;