diff --git a/UnitTests/HttpInterface/api-collection_spec.rb b/UnitTests/HttpInterface/api-collection_spec.rb index e656c0292c..a4ffaa77c0 100644 --- a/UnitTests/HttpInterface/api-collection_spec.rb +++ b/UnitTests/HttpInterface/api-collection_spec.rb @@ -30,9 +30,9 @@ describe AvocadoDB do doc = AvocadoDB.log_get("#{prefix}-all-collections", cmd) doc.code.should eq(200) + doc.headers['content-type'].should eq("application/json") doc.parsed_response['error'].should eq(false) doc.parsed_response['code'].should eq(200) - doc.headers['content-type'].should eq("application/json") collections = doc.parsed_response['collections'] names = doc.parsed_response['names'] @@ -53,10 +53,10 @@ describe AvocadoDB do doc = AvocadoDB.log_get("#{prefix}-bad-handle", cmd) doc.code.should eq(404) + doc.headers['content-type'].should eq("application/json") doc.parsed_response['error'].should eq(true) doc.parsed_response['errorNum'].should eq(1203) doc.parsed_response['code'].should eq(404) - doc.headers['content-type'].should eq("application/json") end it "creating a collection without name" do @@ -64,10 +64,10 @@ describe AvocadoDB do doc = AvocadoDB.log_post("#{prefix}-create-missing-name", cmd) doc.code.should eq(400) + doc.headers['content-type'].should eq("application/json") doc.parsed_response['error'].should eq(true) doc.parsed_response['code'].should eq(400) doc.parsed_response['errorNum'].should eq(1208) - doc.headers['content-type'].should eq("application/json") end it "creating a collection with an illegal name" do @@ -76,10 +76,10 @@ describe AvocadoDB do doc = AvocadoDB.log_post("#{prefix}-create-illegal-name", cmd, :body => body) doc.code.should eq(400) + doc.headers['content-type'].should eq("application/json") doc.parsed_response['error'].should eq(true) doc.parsed_response['code'].should eq(400) doc.parsed_response['errorNum'].should eq(1208) - doc.headers['content-type'].should eq("application/json") end it "creating a collection with a duplicate name" do @@ -91,10 +91,10 @@ describe AvocadoDB do doc = AvocadoDB.log_post("#{prefix}-create-illegal-name", cmd, :body => body) doc.code.should eq(400) + doc.headers['content-type'].should eq("application/json") doc.parsed_response['error'].should eq(true) doc.parsed_response['code'].should eq(400) doc.parsed_response['errorNum'].should eq(1207) - doc.headers['content-type'].should eq("application/json") end it "creating a collection with an illegal body" do @@ -103,11 +103,11 @@ describe AvocadoDB do doc = AvocadoDB.log_post("#{prefix}-create-illegal-body", cmd, :body => body) doc.code.should eq(400) + doc.headers['content-type'].should eq("application/json") doc.parsed_response['error'].should eq(true) doc.parsed_response['code'].should eq(400) doc.parsed_response['errorNum'].should eq(600) doc.parsed_response['errorMessage'].should eq("SyntaxError: Unexpected token n") - doc.headers['content-type'].should eq("application/json") end it "creating a collection with a null body" do @@ -116,10 +116,10 @@ describe AvocadoDB do doc = AvocadoDB.log_post("#{prefix}-create-null-body", cmd, :body => body) doc.code.should eq(400) + doc.headers['content-type'].should eq("application/json") doc.parsed_response['error'].should eq(true) doc.parsed_response['code'].should eq(400) doc.parsed_response['errorNum'].should eq(1208) - doc.headers['content-type'].should eq("application/json") end end @@ -143,10 +143,9 @@ describe AvocadoDB do doc = AvocadoDB.log_get("#{prefix}-get-collection-identifier", cmd) doc.code.should eq(200) + doc.headers['content-type'].should eq("application/json") doc.parsed_response['error'].should eq(false) doc.parsed_response['code'].should eq(200) - doc.headers['content-type'].should eq("application/json") - doc.parsed_response['id'].should eq(@cid) doc.parsed_response['name'].should eq(@cn) doc.parsed_response['status'].should be_kind_of(Integer) @@ -158,10 +157,9 @@ describe AvocadoDB do doc = AvocadoDB.log_get("#{prefix}-get-collection-name", cmd) doc.code.should eq(200) + doc.headers['content-type'].should eq("application/json") doc.parsed_response['error'].should eq(false) doc.parsed_response['code'].should eq(200) - doc.headers['content-type'].should eq("application/json") - doc.parsed_response['id'].should eq(@cid) doc.parsed_response['name'].should eq(@cn) doc.parsed_response['status'].should be_kind_of(Integer) @@ -173,10 +171,9 @@ describe AvocadoDB do doc = AvocadoDB.log_get("#{prefix}-get-collection-count", cmd) doc.code.should eq(200) + doc.headers['content-type'].should eq("application/json") doc.parsed_response['error'].should eq(false) doc.parsed_response['code'].should eq(200) - doc.headers['content-type'].should eq("application/json") - doc.parsed_response['id'].should eq(@cid) doc.parsed_response['name'].should eq(@cn) doc.parsed_response['status'].should eq(3) @@ -189,10 +186,9 @@ describe AvocadoDB do doc = AvocadoDB.log_get("#{prefix}-get-collection-figures", cmd) doc.code.should eq(200) + doc.headers['content-type'].should eq("application/json") doc.parsed_response['error'].should eq(false) doc.parsed_response['code'].should eq(200) - doc.headers['content-type'].should eq("application/json") - doc.parsed_response['id'].should eq(@cid) doc.parsed_response['name'].should eq(@cn) doc.parsed_response['status'].should eq(3) @@ -219,10 +215,10 @@ describe AvocadoDB do doc = AvocadoDB.log_delete("#{prefix}-delete-collection-identifier", cmd) doc.code.should eq(200) + doc.headers['content-type'].should eq("application/json") doc.parsed_response['error'].should eq(false) doc.parsed_response['code'].should eq(200) doc.parsed_response['id'].should eq(cid) - doc.headers['content-type'].should eq("application/json") cmd = api + "/" + String(cid) doc = AvocadoDB.get(cmd) @@ -237,10 +233,10 @@ describe AvocadoDB do doc = AvocadoDB.log_delete("#{prefix}-delete-collection-name", cmd) doc.code.should eq(200) + doc.headers['content-type'].should eq("application/json") doc.parsed_response['error'].should eq(false) doc.parsed_response['code'].should eq(200) doc.parsed_response['id'].should eq(cid) - doc.headers['content-type'].should eq("application/json") cmd = api + "/" + String(cid) doc = AvocadoDB.get(cmd) @@ -265,12 +261,12 @@ describe AvocadoDB do doc = AvocadoDB.log_post("#{prefix}-create-collection", cmd, :body => body) doc.code.should eq(200) + doc.headers['content-type'].should eq("application/json") doc.parsed_response['error'].should eq(false) doc.parsed_response['code'].should eq(200) doc.parsed_response['id'].should be_kind_of(Integer) doc.parsed_response['name'].should eq(@cn) doc.parsed_response['waitForSync'].should == false - doc.headers['content-type'].should eq("application/json") cmd = api + "/" + String(@cn) + "/figures" doc = AvocadoDB.get(cmd) @@ -286,12 +282,12 @@ describe AvocadoDB do doc = AvocadoDB.log_post("#{prefix}-create-collection-sync", cmd, :body => body) doc.code.should eq(200) + doc.headers['content-type'].should eq("application/json") doc.parsed_response['error'].should eq(false) doc.parsed_response['code'].should eq(200) doc.parsed_response['id'].should be_kind_of(Integer) doc.parsed_response['name'].should eq(@cn) doc.parsed_response['waitForSync'].should == true - doc.headers['content-type'].should eq("application/json") cmd = api + "/" + String(@cn) + "/figures" doc = AvocadoDB.get(cmd) @@ -303,10 +299,10 @@ describe AvocadoDB do end ################################################################################ -## updating a collection +## load a collection ################################################################################ - context "updating:" do + context "loading:" do before do @cn = "UnitTestsCollectionBasics" end @@ -319,13 +315,13 @@ describe AvocadoDB do doc = AvocadoDB.log_put("#{prefix}-identifier-load", cmd) doc.code.should eq(200) + doc.headers['content-type'].should eq("application/json") doc.parsed_response['error'].should eq(false) doc.parsed_response['code'].should eq(200) doc.parsed_response['id'].should eq(cid) doc.parsed_response['name'].should eq(@cn) doc.parsed_response['status'].should eq(3) doc.parsed_response['count'].should be_kind_of(Integer) - doc.headers['content-type'].should eq("application/json") AvocadoDB.drop_collection(@cn) end @@ -338,16 +334,26 @@ describe AvocadoDB do doc = AvocadoDB.log_put("#{prefix}-name-load", cmd) doc.code.should eq(200) + doc.headers['content-type'].should eq("application/json") doc.parsed_response['error'].should eq(false) doc.parsed_response['code'].should eq(200) doc.parsed_response['id'].should eq(cid) doc.parsed_response['name'].should eq(@cn) doc.parsed_response['status'].should eq(3) doc.parsed_response['count'].should be_kind_of(Integer) - doc.headers['content-type'].should eq("application/json") AvocadoDB.drop_collection(@cn) end + end + +################################################################################ +## unloading a collection +################################################################################ + + context "unloading:" do + before do + @cn = "UnitTestsCollectionBasics" + end it "unload a collection by identifier" do AvocadoDB.drop_collection(@cn) @@ -357,12 +363,12 @@ describe AvocadoDB do doc = AvocadoDB.log_put("#{prefix}-identifier-unload", cmd) doc.code.should eq(200) + doc.headers['content-type'].should eq("application/json") doc.parsed_response['error'].should eq(false) doc.parsed_response['code'].should eq(200) doc.parsed_response['id'].should eq(cid) doc.parsed_response['name'].should eq(@cn) doc.parsed_response['status'].should eq(4) - doc.headers['content-type'].should eq("application/json") AvocadoDB.drop_collection(@cn) end @@ -375,16 +381,278 @@ describe AvocadoDB do doc = AvocadoDB.log_put("#{prefix}-name-unload", cmd) doc.code.should eq(200) + doc.headers['content-type'].should eq("application/json") doc.parsed_response['error'].should eq(false) doc.parsed_response['code'].should eq(200) doc.parsed_response['id'].should eq(cid) doc.parsed_response['name'].should eq(@cn) [2,4].include?(doc.parsed_response['status']).should be_true - doc.headers['content-type'].should eq("application/json") AvocadoDB.drop_collection(@cn) end end +################################################################################ +## truncate a collection +################################################################################ + + context "truncating:" do + before do + @cn = "UnitTestsCollectionBasics" + @cid = AvocadoDB.create_collection(@cn) + end + + after do + AvocadoDB.drop_collection(@cn) + end + + it "truncate a collection by identifier" do + cmd = "/document?collection=#{@cid}" + body = "{ \"Hallo\" : \"World\" }" + + for i in ( 1 .. 10 ) + doc = AvocadoDB.post(cmd, :body => body) + end + + AvocadoDB.size_collection(@cid).should eq(10) + + cmd = api + "/" + String(@cid) + "/truncate" + doc = AvocadoDB.log_put("#{prefix}-identifier-truncate", cmd) + + doc.code.should eq(200) + doc.headers['content-type'].should eq("application/json") + doc.parsed_response['error'].should eq(false) + doc.parsed_response['code'].should eq(200) + doc.parsed_response['id'].should eq(@cid) + doc.parsed_response['name'].should eq(@cn) + doc.parsed_response['status'].should eq(3) + + AvocadoDB.size_collection(@cid).should eq(0) + + AvocadoDB.drop_collection(@cn) + end + end + +################################################################################ +## renames a collection +################################################################################ + + context "renaming:" do + it "rename a collection by identifier" do + cn = "UnitTestsCollectionBasics" + AvocadoDB.drop_collection(cn) + cid = AvocadoDB.create_collection(cn) + + cmd = "/document?collection=#{cid}" + body = "{ \"Hallo\" : \"World\" }" + + for i in ( 1 .. 10 ) + doc = AvocadoDB.post(cmd, :body => body) + end + + AvocadoDB.size_collection(cid).should eq(10) + AvocadoDB.size_collection(cn).should eq(10) + + cn2 = "UnitTestsCollectionBasics2" + AvocadoDB.drop_collection(cn2) + + body = "{ \"name\" : \"#{cn2}\" }" + cmd = api + "/" + String(cid) + "/rename" + doc = AvocadoDB.log_put("#{prefix}-identifier-rename", cmd, :body => body) + + doc.code.should eq(200) + doc.headers['content-type'].should eq("application/json") + doc.parsed_response['error'].should eq(false) + doc.parsed_response['code'].should eq(200) + doc.parsed_response['id'].should eq(cid) + doc.parsed_response['name'].should eq(cn2) + doc.parsed_response['status'].should eq(3) + + AvocadoDB.size_collection(cid).should eq(10) + AvocadoDB.size_collection(cn2).should eq(10) + + cmd = api + "/" + String(cn) + doc = AvocadoDB.get(cmd) + + doc.code.should eq(404) + doc.parsed_response['error'].should eq(true) + doc.parsed_response['errorNum'].should eq(1203) + + cmd = api + "/" + String(cn2) + doc = AvocadoDB.get(cmd) + + doc.code.should eq(200) + doc.parsed_response['error'].should eq(false) + doc.parsed_response['name'].should eq(cn2) + doc.parsed_response['status'].should eq(3) + + AvocadoDB.drop_collection(cn) + AvocadoDB.drop_collection(cn2) + end + + it "rename a collection by identifier with conflict" do + cn = "UnitTestsCollectionBasics" + AvocadoDB.drop_collection(cn) + cid = AvocadoDB.create_collection(cn) + + cn2 = "UnitTestsCollectionBasics2" + AvocadoDB.drop_collection(cn2) + cid2 = AvocadoDB.create_collection(cn2) + + body = "{ \"Hallo\" : \"World\" }" + + cmd = "/document?collection=#{cid}" + + for i in ( 1 .. 10 ) + doc = AvocadoDB.post(cmd, :body => body) + end + + AvocadoDB.size_collection(cid).should eq(10) + AvocadoDB.size_collection(cn).should eq(10) + + cmd = "/document?collection=#{cid2}" + + for i in ( 1 .. 20 ) + doc = AvocadoDB.post(cmd, :body => body) + end + + AvocadoDB.size_collection(cid2).should eq(20) + AvocadoDB.size_collection(cn2).should eq(20) + + body = "{ \"name\" : \"#{cn2}\" }" + cmd = api + "/" + String(cid) + "/rename" + doc = AvocadoDB.log_put("#{prefix}-identifier-rename-conflict", cmd, :body => body) + + doc.code.should eq(400) + doc.headers['content-type'].should eq("application/json") + doc.parsed_response['error'].should eq(true) + doc.parsed_response['code'].should eq(400) + doc.parsed_response['errorNum'].should eq(1207) + + AvocadoDB.size_collection(cid).should eq(10) + AvocadoDB.size_collection(cn).should eq(10) + + AvocadoDB.size_collection(cid2).should eq(20) + AvocadoDB.size_collection(cn2).should eq(20) + + AvocadoDB.drop_collection(cn) + AvocadoDB.drop_collection(cn2) + end + + it "rename a new-born collection by identifier" do + cn = "UnitTestsCollectionBasics" + AvocadoDB.drop_collection(cn) + cid = AvocadoDB.create_collection(cn) + + cn2 = "UnitTestsCollectionBasics2" + AvocadoDB.drop_collection(cn2) + + body = "{ \"name\" : \"#{cn2}\" }" + cmd = api + "/" + String(cid) + "/rename" + doc = AvocadoDB.log_put("#{prefix}-identifier-rename-new-born", cmd, :body => body) + + doc.code.should eq(200) + doc.headers['content-type'].should eq("application/json") + doc.parsed_response['error'].should eq(false) + doc.parsed_response['code'].should eq(200) + doc.parsed_response['id'].should eq(cid) + doc.parsed_response['name'].should eq(cn2) + doc.parsed_response['status'].should eq(3) + + cmd = api + "/" + String(cn) + doc = AvocadoDB.get(cmd) + + doc.code.should eq(404) + doc.parsed_response['error'].should eq(true) + doc.parsed_response['errorNum'].should eq(1203) + + cmd = api + "/" + String(cn2) + doc = AvocadoDB.get(cmd) + + doc.code.should eq(200) + doc.parsed_response['error'].should eq(false) + doc.parsed_response['name'].should eq(cn2) + doc.parsed_response['status'].should eq(3) + + AvocadoDB.drop_collection(cn) + AvocadoDB.drop_collection(cn2) + end + + it "rename a new-born collection by identifier with conflict" do + cn = "UnitTestsCollectionBasics" + AvocadoDB.drop_collection(cn) + cid = AvocadoDB.create_collection(cn) + + cn2 = "UnitTestsCollectionBasics2" + AvocadoDB.drop_collection(cn2) + cid2 = AvocadoDB.create_collection(cn2) + + cmd = "/document?collection=#{cid2}" + + body = "{ \"name\" : \"#{cn2}\" }" + cmd = api + "/" + String(cid) + "/rename" + doc = AvocadoDB.log_put("#{prefix}-identifier-rename-conflict", cmd, :body => body) + + doc.code.should eq(400) + doc.headers['content-type'].should eq("application/json") + doc.parsed_response['error'].should eq(true) + doc.parsed_response['code'].should eq(400) + doc.parsed_response['errorNum'].should eq(1207) + + AvocadoDB.drop_collection(cn) + AvocadoDB.drop_collection(cn2) + end + end + +################################################################################ +## parameter a collection +################################################################################ + + context "parameter:" do + it "changing the parameter of a collection by identifier" do + cn = "UnitTestsCollectionBasics" + AvocadoDB.drop_collection(cn) + cid = AvocadoDB.create_collection(cn) + + cmd = "/document?collection=#{cid}" + body = "{ \"Hallo\" : \"World\" }" + + for i in ( 1 .. 10 ) + doc = AvocadoDB.post(cmd, :body => body) + end + + AvocadoDB.size_collection(cid).should eq(10) + AvocadoDB.size_collection(cn).should eq(10) + + cmd = api + "/" + String(cid) + "/parameter" + body = "{ \"waitForSync\" : true }" + doc = AvocadoDB.log_put("#{prefix}-identifier-parameter-sync", cmd, :body => body) + + doc.code.should eq(200) + doc.headers['content-type'].should eq("application/json") + doc.parsed_response['error'].should eq(false) + doc.parsed_response['code'].should eq(200) + doc.parsed_response['id'].should eq(cid) + doc.parsed_response['name'].should eq(cn) + doc.parsed_response['status'].should eq(3) + doc.parsed_response['waitForSync'].should eq(true) + + cmd = api + "/" + String(cid) + "/parameter" + body = "{ \"waitForSync\" : false }" + doc = AvocadoDB.log_put("#{prefix}-identifier-parameter-no-sync", cmd, :body => body) + + doc.code.should eq(200) + doc.headers['content-type'].should eq("application/json") + doc.parsed_response['error'].should eq(false) + doc.parsed_response['code'].should eq(200) + doc.parsed_response['id'].should eq(cid) + doc.parsed_response['name'].should eq(cn) + doc.parsed_response['status'].should eq(3) + doc.parsed_response['waitForSync'].should eq(false) + + AvocadoDB.drop_collection(cn) + end + end + end end diff --git a/V8/v8-vocbase.cpp b/V8/v8-vocbase.cpp index 4be37f70e6..e601c84521 100644 --- a/V8/v8-vocbase.cpp +++ b/V8/v8-vocbase.cpp @@ -3162,23 +3162,19 @@ static v8::Handle JS_DeleteVocbaseCol (v8::Arguments const& argv) { // inside a write transaction // ............................................................................. - bool ok = doc->destroyLock(doc, did, 0, 0, TRI_DOC_UPDATE_LAST_WRITE); + int res = doc->destroyLock(doc, did, 0, 0, TRI_DOC_UPDATE_LAST_WRITE); // ............................................................................. // outside a write transaction // ............................................................................. - if (! ok) { - if (TRI_errno() == TRI_ERROR_AVOCADO_DOCUMENT_NOT_FOUND) { + if (res != TRI_ERROR_NO_ERROR) { + if (res == TRI_ERROR_AVOCADO_DOCUMENT_NOT_FOUND) { ReleaseCollection(collection); return scope.Close(v8::False()); } else { - string err = "cannot delete document: "; - err += TRI_last_error(); - - ReleaseCollection(collection); - return scope.Close(v8::ThrowException(v8::String::New(err.c_str()))); + return scope.Close(v8::ThrowException(CreateErrorObject(res, "cannot delete document"))); } } @@ -4301,10 +4297,7 @@ static v8::Handle JS_RenameVocbaseCol (v8::Arguments const& argv) { int res = TRI_RenameCollectionVocBase(collection->_vocbase, collection, name.c_str()); if (res != TRI_ERROR_NO_ERROR) { - string err = "cannot rename collection: "; - err += TRI_last_error(); - - return scope.Close(v8::ThrowException(v8::String::New(err.c_str()))); + return scope.Close(v8::ThrowException(CreateErrorObject(res, "cannot rename collection"))); } return scope.Close(v8::Undefined()); diff --git a/VocBase/blob-collection.c b/VocBase/blob-collection.c index 3ec35793a1..009da6e48a 100644 --- a/VocBase/blob-collection.c +++ b/VocBase/blob-collection.c @@ -315,7 +315,6 @@ TRI_blob_collection_t* TRI_CreateBlobCollection (char const* path, TRI_col_param info._cid = TRI_NewTickVocBase(); TRI_CopyString(info._name, parameter->_name, sizeof(info._name)); info._maximalSize = parameter->_maximalSize; - info._size = sizeof(TRI_col_info_t); collection = TRI_CreateCollection(&blob->base, path, &info); diff --git a/VocBase/collection.c b/VocBase/collection.c index fd2cd6e4f3..221e7f1380 100644 --- a/VocBase/collection.c +++ b/VocBase/collection.c @@ -647,7 +647,6 @@ int TRI_UpdateParameterInfoCollection (TRI_collection_t* collection) { parameter._maximalSize = collection->_maximalSize; parameter._waitForSync = collection->_waitForSync; parameter._deleted = collection->_deleted; - parameter._size = sizeof(TRI_col_info_t); return TRI_SaveParameterInfoCollection(collection->_directory, ¶meter); } @@ -670,7 +669,6 @@ int TRI_RenameCollection (TRI_collection_t* collection, char const* name) { parameter._maximalSize = collection->_maximalSize; parameter._waitForSync = collection->_waitForSync; parameter._deleted = collection->_deleted; - parameter._size = sizeof(TRI_col_info_t); res = TRI_SaveParameterInfoCollection(collection->_directory, ¶meter); diff --git a/VocBase/collection.h b/VocBase/collection.h index fa51214dc1..5f34bcec19 100644 --- a/VocBase/collection.h +++ b/VocBase/collection.h @@ -179,8 +179,6 @@ typedef struct TRI_col_info_s { bool _waitForSync; // if true, wait for msync bool _deleted; // if true, collections has been deleted - - TRI_voc_size_t _size; // total size of the parameter info block } TRI_col_info_t; diff --git a/VocBase/simple-collection.c b/VocBase/simple-collection.c index 7ecf54a263..1756f509eb 100644 --- a/VocBase/simple-collection.c +++ b/VocBase/simple-collection.c @@ -1786,7 +1786,6 @@ TRI_sim_collection_t* TRI_CreateSimCollection (char const* path, TRI_CopyString(info._name, parameter->_name, sizeof(info._name)); info._waitForSync = parameter->_waitForSync; info._maximalSize = parameter->_maximalSize; - info._size = sizeof(TRI_col_info_t); // first create the document collection doc = TRI_Allocate(sizeof(TRI_sim_collection_t)); diff --git a/VocBase/vocbase.c b/VocBase/vocbase.c index 853697900a..37e411afd1 100644 --- a/VocBase/vocbase.c +++ b/VocBase/vocbase.c @@ -1506,8 +1506,7 @@ int TRI_RenameCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* coll } // check if the new name is unused - cnv.c = collection; - found = TRI_InsertKeyAssociativePointer(&vocbase->_collectionsByName, newName, cnv.v, false); + found = TRI_LookupByKeyAssociativePointer(&vocbase->_collectionsByName, newName); if (found != NULL) { TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase); @@ -1521,7 +1520,7 @@ int TRI_RenameCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* coll // ............................................................................. if (collection->_status == TRI_VOC_COL_STATUS_NEW_BORN) { - TRI_CopyString(collection->_name, newName, sizeof(collection->_name)); + // do nothing } // ............................................................................. @@ -1532,8 +1531,6 @@ int TRI_RenameCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* coll res = TRI_LoadParameterInfoCollection(collection->_path, &info); if (res != TRI_ERROR_NO_ERROR) { - TRI_RemoveKeyAssociativePointer(&vocbase->_collectionsByName, newName); - TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase); TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection); @@ -1545,15 +1542,11 @@ int TRI_RenameCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* coll res = TRI_SaveParameterInfoCollection(collection->_path, &info); if (res != TRI_ERROR_NO_ERROR) { - TRI_RemoveKeyAssociativePointer(&vocbase->_collectionsByName, newName); - TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase); TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection); return TRI_set_errno(res); } - - TRI_CopyString(collection->_name, newName, sizeof(collection->_name)); } // ............................................................................. @@ -1564,15 +1557,11 @@ int TRI_RenameCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* coll res = TRI_RenameCollection(&collection->_collection->base, newName); if (res != TRI_ERROR_NO_ERROR) { - TRI_RemoveKeyAssociativePointer(&vocbase->_collectionsByName, newName); - TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase); TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection); return TRI_set_errno(res); } - - TRI_CopyString(collection->_name, newName, sizeof(collection->_name)); } // ............................................................................. @@ -1580,8 +1569,6 @@ int TRI_RenameCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* coll // ............................................................................. else { - TRI_RemoveKeyAssociativePointer(&vocbase->_collectionsByName, newName); - TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase); TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection); @@ -1589,10 +1576,14 @@ int TRI_RenameCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* coll } // ............................................................................. - // remove old name and release locks + // rename and release locks // ............................................................................. TRI_RemoveKeyAssociativePointer(&vocbase->_collectionsByName, oldName); + TRI_CopyString(collection->_name, newName, sizeof(collection->_name)); + + cnv.c = collection; + TRI_InsertKeyAssociativePointer(&vocbase->_collectionsByName, newName, cnv.v, false); TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase); TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection); diff --git a/js/actions/system/api-collection.js b/js/actions/system/api-collection.js index bb3e00f2f5..f3b8a7e220 100644 --- a/js/actions/system/api-collection.js +++ b/js/actions/system/api-collection.js @@ -100,7 +100,6 @@ function CollectionRepresentation (collection, showParameter, showCount, showFig /// @brief creates a collection /// /// @REST{POST /_api/collection} -//////////////////////////////// /// /// Creates an new collection with a given name. The request must contain an /// object with the following attributes. @@ -112,7 +111,6 @@ function CollectionRepresentation (collection, showParameter, showCount, showFig /// document. /// /// @EXAMPLES -///////////// /// /// @verbinclude api-collection-create-collection //////////////////////////////////////////////////////////////////////////////// @@ -128,8 +126,6 @@ function POST_api_collection (req, res) { return; } - var waitForSync = false; - if (! body.hasOwnProperty("name")) { actions.resultBad(req, res, actions.ERROR_AVOCADO_ILLEGAL_NAME, "name must be non-empty"); @@ -137,6 +133,7 @@ function POST_api_collection (req, res) { } var name = body.name; + var waitForSync = false; if (body.hasOwnProperty("waitForSync")) { waitForSync = body.waitForSync; @@ -166,7 +163,6 @@ function POST_api_collection (req, res) { /// @brief returns all collections /// /// @REST{GET /_api/collection} -/////////////////////////////// /// /// Returns an object with an attribute @LIT{collections} containing a /// list of all collection descriptions. The same information is also @@ -174,7 +170,6 @@ function POST_api_collection (req, res) { /// as keys. /// /// @EXAMPLES -///////////// /// /// Return information about all collections: /// @@ -353,7 +348,6 @@ function GET_api_collection (req, res) { /// @brief loads a collection /// /// @REST{PUT /_api/collection/@FA{collection-identifier}/load} -/////////////////////////////////////////////////////////////// /// /// Loads a collection into memory. On success an object with the following /// @@ -372,7 +366,6 @@ function GET_api_collection (req, res) { /// It is possible to specify a name instead of an identifier. /// /// @EXAMPLES -///////////// /// /// @verbinclude api-collection-identifier-load //////////////////////////////////////////////////////////////////////////////// @@ -394,7 +387,6 @@ function PUT_api_collection_load (req, res, collection) { /// @brief unloads a collection /// /// @REST{PUT /_api/collection/@FA{collection-identifier}/unload} -///////////////////////////////////////////////////////////////// /// /// Removes a collection from memory. This call does not delete any documents. /// You can use the collection afterwards; in which case it will be loaded into @@ -411,7 +403,6 @@ function PUT_api_collection_load (req, res, collection) { /// 404} is returned. /// /// @EXAMPLES -///////////// /// /// @verbinclude api-collection-identifier-unload //////////////////////////////////////////////////////////////////////////////// @@ -433,23 +424,31 @@ function PUT_api_collection_unload (req, res, collection) { /// @brief truncates a collection /// /// @REST{PUT /_api/collection/@FA{collection-identifier}/truncate} -/////////////////////////////////////////////////////////////////// /// /// Removes all documents from the collection, but leaves the indexes intact. /// /// @EXAMPLES -///////////// /// +/// @verbinclude api-collection-identifier-truncate //////////////////////////////////////////////////////////////////////////////// function PUT_api_collection_truncate (req, res, collection) { + try { + collection.truncate(); + + var result = CollectionRepresentation(collection); + + actions.resultOk(req, res, actions.HTTP_OK, result); + } + catch (err) { + actions.resultException(req, res, err); + } } //////////////////////////////////////////////////////////////////////////////// /// @brief changes a collection /// /// @REST{PUT /_api/collection/@FA{collection-identifier}/parameter} -//////////////////////////////////////////////////////////////////// /// /// Changes the parameter of a collection. Expects an object with the /// attribute(s) @@ -466,18 +465,36 @@ function PUT_api_collection_truncate (req, res, collection) { /// @LIT{waitForSync}: The new value. /// /// @EXAMPLES -///////////// /// //////////////////////////////////////////////////////////////////////////////// function PUT_api_collection_parameter (req, res, collection) { + var body; + + try { + body = JSON.parse(req.requestBody || "{}") || {}; + } + catch (err) { + actions.resultBad(req, res, actions.ERROR_HTTP_CORRUPTED_JSON, err); + return; + } + + try { + collection.parameter(body); + + var result = CollectionRepresentation(collection, true); + + actions.resultOk(req, res, actions.HTTP_OK, result); + } + catch (err) { + actions.resultException(req, res, err); + } } //////////////////////////////////////////////////////////////////////////////// /// @brief renames a collection /// /// @REST{PUT /_api/collection/@FA{collection-identifier}/rename} -///////////////////////////////////////////////////////////////// /// /// Renames a collection. Expects an object with the attribute(s) /// @@ -490,11 +507,39 @@ function PUT_api_collection_parameter (req, res, collection) { /// @LIT{name}: The new name of the collection. /// /// @EXAMPLES -///////////// /// +/// @verbinclude api-collection-identifier-rename //////////////////////////////////////////////////////////////////////////////// function PUT_api_collection_rename (req, res, collection) { + var body; + + try { + body = JSON.parse(req.requestBody || "{}") || {}; + } + catch (err) { + actions.resultBad(req, res, actions.ERROR_HTTP_CORRUPTED_JSON, err); + return; + } + + if (! body.hasOwnProperty("name")) { + actions.resultBad(req, res, actions.ERROR_AVOCADO_ILLEGAL_NAME, + "name must be non-empty"); + return; + } + + var name = body.name; + + try { + collection.rename(name); + + var result = CollectionRepresentation(collection); + + actions.resultOk(req, res, actions.HTTP_OK, result); + } + catch (err) { + actions.resultException(req, res, err); + } } //////////////////////////////////////////////////////////////////////////////// diff --git a/js/server/js-server.h b/js/server/js-server.h index b9c52525f2..d27534bf1b 100644 --- a/js/server/js-server.h +++ b/js/server/js-server.h @@ -168,6 +168,30 @@ static string JS_server_server = "AvocadoEdges.prototype._drop = AvocadoDatabase._drop;\n" "\n" "////////////////////////////////////////////////////////////////////////////////\n" + "/// @brief truncates a collection\n" + "////////////////////////////////////////////////////////////////////////////////\n" + "\n" + "AvocadoDatabase.prototype._truncate = function(name) {\n" + " var collection = name;\n" + "\n" + " if (typeof name === \"string\") {\n" + " collection = db[name];\n" + " }\n" + "\n" + " if (collection == null) {\n" + " return;\n" + " }\n" + "\n" + " var all = collection.ALL(null, null).documents;\n" + "\n" + " for (var i = 0; i < all.length; ++i) {\n" + " collection.delete(all[i]._id);\n" + " }\n" + "}\n" + "\n" + "AvocadoEdges.prototype._truncate = AvocadoDatabase._truncate;\n" + "\n" + "////////////////////////////////////////////////////////////////////////////////\n" "/// @}\n" "////////////////////////////////////////////////////////////////////////////////\n" "\n" @@ -225,6 +249,14 @@ static string JS_server_server = "}\n" "\n" "////////////////////////////////////////////////////////////////////////////////\n" + "/// @brief truncates a collection\n" + "////////////////////////////////////////////////////////////////////////////////\n" + "\n" + "AvocadoCollection.prototype.truncate = function() {\n" + " return db._truncate(this);\n" + "}\n" + "\n" + "////////////////////////////////////////////////////////////////////////////////\n" "/// @brief prints a collection\n" "////////////////////////////////////////////////////////////////////////////////\n" "\n" diff --git a/js/server/server.js b/js/server/server.js index f177311259..94c4449b3d 100644 --- a/js/server/server.js +++ b/js/server/server.js @@ -166,6 +166,30 @@ AvocadoDatabase.prototype._drop = function(name) { AvocadoEdges.prototype._drop = AvocadoDatabase._drop; +//////////////////////////////////////////////////////////////////////////////// +/// @brief truncates a collection +//////////////////////////////////////////////////////////////////////////////// + +AvocadoDatabase.prototype._truncate = function(name) { + var collection = name; + + if (typeof name === "string") { + collection = db[name]; + } + + if (collection == null) { + return; + } + + var all = collection.ALL(null, null).documents; + + for (var i = 0; i < all.length; ++i) { + collection.delete(all[i]._id); + } +} + +AvocadoEdges.prototype._truncate = AvocadoDatabase._truncate; + //////////////////////////////////////////////////////////////////////////////// /// @} //////////////////////////////////////////////////////////////////////////////// @@ -223,6 +247,14 @@ AvocadoCollection.prototype.toArray = function() { return this.all().toArray(); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief truncates a collection +//////////////////////////////////////////////////////////////////////////////// + +AvocadoCollection.prototype.truncate = function() { + return db._truncate(this); +} + //////////////////////////////////////////////////////////////////////////////// /// @brief prints a collection ////////////////////////////////////////////////////////////////////////////////